Skip to content

Commit 8ebdaa2

Browse files
Revised unit test framework to allow for more specific test conditions
1 parent e85e683 commit 8ebdaa2

73 files changed

Lines changed: 1272 additions & 739 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/CONTRIBUTING.md

Lines changed: 92 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -371,43 +371,60 @@ class NewAPIUnitTest(unit_test_framework.APIUnitTest):
371371
#### Overriding Base Model Properties ####
372372
The APIUnitTest class requires you to override a some properties to function correctly:
373373

374-
- `url` : A string specifying the URL this unit test will be testing<br>
375-
- `get_payloads` : A list of dictionary formatted API payloads to use when testing GET requests. If this endpoint does not
376-
support GET requests, you do not need to override this property. If this endpoint does support GET request, but does not
377-
require any payload data to receive a valid response you must set this value to `[{}]`
378-
- `post_payloads` : A list of dictionary formatted API payloads to use when testing POST requests. If this endpoint does
379-
not support POST requests, you do not need to override this property.
380-
- `put_payloads` : A list of dictionary formatted API payloads to use when testing PUT requests. If this endpoint does
381-
not support PUT requests, you do not need to override this property.
382-
- `delete_payloads` : A list of dictionary formatted API payloads to use when testing DELETE requests. If this endpoint does
383-
not support DELETE requests, you do not need to override this property.
374+
- `url` : A string specifying the URL this unit test will be testing
375+
- `time_delay` : An integer specifying how many seconds should be waited between requests. Defaults to `1`.
376+
- `get_tests` : A list of dictionary formatted test parameters for GET requests. If this endpoint does not support
377+
GET requests, you do not need to override this property. If this endpoint does support GET request, but does not require
378+
any payload data to receive a valid response you must set this value to `[{}]`. Each dictionary can contain:
379+
- `name` : set a descriptive name to be printed alongside test results (defaults to `unnamed test`)
380+
- `payload` : a nested dictionary that contains the request payload to use when running the test (defaults to `{}`)
381+
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
382+
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
383+
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
384+
385+
- `post_tests` : A list of dictionary formatted test parameters for POST requests. If this endpoint does not support
386+
POST requests, you do not need to override this property. If this endpoint does support POST request, but does not require
387+
any payload data to receive a valid response you must set this value to `[{}]`. Each dictionary can contain:
388+
- `name` : set a descriptive name to be printed alongside test results (defaults to `unnamed test`)
389+
- `payload` : a nested dictionary that contains the request payload to use when running the test (defaults to `{}`)
390+
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
391+
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
392+
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
393+
394+
- `put_tests` : A list of dictionary formatted test parameters for PUT requests. If this endpoint does not support
395+
PUT requests, you do not need to override this property. If this endpoint does support PUT request, but does not require
396+
any payload data to receive a valid response you must set this value to `[{}]`. Each dictionary can contain:
397+
- `name` : set a descriptive name to be printed alongside test results (defaults to `unnamed test`)
398+
- `payload` : a nested dictionary that contains the request payload to use when running the test (defaults to `{}`)
399+
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
400+
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
401+
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
402+
403+
- `delete_tests` : A list of dictionary formatted test parameters for DELETE requests. If this endpoint does not support
404+
DELETE requests, you do not need to override this property. If this endpoint does support DELETE request, but does not require
405+
any payload data to receive a valid response you must set this value to `[{}]`. Each dictionary can contain:
406+
- `name` : set a descriptive name to be printed alongside test results (defaults to `unnamed test`)
407+
- `payload` : a nested dictionary that contains the request payload to use when running the test (defaults to `{}`)
408+
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
409+
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
410+
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
411+
384412
- `get_responses` : A list of previously executed GET requests in a dictionary format. Failing responses will not be
385413
included.
414+
386415
- `post_responses` : A list of previously executed POST requests in a dictionary format. Failing responses will not be
387416
included.
417+
388418
- `put_responses` : A list of previously executed PUT requests in a dictionary format. Failing responses will not be
389419
included.
420+
390421
- `delete_responses` : A list of previously executed DELETE requests in a dictionary format. Failing responses will not be
391422
included.
392423

393-
```python
394-
import unit_test_framework
424+
#### Other Base Model Properties
425+
The APIUnitTest class also contains a few properties that are not intended to be overridden:
395426

396-
class NewAPIUnitTest(unit_test_framework.APIUnitTest):
397-
url = "/api/v1/your_endpoint"
398-
get_payloads = [{}]
399-
post_payloads = [
400-
{"some_parameter": "some value to create"},
401-
{"some_parameter": "some other value to create"}
402-
]
403-
put_payloads = [
404-
{"some_parameter": "some value to update"},
405-
{"some_parameter": "some other value to update"}
406-
]
407-
delete_payloads = [
408-
{"some_parameter": "some value to delete"},
409-
]
410-
```
427+
- `uid` : a unique ID that can be used for payload fields that required a unique value
411428

412429
#### Overriding Base Model Methods ####
413430
There are methods that will assist you when you need to dynamically format API request data. These are typically used
@@ -432,18 +449,52 @@ import unit_test_framework
432449

433450
class NewAPIUnitTest(unit_test_framework.APIUnitTest):
434451
url = "/api/v1/your_endpoint"
435-
get_payloads = [{}]
436-
post_payloads = [
437-
{"some_parameter": "some value to create"},
438-
{"some_parameter": "some other value to create"}
439-
]
440-
put_payloads = [
441-
{"some_parameter": "some value to update"},
442-
{"some_parameter": "some other value to update"}
452+
get_requests = [{}]
453+
post_requests = [
454+
{
455+
"payload": {
456+
"some_parameter": "some value to create"
457+
},
458+
"status": 400,
459+
"return": 1,
460+
"resp_time": 0.5
461+
},
462+
{
463+
"payload": {
464+
"some_other parameter": "some other value to create"
465+
},
466+
"status": 200,
467+
"return": 0,
468+
"resp_time": 0.6
469+
}, ]
470+
put_requests = [
471+
{
472+
"payload": {
473+
"some_parameter": "some value to update"
474+
},
475+
"status": 400,
476+
"return": 1,
477+
"resp_time": 0.5
478+
},
479+
{
480+
"payload": {
481+
"some_other parameter": "some other value to update"
482+
},
483+
"status": 200,
484+
"return": 0,
485+
"resp_time": 0.6
486+
},
443487
]
444-
delete_payloads = [
445-
{"some_parameter": "some value to delete"},
446-
]
488+
delete_requests = [
489+
{
490+
"payload": {
491+
"some_parameter": "some value to delete"
492+
},
493+
"status": 200,
494+
"return": 0,
495+
"resp_time": 0.5
496+
},
497+
]
447498

448499
NewAPIUnitTest()
449500
```
@@ -457,7 +508,9 @@ Or you may run all the unit tests by running:<br>
457508
Unit tests will check API responses for the following:
458509
- Ability to connect to API endpoint
459510
- API responses properly return data in a JSON format
460-
- API payloads return a 200 OK response
511+
- API responses include the correct HTTP status code
512+
- API responses include the expected API return code
513+
- API responses are received within an acceptable time frame
461514
- CRUD success. POST requests are always run first, then GET requests to check that the creation was successful, then
462515
PUT requests attempt to update the created object, then finally DELETE requests attempt to destroy the object.
463516

tests/test_api_v1_firewall_alias.py

Lines changed: 84 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,104 @@
1616

1717
class APIUnitTestFirewallAlias(unit_test_framework.APIUnitTest):
1818
url = "/api/v1/firewall/alias"
19-
get_payloads = [{}]
20-
post_payloads = [
19+
get_tests = [
20+
{"name": "Read all aliases"}
21+
]
22+
post_tests = [
2123
{
22-
"name": "RFC1918",
23-
"type": "network",
24-
"descr": "Unit Test",
25-
"address": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/24"],
26-
"detail": ["Class A", "Class B", "Class C"]
24+
"name": "Create network alias",
25+
"payload": {
26+
"name": "RFC1918",
27+
"type": "network",
28+
"descr": "Unit Test",
29+
"address": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/24"],
30+
"detail": ["Class A", "Class B", "Class C"]
31+
},
32+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
2733
},
2834
{
29-
"name": "HTTP_PORTS",
30-
"type": "port",
31-
"descr": "Unit Test",
32-
"address": [80, 443, 8443],
33-
"detail": ["HTTP", "HTTPS", "HTTPS-ALT"]
35+
"name": "Create port alias",
36+
"payload": {
37+
"name": "HTTP_PORTS",
38+
"type": "port",
39+
"descr": "Unit Test",
40+
"address": [80, 443, 8443],
41+
"detail": ["HTTP", "HTTPS", "HTTPS-ALT"]
42+
},
43+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
3444
},
3545
{
36-
"name": "DNS_SERVERS",
37-
"type": "host",
38-
"descr": "Unit Test",
39-
"address": ["1.1.1.1", "8.8.8.8", "8.8.4.4"],
40-
"detail": ["Cloudflare DNS", "Google DNS", "Secondary Google DNS"]
46+
"name": "Create host alias",
47+
"payload": {
48+
"name": "DNS_SERVERS",
49+
"type": "host",
50+
"descr": "Unit Test",
51+
"address": ["1.1.1.1", "8.8.8.8", "8.8.4.4"],
52+
"detail": ["Cloudflare DNS", "Google DNS", "Secondary Google DNS"]
53+
},
54+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
4155
}
42-
4356
]
44-
put_payloads = [
57+
put_tests = [
4558
{
46-
"id": "RFC1918",
47-
"name": "UPDATED_RFC1918",
48-
"type": "network",
49-
"descr": "Updated Unit Test",
50-
"address": ["10.0.0.0/32", "172.16.0.0/32", "192.168.0.0/32"],
51-
"detail": ["New Class A", "New Class B", "New Class C"]
59+
"name": "Update network alias",
60+
"payload": {
61+
"id": "RFC1918",
62+
"name": "UPDATED_RFC1918",
63+
"type": "network",
64+
"descr": "Updated Unit Test",
65+
"address": ["10.0.0.0/32", "172.16.0.0/32", "192.168.0.0/32"],
66+
"detail": ["New Class A", "New Class B", "New Class C"]
67+
},
68+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
5269
},
5370
{
54-
"id": "HTTP_PORTS",
55-
"name": "UPDATED_HTTP_PORTS",
56-
"type": "port",
57-
"descr": "Updated Unit Test",
58-
"address": [8080, 4433, 443],
59-
"detail": ["HTTP-ALT", "HTTPS-ALT", "HTTPS"]
71+
"name": "Update port alias",
72+
"payload": {
73+
"id": "HTTP_PORTS",
74+
"name": "UPDATED_HTTP_PORTS",
75+
"type": "port",
76+
"descr": "Updated Unit Test",
77+
"address": [8080, 4433, 443],
78+
"detail": ["HTTP-ALT", "HTTPS-ALT", "HTTPS"]
79+
},
80+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
6081
},
6182
{
62-
"id": "DNS_SERVERS",
63-
"name": "UPDATED_DNS_SERVERS",
64-
"type": "host",
65-
"descr": "Updated Unit Test",
66-
"address": ["8.8.8.8"],
67-
"detail": ["Google DNS"]
83+
"name": "Update host alias",
84+
"payload": {
85+
"id": "DNS_SERVERS",
86+
"name": "UPDATED_DNS_SERVERS",
87+
"type": "host",
88+
"descr": "Updated Unit Test",
89+
"address": ["8.8.8.8"],
90+
"detail": ["Google DNS"]
91+
},
92+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
6893
}
6994
]
70-
delete_payloads = [
71-
{"id": "UPDATED_RFC1918"},
72-
{"id": "UPDATED_HTTP_PORTS"},
73-
{"id": "UPDATED_DNS_SERVERS"}
95+
delete_tests = [
96+
{
97+
"name": "Delete network alias",
98+
"payload": {
99+
"id": "UPDATED_RFC1918"
100+
},
101+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
102+
},
103+
{
104+
"name": "Delete port alias",
105+
"payload": {
106+
"id": "UPDATED_HTTP_PORTS"
107+
},
108+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
109+
},
110+
{
111+
"name": "Delete host alias",
112+
"payload": {
113+
"id": "UPDATED_DNS_SERVERS"
114+
},
115+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
116+
}
74117
]
75118

76119
APIUnitTestFirewallAlias()

tests/test_api_v1_firewall_nat_one_to_one.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,50 @@
1616

1717
class APIUnitTestFirewallNATOneToOne(unit_test_framework.APIUnitTest):
1818
url = "/api/v1/firewall/nat/one_to_one"
19-
get_payloads = [{}]
20-
post_payloads = [
19+
get_tests = [
20+
{"name": "Read all 1:1 NAT mappings"}
21+
]
22+
post_tests = [
2123
{
22-
"interface": "wan",
23-
"src": "any",
24-
"dst": "wanip",
25-
"external": "192.168.1.123",
26-
"natreflection": "enable",
27-
"descr": "Unit Test",
28-
"nobinat": True,
29-
"top": True,
30-
"disabled": True
24+
"name": "Create 1:1 NAT mapping",
25+
"payload": {
26+
"interface": "wan",
27+
"src": "any",
28+
"dst": "wanip",
29+
"external": "192.168.1.123",
30+
"natreflection": "enable",
31+
"descr": "Unit Test",
32+
"nobinat": True,
33+
"top": True,
34+
"disabled": True
35+
}
3136
}
3237
]
33-
put_payloads = [
38+
put_tests = [
3439
{
35-
"id": 0,
36-
"interface": "wan",
37-
"src": "!1.1.1.1",
38-
"dst": "1.2.3.4",
39-
"external": "4.3.2.1",
40-
"natreflection": "disable",
41-
"descr": "Updated Unit Test",
42-
"disabled": False,
43-
"nobinat": False,
44-
"top": False,
45-
"apply": True
40+
"name": "Update 1:1 NAT mapping and apply",
41+
"payload": {
42+
"id": 0,
43+
"interface": "wan",
44+
"src": "!1.1.1.1",
45+
"dst": "1.2.3.4",
46+
"external": "4.3.2.1",
47+
"natreflection": "disable",
48+
"descr": "Updated Unit Test",
49+
"disabled": False,
50+
"nobinat": False,
51+
"top": False,
52+
"apply": True
53+
},
54+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
4655
}
4756
]
48-
delete_payloads = [
49-
{"id": 0, "apply": True}
57+
delete_tests = [
58+
{
59+
"name": "Delete 1:1 NAT mapping and apply",
60+
"payload": {"id": 0, "apply": True},
61+
"resp_time": 3 # Allow a few seconds for the firewall filter to reload
62+
}
5063
]
5164

5265
APIUnitTestFirewallNATOneToOne()

0 commit comments

Comments
 (0)