Skip to content

Commit ce7d4c6

Browse files
authored
Extend test guidelines with implementation notes for unit/regression tests (#186)
Signed-off-by: Martin Morgenstern <[email protected]>
1 parent ca8768a commit ce7d4c6

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

contributor-docs/development/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Developer documentation
2+
3+
Welcome to the developer section of the contributor docs. Here you will find
4+
guidelines for the implementation of tooling such as the SCS conformance tests.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: SCS Conformance Test Implementation Guide
3+
type:
4+
status: Draft
5+
track: Global
6+
---
7+
8+
SovereignCloudStack (SCS) uses [conformance tests][gh-scripts] to certify
9+
compliance of a given cloud offering with respect to a given [certificate
10+
scope][cert-scopes] such as *SCS Compatible IaaS v4*.
11+
Our aim is that these tests are reliable, consistent and comprehensible for
12+
the users.
13+
This document is a guideline for conformance test authors and summarizes the
14+
current best practices to achieve this goal.
15+
16+
## 1. Mapping of RFC2119 Keywords
17+
18+
Test authors working on new and existing conformance tests for an SCS standard
19+
must implement the keywords such as MUST and SHOULD according to the [SCS
20+
RFC2119 Keyword Test Guide][scs-rfc2119-guide].
21+
22+
## 2. Unit and Regression Tests
23+
24+
Test authors are *strongly* encouraged to include unit and regression tests for
25+
the conformance test's logic.
26+
Conformance tests will inevitably contain some non-trivial algorithms, be it for
27+
parsing flavor names or evaluating CVE vulnerability reports.
28+
Testing them automatically and regularly against valid and invalid inputs helps
29+
test authors to find programming mistakes early on.
30+
As a bonus, a well written unit test also makes it easier for reviewers to cross
31+
check a given pull request with new, enhanced or refactored conformance tests.
32+
33+
In general, unit and regression tests for the conformance tests are located in
34+
the same location as the conformance tests, that is, the `Tests/` directory of
35+
the [SCS standards repository][scs-standards].
36+
Setup and development of the unit tests is described in the [SCS conformance
37+
tests README][tests-readme].
38+
39+
### Naming Conventions
40+
41+
Any module that ends in `_test` will be picked up as a unit test module by
42+
pytest in our CI pipeline (in other words, all files matched by the pattern
43+
`Tests/**/*_test.py`).
44+
Pytest will execute any function prefixed with `test_` as a test function, or,
45+
alternatively, tests based on the `unittest` module from the Python standard
46+
library.
47+
48+
Follow these naming rules:
49+
50+
* The name of a unit test module is constructed from the module to be unit
51+
tested and the `_test` suffix. For example, unit tests for `flavor_names.py`
52+
should reside in `flavor_names_test.py`.
53+
* The name of a Python module in general should be a valid [Python
54+
identifier][python-identifiers], to allow imports via the `import` statement.
55+
For example, use `flavor_names.py` instead of `flavor-names.py`.
56+
57+
### Write Testable Conformance Tests
58+
59+
Software design fills complete book shelves and this section can only cover some
60+
basic best practices.
61+
As a general rule of thumb, the earlier you begin writing unit tests, the better
62+
– it will force you to write modules that are easy to test.
63+
64+
Divide conformance tests scripts into smaller, loosely coupled units, i.e.,
65+
functions that serve one purpose each.
66+
Use the [*dependency injection*][wiki-di] technique, i.e., pass externally
67+
retrieved data as function arguments instead of hardcoding the calls to the
68+
retrieval functions inside a function.
69+
Avoid logging calls deep down in the call hierarchy and use explicit return
70+
values or raise exceptions, instead.
71+
Here is an abstract example of a conformance test which does exactly that:
72+
73+
```python
74+
# property_compliance.py
75+
76+
def retrieve(location):
77+
"""Retrieve raw data via network."""
78+
...
79+
80+
def parse(data):
81+
"""Parse raw data and return a dict."""
82+
...
83+
84+
def handle(...):
85+
"""Evaluate parsed data."""
86+
...
87+
88+
def main(args):
89+
...
90+
data = retrieve(location)
91+
parsed = parse(data)
92+
result = handle(parsed)
93+
...
94+
if result.some_prop != expected_value:
95+
logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value)
96+
...
97+
return result.success
98+
99+
if __name__ == "__main__":
100+
# using sys.exit(…) only here makes it possible to unit test main(…)
101+
sys.exit(main(sys.argv))
102+
```
103+
104+
Adhering to this style makes it easier to test an algorithm in isolation,
105+
without actually making a call to some external service.
106+
107+
### Pytest Test Example
108+
109+
Assuming we want to unit test some members of the module `property_compliance`
110+
from the previous section, we would create a file `property_compliance_test.py`
111+
with the following content as a starting point:
112+
113+
```python
114+
"""Unit tests for property_compliance.
115+
116+
(c) Your Name <[email protected]>, 4/2024
117+
SPDX-License-Identifier: CC-BY-SA-4.0
118+
"""
119+
120+
import pytest
121+
122+
from property_compliance import parse
123+
124+
125+
def test_success():
126+
assert parse("some valid input") == "expected output"
127+
128+
129+
def test_failure():
130+
with pytest.raises(ValueError):
131+
parse("invalid input")
132+
```
133+
134+
## 3. Conformance Tests Shouldn't Require Admin Privileges
135+
136+
Conformance tests are expected to be executable without admin privileges (see §2 of
137+
[Regulations for achieving SCS-compatible certification][scs-0004-v1]).
138+
In particular, this means:
139+
140+
* The cloud credentials (e.g., kubeconfig and OpenStack `clouds.yaml`) passed to
141+
the scripts are non-admin credentials.
142+
* Conformance tests scripts should not require root privileges, except for the
143+
installation of operating system prerequisites (e.g., a Python interpreter).
144+
145+
[scs-standards]: https://github.com/SovereignCloudStack/standards/
146+
[tests-readme]: https://github.com/SovereignCloudStack/standards/blob/main/Tests/README.md
147+
[python-identifiers]: https://docs.python.org/3/reference/lexical_analysis.html#identifiers
148+
[gh-scripts]: https://github.com/SovereignCloudStack/standards/tree/main/Tests
149+
[cert-scopes]: https://docs.scs.community/standards/certification/scopes-versions
150+
[scs-rfc2119-guide]: https://docs.scs.community/contributor-docs/operations/tests/rfc2119-keyword-test-guide
151+
[scs-0004-v1]: https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0004-v1-achieving-certification.md
152+
[wiki-di]: https://en.wikipedia.org/wiki/Dependency_injection

0 commit comments

Comments
 (0)