Merge ~bjornt/maas:api-better-tests into maas:master
- Git
- lp:~bjornt/maas
- api-better-tests
- Merge into master
Proposed by
Björn Tillenius
Status: | Merged |
---|---|
Approved by: | Björn Tillenius |
Approved revision: | 6cea490cb6d91dedbdf2e984fa668589495d307f |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~bjornt/maas:api-better-tests |
Merge into: | maas:master |
Diff against target: |
854 lines (+486/-162) 4 files modified
src/maasserver/api/tests/test_interfaces.py (+210/-57) src/maasserver/api/tests/test_subnets.py (+146/-30) src/maasserver/api/tests/test_vlans.py (+128/-75) src/maasserver/testing/factory.py (+2/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Adam Collard (community) | Approve | ||
MAAS Lander | Needs Fixing | ||
Review via email: mp+419448@code.launchpad.net |
Commit message
Add some more tests for the API handlers.
This is in preparation for changing the way we generate the JSON
representation.
Description of the change
To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) : | # |
review:
Approve
~bjornt/maas:api-better-tests
updated
- 6cea490... by Björn Tillenius
-
Fix test failures.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/maasserver/api/tests/test_interfaces.py b/src/maasserver/api/tests/test_interfaces.py | |||
2 | index 89c6171..5b17370 100644 | |||
3 | --- a/src/maasserver/api/tests/test_interfaces.py | |||
4 | +++ b/src/maasserver/api/tests/test_interfaces.py | |||
5 | @@ -26,6 +26,7 @@ from maasserver.enum import ( | |||
6 | 26 | NODE_TYPE, | 26 | NODE_TYPE, |
7 | 27 | ) | 27 | ) |
8 | 28 | from maasserver.models import Interface | 28 | from maasserver.models import Interface |
9 | 29 | from maasserver.models.vlan import DEFAULT_MTU | ||
10 | 29 | from maasserver.testing.api import APITestCase, APITransactionTestCase | 30 | from maasserver.testing.api import APITestCase, APITransactionTestCase |
11 | 30 | from maasserver.testing.factory import factory | 31 | from maasserver.testing.factory import factory |
12 | 31 | from maasserver.utils.converters import json_load_bytes | 32 | from maasserver.utils.converters import json_load_bytes |
13 | @@ -60,6 +61,44 @@ def get_interface_uri(interface, node=None): | |||
14 | 60 | return reverse("interface_handler", args=[node.system_id, interface]) | 61 | return reverse("interface_handler", args=[node.system_id, interface]) |
15 | 61 | 62 | ||
16 | 62 | 63 | ||
17 | 64 | def serialize_vlan(vlan): | ||
18 | 65 | return { | ||
19 | 66 | "id": vlan.id, | ||
20 | 67 | "dhcp_on": vlan.dhcp_on, | ||
21 | 68 | "external_dhcp": vlan.external_dhcp, | ||
22 | 69 | "fabric": vlan.fabric.get_name(), | ||
23 | 70 | "fabric_id": vlan.fabric_id, | ||
24 | 71 | "mtu": vlan.mtu, | ||
25 | 72 | "primary_rack": None, | ||
26 | 73 | "secondary_rack": None, | ||
27 | 74 | "space": "undefined" if not vlan.space else vlan.space.get_name(), | ||
28 | 75 | "vid": vlan.vid, | ||
29 | 76 | "name": vlan.get_name(), | ||
30 | 77 | "relay_vlan": None, | ||
31 | 78 | "resource_uri": f"/MAAS/api/2.0/vlans/{vlan.id}/", | ||
32 | 79 | } | ||
33 | 80 | |||
34 | 81 | |||
35 | 82 | def serialize_subnet(subnet): | ||
36 | 83 | return { | ||
37 | 84 | "name": subnet.name, | ||
38 | 85 | "id": subnet.id, | ||
39 | 86 | "vlan": serialize_vlan(subnet.vlan), | ||
40 | 87 | "description": "", | ||
41 | 88 | "cidr": subnet.cidr, | ||
42 | 89 | "rdns_mode": subnet.rdns_mode, | ||
43 | 90 | "gateway_ip": subnet.gateway_ip, | ||
44 | 91 | "dns_servers": subnet.dns_servers, | ||
45 | 92 | "allow_dns": subnet.allow_dns, | ||
46 | 93 | "allow_proxy": subnet.allow_proxy, | ||
47 | 94 | "active_discovery": subnet.active_discovery, | ||
48 | 95 | "managed": subnet.managed, | ||
49 | 96 | "disabled_boot_architectures": subnet.disabled_boot_architectures, | ||
50 | 97 | "space": "undefined" if not subnet.space else subnet.space.get_name(), | ||
51 | 98 | "resource_uri": f"/MAAS/api/2.0/subnets/{subnet.id}/", | ||
52 | 99 | } | ||
53 | 100 | |||
54 | 101 | |||
55 | 63 | def make_complex_interface(node, name=None): | 102 | def make_complex_interface(node, name=None): |
56 | 64 | """Makes interface with parents and children.""" | 103 | """Makes interface with parents and children.""" |
57 | 65 | fabric = factory.make_Fabric() | 104 | fabric = factory.make_Fabric() |
58 | @@ -887,14 +926,113 @@ class TestNodeInterfaceAPI(APITransactionTestCase.ForUser): | |||
59 | 887 | get_interface_uri(interface, node=node), | 926 | get_interface_uri(interface, node=node), |
60 | 888 | ) | 927 | ) |
61 | 889 | 928 | ||
62 | 929 | def test_read_basic(self): | ||
63 | 930 | node = factory.make_Node() | ||
64 | 931 | interface = factory.make_Interface( | ||
65 | 932 | node=node, | ||
66 | 933 | name="eno1", | ||
67 | 934 | iftype=INTERFACE_TYPE.PHYSICAL, | ||
68 | 935 | mac_address="11:11:11:11:11:11", | ||
69 | 936 | enabled=False, | ||
70 | 937 | vendor="my-vendor", | ||
71 | 938 | product="my-product", | ||
72 | 939 | firmware_version="1.2.3", | ||
73 | 940 | link_connected=False, | ||
74 | 941 | vlan=None, | ||
75 | 942 | interface_speed=100, | ||
76 | 943 | sriov_max_vf=0, | ||
77 | 944 | tags=[], | ||
78 | 945 | ) | ||
79 | 946 | |||
80 | 947 | uri = get_interface_uri(interface) | ||
81 | 948 | response = self.client.get(uri) | ||
82 | 949 | self.assertEqual( | ||
83 | 950 | http.client.OK, response.status_code, response.content | ||
84 | 951 | ) | ||
85 | 952 | parsed_interface = json_load_bytes(response.content) | ||
86 | 953 | self.maxDiff = None | ||
87 | 954 | self.assertEqual( | ||
88 | 955 | { | ||
89 | 956 | "system_id": node.system_id, | ||
90 | 957 | "id": interface.id, | ||
91 | 958 | "name": "eno1", | ||
92 | 959 | "type": INTERFACE_TYPE.PHYSICAL, | ||
93 | 960 | "vlan": None, | ||
94 | 961 | "mac_address": "11:11:11:11:11:11", | ||
95 | 962 | "parents": [], | ||
96 | 963 | "children": [], | ||
97 | 964 | "tags": [], | ||
98 | 965 | "enabled": False, | ||
99 | 966 | "links": [], | ||
100 | 967 | "params": "", | ||
101 | 968 | "discovered": None, | ||
102 | 969 | "effective_mtu": DEFAULT_MTU, | ||
103 | 970 | "vendor": "my-vendor", | ||
104 | 971 | "product": "my-product", | ||
105 | 972 | "firmware_version": "1.2.3", | ||
106 | 973 | "link_connected": False, | ||
107 | 974 | "interface_speed": 100, | ||
108 | 975 | "link_speed": 0, | ||
109 | 976 | "numa_node": 0, | ||
110 | 977 | "sriov_max_vf": 0, | ||
111 | 978 | "resource_uri": ( | ||
112 | 979 | f"/MAAS/api/2.0/nodes/{node.system_id}/interfaces/{interface.id}/" | ||
113 | 980 | ), | ||
114 | 981 | }, | ||
115 | 982 | parsed_interface, | ||
116 | 983 | ) | ||
117 | 984 | |||
118 | 985 | def test_read_connected(self): | ||
119 | 986 | vlan = factory.make_VLAN(name="my-vlan", mtu=1234) | ||
120 | 987 | interface = factory.make_Interface( | ||
121 | 988 | enabled=True, | ||
122 | 989 | link_connected=True, | ||
123 | 990 | vlan=vlan, | ||
124 | 991 | interface_speed=100, | ||
125 | 992 | link_speed=10, | ||
126 | 993 | tags=["foo", "bar"], | ||
127 | 994 | ) | ||
128 | 995 | |||
129 | 996 | uri = get_interface_uri(interface) | ||
130 | 997 | response = self.client.get(uri) | ||
131 | 998 | self.assertEqual( | ||
132 | 999 | http.client.OK, response.status_code, response.content | ||
133 | 1000 | ) | ||
134 | 1001 | parsed_interface = json_load_bytes(response.content) | ||
135 | 1002 | expected_parts = { | ||
136 | 1003 | "id": interface.id, | ||
137 | 1004 | "tags": ["foo", "bar"], | ||
138 | 1005 | "enabled": True, | ||
139 | 1006 | "discovered": None, | ||
140 | 1007 | "effective_mtu": 1234, | ||
141 | 1008 | "link_connected": True, | ||
142 | 1009 | "interface_speed": 100, | ||
143 | 1010 | "link_speed": 10, | ||
144 | 1011 | "vlan": { | ||
145 | 1012 | "id": vlan.id, | ||
146 | 1013 | "dhcp_on": vlan.dhcp_on, | ||
147 | 1014 | "external_dhcp": vlan.external_dhcp, | ||
148 | 1015 | "fabric": vlan.fabric.get_name(), | ||
149 | 1016 | "fabric_id": vlan.fabric_id, | ||
150 | 1017 | "mtu": vlan.mtu, | ||
151 | 1018 | "primary_rack": None, | ||
152 | 1019 | "secondary_rack": None, | ||
153 | 1020 | "space": "undefined", | ||
154 | 1021 | "vid": vlan.vid, | ||
155 | 1022 | "name": vlan.get_name(), | ||
156 | 1023 | "relay_vlan": None, | ||
157 | 1024 | "resource_uri": f"/MAAS/api/2.0/vlans/{vlan.id}/", | ||
158 | 1025 | }, | ||
159 | 1026 | } | ||
160 | 1027 | for key, value in expected_parts.items(): | ||
161 | 1028 | self.assertEqual(parsed_interface[key], value) | ||
162 | 1029 | |||
163 | 890 | def test_read(self): | 1030 | def test_read(self): |
164 | 891 | node = factory.make_Node() | 1031 | node = factory.make_Node() |
165 | 892 | bond, parents, children = make_complex_interface(node) | 1032 | bond, parents, children = make_complex_interface(node) |
166 | 893 | # Add some known links to the bond interface. | ||
167 | 894 | 1033 | ||
171 | 895 | # First link is a DHCP link. | 1034 | # Add some known links to the bond interface. |
172 | 896 | links = [] | 1035 | dhcp_subnet = factory.make_Subnet(vlan=bond.vlan) |
170 | 897 | dhcp_subnet = factory.make_Subnet() | ||
173 | 898 | dhcp_ip = factory.make_StaticIPAddress( | 1036 | dhcp_ip = factory.make_StaticIPAddress( |
174 | 899 | alloc_type=IPADDRESS_TYPE.DHCP, | 1037 | alloc_type=IPADDRESS_TYPE.DHCP, |
175 | 900 | ip="", | 1038 | ip="", |
176 | @@ -908,19 +1046,9 @@ class TestNodeInterfaceAPI(APITransactionTestCase.ForUser): | |||
177 | 908 | subnet=dhcp_subnet, | 1046 | subnet=dhcp_subnet, |
178 | 909 | interface=bond, | 1047 | interface=bond, |
179 | 910 | ) | 1048 | ) |
180 | 911 | links.append( | ||
181 | 912 | MatchesDict( | ||
182 | 913 | { | ||
183 | 914 | "id": Equals(dhcp_ip.id), | ||
184 | 915 | "mode": Equals(INTERFACE_LINK_TYPE.DHCP), | ||
185 | 916 | "subnet": ContainsDict({"id": Equals(dhcp_subnet.id)}), | ||
186 | 917 | "ip_address": Equals(discovered_ip), | ||
187 | 918 | } | ||
188 | 919 | ) | ||
189 | 920 | ) | ||
190 | 921 | 1049 | ||
191 | 922 | # Second link is a STATIC ip link. | 1050 | # Second link is a STATIC ip link. |
193 | 923 | static_subnet = factory.make_Subnet() | 1051 | static_subnet = factory.make_Subnet(vlan=bond.vlan) |
194 | 924 | static_ip = factory.pick_ip_in_network(static_subnet.get_ipnetwork()) | 1052 | static_ip = factory.pick_ip_in_network(static_subnet.get_ipnetwork()) |
195 | 925 | sip = factory.make_StaticIPAddress( | 1053 | sip = factory.make_StaticIPAddress( |
196 | 926 | alloc_type=IPADDRESS_TYPE.STICKY, | 1054 | alloc_type=IPADDRESS_TYPE.STICKY, |
197 | @@ -928,40 +1056,21 @@ class TestNodeInterfaceAPI(APITransactionTestCase.ForUser): | |||
198 | 928 | subnet=static_subnet, | 1056 | subnet=static_subnet, |
199 | 929 | interface=bond, | 1057 | interface=bond, |
200 | 930 | ) | 1058 | ) |
201 | 931 | links.append( | ||
202 | 932 | MatchesDict( | ||
203 | 933 | { | ||
204 | 934 | "id": Equals(sip.id), | ||
205 | 935 | "mode": Equals(INTERFACE_LINK_TYPE.STATIC), | ||
206 | 936 | "ip_address": Equals(static_ip), | ||
207 | 937 | "subnet": ContainsDict({"id": Equals(static_subnet.id)}), | ||
208 | 938 | } | ||
209 | 939 | ) | ||
210 | 940 | ) | ||
211 | 941 | 1059 | ||
212 | 942 | # Third link is just a LINK_UP. In reality this cannot exist while the | 1060 | # Third link is just a LINK_UP. In reality this cannot exist while the |
213 | 943 | # other two links exist but for testing we allow it. If validation of | 1061 | # other two links exist but for testing we allow it. If validation of |
214 | 944 | # the StaticIPAddress model ever included this check, which it | 1062 | # the StaticIPAddress model ever included this check, which it |
215 | 945 | # probably should then this will fail and cause this test to break. | 1063 | # probably should then this will fail and cause this test to break. |
217 | 946 | link_subnet = factory.make_Subnet() | 1064 | link_subnet = factory.make_Subnet(vlan=bond.vlan) |
218 | 947 | link_ip = factory.make_StaticIPAddress( | 1065 | link_ip = factory.make_StaticIPAddress( |
219 | 948 | alloc_type=IPADDRESS_TYPE.STICKY, | 1066 | alloc_type=IPADDRESS_TYPE.STICKY, |
220 | 949 | ip="", | 1067 | ip="", |
221 | 950 | subnet=link_subnet, | 1068 | subnet=link_subnet, |
222 | 951 | interface=bond, | 1069 | interface=bond, |
223 | 952 | ) | 1070 | ) |
224 | 953 | links.append( | ||
225 | 954 | MatchesDict( | ||
226 | 955 | { | ||
227 | 956 | "id": Equals(link_ip.id), | ||
228 | 957 | "mode": Equals(INTERFACE_LINK_TYPE.LINK_UP), | ||
229 | 958 | "subnet": ContainsDict({"id": Equals(link_subnet.id)}), | ||
230 | 959 | } | ||
231 | 960 | ) | ||
232 | 961 | ) | ||
233 | 962 | 1071 | ||
234 | 963 | # Add MTU parameter. | 1072 | # Add MTU parameter. |
236 | 964 | bond.params = {"mtu": random.randint(800, 2000)} | 1073 | bond.params = {"mtu": 1234} |
237 | 965 | bond.save() | 1074 | bond.save() |
238 | 966 | 1075 | ||
239 | 967 | uri = get_interface_uri(bond) | 1076 | uri = get_interface_uri(bond) |
240 | @@ -970,33 +1079,77 @@ class TestNodeInterfaceAPI(APITransactionTestCase.ForUser): | |||
241 | 970 | http.client.OK, response.status_code, response.content | 1079 | http.client.OK, response.status_code, response.content |
242 | 971 | ) | 1080 | ) |
243 | 972 | parsed_interface = json_load_bytes(response.content) | 1081 | parsed_interface = json_load_bytes(response.content) |
261 | 973 | self.assertThat( | 1082 | |
262 | 974 | parsed_interface, | 1083 | expected_parts = { |
263 | 975 | ContainsDict( | 1084 | "id": bond.id, |
264 | 976 | { | 1085 | "name": bond.name, |
265 | 977 | "id": Equals(bond.id), | 1086 | "type": bond.type, |
266 | 978 | "name": Equals(bond.name), | 1087 | "mac_address": str(bond.mac_address), |
267 | 979 | "type": Equals(bond.type), | 1088 | "vlan": serialize_vlan(bond.vlan), |
268 | 980 | "vlan": ContainsDict({"id": Equals(bond.vlan.id)}), | 1089 | "tags": bond.tags, |
269 | 981 | "mac_address": Equals("%s" % bond.mac_address), | 1090 | "resource_uri": get_interface_uri(bond), |
270 | 982 | "tags": Equals(bond.tags), | 1091 | "params": {"mtu": 1234}, |
271 | 983 | "resource_uri": Equals(get_interface_uri(bond)), | 1092 | "effective_mtu": 1500, |
272 | 984 | "params": Equals(bond.params), | 1093 | "system_id": node.system_id, |
273 | 985 | "effective_mtu": Equals(bond.get_effective_mtu()), | 1094 | } |
274 | 986 | "system_id": Equals(node.system_id), | 1095 | for key, value in expected_parts.items(): |
275 | 987 | } | 1096 | self.assertEqual(parsed_interface[key], value) |
259 | 988 | ), | ||
260 | 989 | ) | ||
276 | 990 | self.assertEqual( | 1097 | self.assertEqual( |
277 | 991 | sorted(nic.name for nic in parents), parsed_interface["parents"] | 1098 | sorted(nic.name for nic in parents), parsed_interface["parents"] |
278 | 992 | ) | 1099 | ) |
279 | 993 | self.assertEqual( | 1100 | self.assertEqual( |
280 | 994 | sorted(nic.name for nic in children), parsed_interface["children"] | 1101 | sorted(nic.name for nic in children), parsed_interface["children"] |
281 | 995 | ) | 1102 | ) |
286 | 996 | self.assertThat(parsed_interface["links"], MatchesSetwise(*links)) | 1103 | |
287 | 997 | json_discovered = parsed_interface["discovered"][0] | 1104 | self.assertEqual( |
288 | 998 | self.assertEqual(dhcp_subnet.id, json_discovered["subnet"]["id"]) | 1105 | [ |
289 | 999 | self.assertEqual(discovered_ip, json_discovered["ip_address"]) | 1106 | { |
290 | 1107 | "id": dhcp_ip.id, | ||
291 | 1108 | "mode": "dhcp", | ||
292 | 1109 | "ip_address": discovered_ip, | ||
293 | 1110 | "subnet": serialize_subnet(dhcp_subnet), | ||
294 | 1111 | }, | ||
295 | 1112 | { | ||
296 | 1113 | "id": sip.id, | ||
297 | 1114 | "mode": "static", | ||
298 | 1115 | "ip_address": static_ip, | ||
299 | 1116 | "subnet": serialize_subnet(static_subnet), | ||
300 | 1117 | }, | ||
301 | 1118 | { | ||
302 | 1119 | "id": link_ip.id, | ||
303 | 1120 | "mode": "link_up", | ||
304 | 1121 | "subnet": serialize_subnet(link_subnet), | ||
305 | 1122 | }, | ||
306 | 1123 | ], | ||
307 | 1124 | parsed_interface["links"], | ||
308 | 1125 | ) | ||
309 | 1126 | self.assertEqual( | ||
310 | 1127 | [ | ||
311 | 1128 | { | ||
312 | 1129 | "ip_address": discovered_ip, | ||
313 | 1130 | "subnet": serialize_subnet(dhcp_subnet), | ||
314 | 1131 | }, | ||
315 | 1132 | ], | ||
316 | 1133 | parsed_interface["discovered"], | ||
317 | 1134 | ) | ||
318 | 1135 | |||
319 | 1136 | def test_read_effective_mtu(self): | ||
320 | 1137 | node = factory.make_Node() | ||
321 | 1138 | bond, parents, children = make_complex_interface(node) | ||
322 | 1139 | bond.params = {"mtu": 1000} | ||
323 | 1140 | bond.save() | ||
324 | 1141 | children[0].params = {"mtu": 2000} | ||
325 | 1142 | children[0].save() | ||
326 | 1143 | |||
327 | 1144 | uri = get_interface_uri(bond) | ||
328 | 1145 | response = self.client.get(uri) | ||
329 | 1146 | self.assertEqual( | ||
330 | 1147 | http.client.OK, response.status_code, response.content | ||
331 | 1148 | ) | ||
332 | 1149 | parsed_interface = json_load_bytes(response.content) | ||
333 | 1150 | |||
334 | 1151 | self.assertEqual(bond.id, parsed_interface["id"]) | ||
335 | 1152 | self.assertEqual(2000, parsed_interface["effective_mtu"]) | ||
336 | 1000 | 1153 | ||
337 | 1001 | def test_read_by_specifier(self): | 1154 | def test_read_by_specifier(self): |
338 | 1002 | node = factory.make_Node(hostname="tasty-biscuits") | 1155 | node = factory.make_Node(hostname="tasty-biscuits") |
339 | diff --git a/src/maasserver/api/tests/test_subnets.py b/src/maasserver/api/tests/test_subnets.py | |||
340 | index c85dede..2fc8cad 100644 | |||
341 | --- a/src/maasserver/api/tests/test_subnets.py | |||
342 | +++ b/src/maasserver/api/tests/test_subnets.py | |||
343 | @@ -8,12 +8,18 @@ import random | |||
344 | 8 | 8 | ||
345 | 9 | from django.conf import settings | 9 | from django.conf import settings |
346 | 10 | from django.urls import reverse | 10 | from django.urls import reverse |
350 | 11 | from testtools.matchers import Contains, ContainsDict, Equals | 11 | from testtools.matchers import Contains, Equals |
351 | 12 | 12 | ||
352 | 13 | from maasserver.enum import IPADDRESS_TYPE, NODE_STATUS, RDNS_MODE_CHOICES | 13 | from maasserver.enum import ( |
353 | 14 | IPADDRESS_TYPE, | ||
354 | 15 | NODE_STATUS, | ||
355 | 16 | RDNS_MODE, | ||
356 | 17 | RDNS_MODE_CHOICES, | ||
357 | 18 | ) | ||
358 | 14 | from maasserver.testing.api import APITestCase, explain_unexpected_response | 19 | from maasserver.testing.api import APITestCase, explain_unexpected_response |
360 | 15 | from maasserver.testing.factory import factory, RANDOM | 20 | from maasserver.testing.factory import factory |
361 | 16 | from maasserver.utils.orm import reload_object | 21 | from maasserver.utils.orm import reload_object |
362 | 22 | from maastesting.djangotestcase import CountQueries | ||
363 | 17 | from provisioningserver.boot import BootMethodRegistry | 23 | from provisioningserver.boot import BootMethodRegistry |
364 | 18 | from provisioningserver.utils.network import inet_ntop, IPRangeStatistics | 24 | from provisioningserver.utils.network import inet_ntop, IPRangeStatistics |
365 | 19 | 25 | ||
366 | @@ -36,21 +42,58 @@ class TestSubnetsAPI(APITestCase.ForUser): | |||
367 | 36 | self.assertEqual("/MAAS/api/2.0/subnets/", get_subnets_uri()) | 42 | self.assertEqual("/MAAS/api/2.0/subnets/", get_subnets_uri()) |
368 | 37 | 43 | ||
369 | 38 | def test_read(self): | 44 | def test_read(self): |
371 | 39 | subnets = [factory.make_Subnet() for _ in range(3)] | 45 | def make_subnet(): |
372 | 46 | space = factory.make_Space() | ||
373 | 47 | subnet = factory.make_Subnet(space=space) | ||
374 | 48 | primary_rack = factory.make_RackController(subnet=subnet) | ||
375 | 49 | secondary_rack = factory.make_RackController(subnet=subnet) | ||
376 | 50 | relay_vlan = factory.make_VLAN() | ||
377 | 51 | vlan = subnet.vlan | ||
378 | 52 | vlan.dhcp_on = True | ||
379 | 53 | vlan.primary_rack = primary_rack | ||
380 | 54 | vlan.secondary_rack = secondary_rack | ||
381 | 55 | vlan.relay_vlan = relay_vlan | ||
382 | 56 | vlan.save() | ||
383 | 57 | return subnet | ||
384 | 58 | |||
385 | 59 | subnets = [make_subnet()] | ||
386 | 40 | uri = get_subnets_uri() | 60 | uri = get_subnets_uri() |
388 | 41 | response = self.client.get(uri) | 61 | with CountQueries() as counter: |
389 | 62 | response = self.client.get(uri) | ||
390 | 63 | base_count = counter.count | ||
391 | 42 | 64 | ||
392 | 43 | self.assertEqual( | 65 | self.assertEqual( |
393 | 44 | http.client.OK, response.status_code, response.content | 66 | http.client.OK, response.status_code, response.content |
394 | 45 | ) | 67 | ) |
396 | 46 | expected_ids = [subnet.id for subnet in subnets] | 68 | |
397 | 47 | result_ids = [ | 69 | result_ids = [ |
398 | 48 | subnet["id"] | 70 | subnet["id"] |
399 | 49 | for subnet in json.loads( | 71 | for subnet in json.loads( |
400 | 50 | response.content.decode(settings.DEFAULT_CHARSET) | 72 | response.content.decode(settings.DEFAULT_CHARSET) |
401 | 51 | ) | 73 | ) |
402 | 52 | ] | 74 | ] |
404 | 53 | self.assertCountEqual(expected_ids, result_ids) | 75 | self.assertCountEqual( |
405 | 76 | [subnet.id for subnet in subnets], | ||
406 | 77 | result_ids, | ||
407 | 78 | json.loads(response.content.decode(settings.DEFAULT_CHARSET)), | ||
408 | 79 | ) | ||
409 | 80 | |||
410 | 81 | subnets.append(make_subnet()) | ||
411 | 82 | with CountQueries() as counter: | ||
412 | 83 | response = self.client.get(uri) | ||
413 | 84 | # XXX: These should be the same. | ||
414 | 85 | self.assertEqual(base_count + 7, counter.count) | ||
415 | 86 | |||
416 | 87 | self.assertEqual( | ||
417 | 88 | http.client.OK, response.status_code, response.content | ||
418 | 89 | ) | ||
419 | 90 | result_ids = [ | ||
420 | 91 | subnet["id"] | ||
421 | 92 | for subnet in json.loads( | ||
422 | 93 | response.content.decode(settings.DEFAULT_CHARSET) | ||
423 | 94 | ) | ||
424 | 95 | ] | ||
425 | 96 | self.assertCountEqual([subnet.id for subnet in subnets], result_ids) | ||
426 | 54 | 97 | ||
427 | 55 | def test_create(self): | 98 | def test_create(self): |
428 | 56 | self.become_admin() | 99 | self.become_admin() |
429 | @@ -269,8 +312,15 @@ class TestSubnetAPI(APITestCase.ForUser): | |||
430 | 269 | "/MAAS/api/2.0/subnets/%s/" % subnet.id, get_subnet_uri(subnet) | 312 | "/MAAS/api/2.0/subnets/%s/" % subnet.id, get_subnet_uri(subnet) |
431 | 270 | ) | 313 | ) |
432 | 271 | 314 | ||
435 | 272 | def test_read(self): | 315 | def test_read_basic(self): |
436 | 273 | subnet = factory.make_Subnet(space=RANDOM) | 316 | subnet = factory.make_Subnet( |
437 | 317 | name="my-subnet", | ||
438 | 318 | cidr="10.10.10.0/24", | ||
439 | 319 | gateway_ip=None, | ||
440 | 320 | space=None, | ||
441 | 321 | dns_servers=[], | ||
442 | 322 | disabled_boot_architectures=[], | ||
443 | 323 | ) | ||
444 | 274 | uri = get_subnet_uri(subnet) | 324 | uri = get_subnet_uri(subnet) |
445 | 275 | response = self.client.get(uri) | 325 | response = self.client.get(uri) |
446 | 276 | 326 | ||
447 | @@ -280,34 +330,100 @@ class TestSubnetAPI(APITestCase.ForUser): | |||
448 | 280 | parsed_subnet = json.loads( | 330 | parsed_subnet = json.loads( |
449 | 281 | response.content.decode(settings.DEFAULT_CHARSET) | 331 | response.content.decode(settings.DEFAULT_CHARSET) |
450 | 282 | ) | 332 | ) |
452 | 283 | self.assertThat( | 333 | self.assertEqual( |
453 | 284 | parsed_subnet, | 334 | parsed_subnet, |
469 | 285 | ContainsDict( | 335 | { |
470 | 286 | { | 336 | "id": subnet.id, |
471 | 287 | "id": Equals(subnet.id), | 337 | "name": "my-subnet", |
472 | 288 | "name": Equals(subnet.name), | 338 | "active_discovery": False, |
473 | 289 | "vlan": ContainsDict({"vid": Equals(subnet.vlan.vid)}), | 339 | "allow_dns": True, |
474 | 290 | "space": Equals(subnet.space.get_name()), | 340 | "allow_proxy": True, |
475 | 291 | "cidr": Equals(subnet.cidr), | 341 | "description": "", |
476 | 292 | "gateway_ip": Equals(subnet.gateway_ip), | 342 | "space": "undefined", |
477 | 293 | "dns_servers": Equals(subnet.dns_servers), | 343 | "cidr": "10.10.10.0/24", |
478 | 294 | "managed": Equals(subnet.managed), | 344 | "gateway_ip": None, |
479 | 295 | "disabled_boot_architectures": Equals( | 345 | "dns_servers": [], |
480 | 296 | subnet.disabled_boot_architectures | 346 | "managed": True, |
481 | 297 | ), | 347 | "disabled_boot_architectures": [], |
482 | 298 | } | 348 | "rdns_mode": RDNS_MODE.DEFAULT, |
483 | 299 | ), | 349 | "resource_uri": f"/MAAS/api/2.0/subnets/{subnet.id}/", |
484 | 350 | "vlan": { | ||
485 | 351 | "id": subnet.vlan_id, | ||
486 | 352 | "dhcp_on": subnet.vlan.dhcp_on, | ||
487 | 353 | "external_dhcp": subnet.vlan.external_dhcp, | ||
488 | 354 | "fabric": subnet.vlan.fabric.get_name(), | ||
489 | 355 | "fabric_id": subnet.vlan.fabric_id, | ||
490 | 356 | "mtu": subnet.vlan.mtu, | ||
491 | 357 | "primary_rack": None, | ||
492 | 358 | "secondary_rack": None, | ||
493 | 359 | "space": "undefined", | ||
494 | 360 | "vid": subnet.vlan.vid, | ||
495 | 361 | "name": subnet.vlan.get_name(), | ||
496 | 362 | "relay_vlan": None, | ||
497 | 363 | "resource_uri": f"/MAAS/api/2.0/vlans/{subnet.vlan_id}/", | ||
498 | 364 | }, | ||
499 | 365 | }, | ||
500 | 300 | ) | 366 | ) |
501 | 301 | 367 | ||
505 | 302 | def test_read_includes_description(self): | 368 | def test_read_full(self): |
506 | 303 | description = factory.make_string() | 369 | space = factory.make_Space(name="my-space") |
507 | 304 | subnet = factory.make_Subnet(space=RANDOM, description=description) | 370 | subnet = factory.make_Subnet( |
508 | 371 | name="my-subnet", | ||
509 | 372 | cidr="10.20.20.0/24", | ||
510 | 373 | gateway_ip="10.20.20.1", | ||
511 | 374 | space=space, | ||
512 | 375 | dns_servers=["10.20.20.20"], | ||
513 | 376 | disabled_boot_architectures=["pxe"], | ||
514 | 377 | active_discovery=True, | ||
515 | 378 | allow_proxy=False, | ||
516 | 379 | allow_dns=False, | ||
517 | 380 | description="My subnet", | ||
518 | 381 | managed=False, | ||
519 | 382 | rdns_mode=RDNS_MODE.DISABLED, | ||
520 | 383 | ) | ||
521 | 305 | uri = get_subnet_uri(subnet) | 384 | uri = get_subnet_uri(subnet) |
522 | 306 | response = self.client.get(uri) | 385 | response = self.client.get(uri) |
523 | 386 | |||
524 | 387 | self.assertEqual( | ||
525 | 388 | http.client.OK, response.status_code, response.content | ||
526 | 389 | ) | ||
527 | 307 | parsed_subnet = json.loads( | 390 | parsed_subnet = json.loads( |
528 | 308 | response.content.decode(settings.DEFAULT_CHARSET) | 391 | response.content.decode(settings.DEFAULT_CHARSET) |
529 | 309 | ) | 392 | ) |
531 | 310 | self.assertEqual(description, parsed_subnet["description"]) | 393 | self.assertEqual( |
532 | 394 | parsed_subnet, | ||
533 | 395 | { | ||
534 | 396 | "id": subnet.id, | ||
535 | 397 | "name": "my-subnet", | ||
536 | 398 | "active_discovery": True, | ||
537 | 399 | "allow_dns": False, | ||
538 | 400 | "allow_proxy": False, | ||
539 | 401 | "description": "My subnet", | ||
540 | 402 | "space": "my-space", | ||
541 | 403 | "cidr": "10.20.20.0/24", | ||
542 | 404 | "gateway_ip": "10.20.20.1", | ||
543 | 405 | "dns_servers": ["10.20.20.20"], | ||
544 | 406 | "managed": False, | ||
545 | 407 | "disabled_boot_architectures": ["pxe"], | ||
546 | 408 | "rdns_mode": RDNS_MODE.DISABLED, | ||
547 | 409 | "resource_uri": f"/MAAS/api/2.0/subnets/{subnet.id}/", | ||
548 | 410 | "vlan": { | ||
549 | 411 | "id": subnet.vlan_id, | ||
550 | 412 | "dhcp_on": subnet.vlan.dhcp_on, | ||
551 | 413 | "external_dhcp": subnet.vlan.external_dhcp, | ||
552 | 414 | "fabric": subnet.vlan.fabric.get_name(), | ||
553 | 415 | "fabric_id": subnet.vlan.fabric_id, | ||
554 | 416 | "mtu": subnet.vlan.mtu, | ||
555 | 417 | "primary_rack": None, | ||
556 | 418 | "secondary_rack": None, | ||
557 | 419 | "space": "my-space", | ||
558 | 420 | "vid": subnet.vlan.vid, | ||
559 | 421 | "name": subnet.vlan.get_name(), | ||
560 | 422 | "relay_vlan": None, | ||
561 | 423 | "resource_uri": f"/MAAS/api/2.0/vlans/{subnet.vlan_id}/", | ||
562 | 424 | }, | ||
563 | 425 | }, | ||
564 | 426 | ) | ||
565 | 311 | 427 | ||
566 | 312 | def test_read_404_when_bad_id(self): | 428 | def test_read_404_when_bad_id(self): |
567 | 313 | uri = reverse("subnet_handler", args=[random.randint(100, 1000)]) | 429 | uri = reverse("subnet_handler", args=[random.randint(100, 1000)]) |
568 | diff --git a/src/maasserver/api/tests/test_vlans.py b/src/maasserver/api/tests/test_vlans.py | |||
569 | index 2296787..38665d2 100644 | |||
570 | --- a/src/maasserver/api/tests/test_vlans.py | |||
571 | +++ b/src/maasserver/api/tests/test_vlans.py | |||
572 | @@ -10,12 +10,13 @@ import random | |||
573 | 10 | 10 | ||
574 | 11 | from django.conf import settings | 11 | from django.conf import settings |
575 | 12 | from django.urls import reverse | 12 | from django.urls import reverse |
577 | 13 | from testtools.matchers import ContainsDict, Equals, Is, Not | 13 | from testtools.matchers import Equals, Is, Not |
578 | 14 | 14 | ||
580 | 15 | from maasserver.models import Space | 15 | from maasserver.models import Space, VLAN |
581 | 16 | from maasserver.testing.api import APITestCase | 16 | from maasserver.testing.api import APITestCase |
582 | 17 | from maasserver.testing.factory import factory, RANDOM | 17 | from maasserver.testing.factory import factory, RANDOM |
583 | 18 | from maasserver.utils.orm import reload_object | 18 | from maasserver.utils.orm import reload_object |
584 | 19 | from maastesting.djangotestcase import CountQueries | ||
585 | 19 | 20 | ||
586 | 20 | 21 | ||
587 | 21 | def get_vlans_uri(fabric): | 22 | def get_vlans_uri(fabric): |
588 | @@ -41,23 +42,71 @@ class TestVlansAPI(APITestCase.ForUser): | |||
589 | 41 | ) | 42 | ) |
590 | 42 | 43 | ||
591 | 43 | def test_read(self): | 44 | def test_read(self): |
592 | 45 | def make_vlan(): | ||
593 | 46 | space = factory.make_Space() | ||
594 | 47 | subnet = factory.make_Subnet(fabric=fabric, space=space) | ||
595 | 48 | primary_rack = factory.make_RackController() | ||
596 | 49 | factory.make_Interface(node=primary_rack, subnet=subnet) | ||
597 | 50 | secondary_rack = factory.make_RackController() | ||
598 | 51 | factory.make_Interface(node=secondary_rack, subnet=subnet) | ||
599 | 52 | relay_vlan = factory.make_VLAN() | ||
600 | 53 | vlan = subnet.vlan | ||
601 | 54 | vlan.dhcp_on = True | ||
602 | 55 | vlan.primary_rack = primary_rack | ||
603 | 56 | vlan.secondary_rack = secondary_rack | ||
604 | 57 | vlan.relay_vlan = relay_vlan | ||
605 | 58 | vlan.save() | ||
606 | 59 | |||
607 | 60 | def serialize_vlan(vlan): | ||
608 | 61 | return { | ||
609 | 62 | "id": vlan.id, | ||
610 | 63 | "name": vlan.get_name(), | ||
611 | 64 | "vid": vlan.vid, | ||
612 | 65 | "fabric": vlan.fabric.name, | ||
613 | 66 | "fabric_id": vlan.fabric_id, | ||
614 | 67 | "mtu": vlan.mtu, | ||
615 | 68 | "primary_rack": ( | ||
616 | 69 | vlan.primary_rack.system_id if vlan.primary_rack else None | ||
617 | 70 | ), | ||
618 | 71 | "secondary_rack": ( | ||
619 | 72 | vlan.secondary_rack.system_id | ||
620 | 73 | if vlan.secondary_rack | ||
621 | 74 | else None | ||
622 | 75 | ), | ||
623 | 76 | "dhcp_on": vlan.dhcp_on, | ||
624 | 77 | "external_dhcp": None, | ||
625 | 78 | "relay_vlan": serialize_vlan(vlan.relay_vlan) | ||
626 | 79 | if vlan.relay_vlan | ||
627 | 80 | else None, | ||
628 | 81 | "space": vlan.space.name if vlan.space else "undefined", | ||
629 | 82 | "resource_uri": f"/MAAS/api/2.0/vlans/{vlan.id}/", | ||
630 | 83 | } | ||
631 | 84 | |||
632 | 44 | fabric = factory.make_Fabric() | 85 | fabric = factory.make_Fabric() |
635 | 45 | for vid in range(1, 4): | 86 | make_vlan() |
636 | 46 | factory.make_VLAN(vid=vid, fabric=fabric) | 87 | |
637 | 47 | uri = get_vlans_uri(fabric) | 88 | uri = get_vlans_uri(fabric) |
639 | 48 | response = self.client.get(uri) | 89 | with CountQueries() as counter: |
640 | 90 | response = self.client.get(uri) | ||
641 | 91 | base_count = counter.count | ||
642 | 49 | 92 | ||
643 | 50 | self.assertEqual( | 93 | self.assertEqual( |
644 | 51 | http.client.OK, response.status_code, response.content | 94 | http.client.OK, response.status_code, response.content |
645 | 52 | ) | 95 | ) |
654 | 53 | expected_ids = [vlan.vid for vlan in fabric.vlan_set.all()] | 96 | result = json.loads(response.content.decode(settings.DEFAULT_CHARSET)) |
655 | 54 | result_ids = [ | 97 | # It's three VLANs, since when creating a fabric, a default VLAN |
656 | 55 | vlan["vid"] | 98 | # is always created. |
657 | 56 | for vlan in json.loads( | 99 | vlans = {vlan.id: vlan for vlan in VLAN.objects.filter(fabric=fabric)} |
658 | 57 | response.content.decode(settings.DEFAULT_CHARSET) | 100 | self.assertEqual(2, len(result)) |
659 | 58 | ) | 101 | for serialized_vlan in result: |
660 | 59 | ] | 102 | vlan = vlans[serialized_vlan["id"]] |
661 | 60 | self.assertCountEqual(expected_ids, result_ids) | 103 | self.assertEqual(serialize_vlan(vlan), serialized_vlan) |
662 | 104 | |||
663 | 105 | make_vlan() | ||
664 | 106 | with CountQueries() as counter: | ||
665 | 107 | response = self.client.get(uri) | ||
666 | 108 | # XXX: These really should be equal. | ||
667 | 109 | self.assertEqual(base_count + 5, counter.count) | ||
668 | 61 | 110 | ||
669 | 62 | def test_create(self): | 111 | def test_create(self): |
670 | 63 | self.become_admin() | 112 | self.become_admin() |
671 | @@ -187,9 +236,11 @@ class TestVlanAPI(APITestCase.ForUser): | |||
672 | 187 | "/MAAS/api/2.0/vlans/%s/" % vlan.id, get_vlan_uri(vlan) | 236 | "/MAAS/api/2.0/vlans/%s/" % vlan.id, get_vlan_uri(vlan) |
673 | 188 | ) | 237 | ) |
674 | 189 | 238 | ||
678 | 190 | def test_read(self): | 239 | def test_read_basic(self): |
679 | 191 | fabric = factory.make_Fabric() | 240 | fabric = factory.make_Fabric(name="my-fabric") |
680 | 192 | vlan = factory.make_VLAN(fabric=fabric) | 241 | vlan = factory.make_VLAN( |
681 | 242 | fabric=fabric, name="my-vlan", vid=123, mtu=1234 | ||
682 | 243 | ) | ||
683 | 193 | uri = get_vlan_uri(vlan) | 244 | uri = get_vlan_uri(vlan) |
684 | 194 | response = self.client.get(uri) | 245 | response = self.client.get(uri) |
685 | 195 | 246 | ||
686 | @@ -199,24 +250,29 @@ class TestVlanAPI(APITestCase.ForUser): | |||
687 | 199 | parsed_vlan = json.loads( | 250 | parsed_vlan = json.loads( |
688 | 200 | response.content.decode(settings.DEFAULT_CHARSET) | 251 | response.content.decode(settings.DEFAULT_CHARSET) |
689 | 201 | ) | 252 | ) |
691 | 202 | self.assertThat( | 253 | self.assertEqual( |
692 | 203 | parsed_vlan, | 254 | parsed_vlan, |
709 | 204 | ContainsDict( | 255 | { |
710 | 205 | { | 256 | "id": vlan.id, |
711 | 206 | "id": Equals(vlan.id), | 257 | "name": "my-vlan", |
712 | 207 | "name": Equals(vlan.get_name()), | 258 | "vid": 123, |
713 | 208 | "vid": Equals(vlan.vid), | 259 | "fabric": "my-fabric", |
714 | 209 | "fabric": Equals(fabric.get_name()), | 260 | "fabric_id": fabric.id, |
715 | 210 | "fabric_id": Equals(fabric.id), | 261 | "mtu": 1234, |
716 | 211 | "resource_uri": Equals(get_vlan_uri(vlan)), | 262 | "primary_rack": None, |
717 | 212 | } | 263 | "secondary_rack": None, |
718 | 213 | ), | 264 | "dhcp_on": False, |
719 | 214 | ) | 265 | "external_dhcp": None, |
720 | 215 | 266 | "relay_vlan": None, | |
721 | 216 | def test_read_with_fabric(self): | 267 | "space": "undefined", |
722 | 217 | fabric = factory.make_Fabric() | 268 | "resource_uri": f"/MAAS/api/2.0/vlans/{vlan.id}/", |
723 | 218 | vlan = factory.make_VLAN(fabric=fabric) | 269 | }, |
724 | 219 | uri = get_vlan_uri(vlan, fabric) | 270 | ) |
725 | 271 | |||
726 | 272 | def test_read_with_space(self): | ||
727 | 273 | space = factory.make_Space(name="my-space") | ||
728 | 274 | vlan = factory.make_VLAN(space=space) | ||
729 | 275 | uri = get_vlan_uri(vlan, vlan.fabric) | ||
730 | 220 | response = self.client.get(uri) | 276 | response = self.client.get(uri) |
731 | 221 | 277 | ||
732 | 222 | self.assertEqual( | 278 | self.assertEqual( |
733 | @@ -225,22 +281,19 @@ class TestVlanAPI(APITestCase.ForUser): | |||
734 | 225 | parsed_vlan = json.loads( | 281 | parsed_vlan = json.loads( |
735 | 226 | response.content.decode(settings.DEFAULT_CHARSET) | 282 | response.content.decode(settings.DEFAULT_CHARSET) |
736 | 227 | ) | 283 | ) |
753 | 228 | self.assertThat( | 284 | self.assertEqual(parsed_vlan["space"], "my-space") |
754 | 229 | parsed_vlan, | 285 | |
755 | 230 | ContainsDict( | 286 | def test_read_with_dhcp(self): |
756 | 231 | { | 287 | subnet = factory.make_Subnet() |
757 | 232 | "id": Equals(vlan.id), | 288 | primary_rack = factory.make_RackController() |
758 | 233 | "name": Equals(vlan.get_name()), | 289 | factory.make_Interface(node=primary_rack, subnet=subnet) |
759 | 234 | "vid": Equals(vlan.vid), | 290 | secondary_rack = factory.make_RackController() |
760 | 235 | "fabric": Equals(fabric.get_name()), | 291 | factory.make_Interface(node=secondary_rack, subnet=subnet) |
761 | 236 | "resource_uri": Equals(get_vlan_uri(vlan)), | 292 | vlan = subnet.vlan |
762 | 237 | } | 293 | vlan.dhcp_on = True |
763 | 238 | ), | 294 | vlan.primary_rack = primary_rack |
764 | 239 | ) | 295 | vlan.secondary_rack = secondary_rack |
765 | 240 | 296 | vlan.save() | |
750 | 241 | def test_read_with_space(self): | ||
751 | 242 | space = factory.make_Space() | ||
752 | 243 | vlan = factory.make_VLAN(space=space) | ||
766 | 244 | uri = get_vlan_uri(vlan, vlan.fabric) | 297 | uri = get_vlan_uri(vlan, vlan.fabric) |
767 | 245 | response = self.client.get(uri) | 298 | response = self.client.get(uri) |
768 | 246 | 299 | ||
769 | @@ -250,21 +303,15 @@ class TestVlanAPI(APITestCase.ForUser): | |||
770 | 250 | parsed_vlan = json.loads( | 303 | parsed_vlan = json.loads( |
771 | 251 | response.content.decode(settings.DEFAULT_CHARSET) | 304 | response.content.decode(settings.DEFAULT_CHARSET) |
772 | 252 | ) | 305 | ) |
788 | 253 | self.assertThat( | 306 | self.assertTrue(parsed_vlan["dhcp_on"]) |
789 | 254 | parsed_vlan, | 307 | self.assertEqual(primary_rack.system_id, parsed_vlan["primary_rack"]) |
790 | 255 | ContainsDict( | 308 | self.assertEqual( |
791 | 256 | { | 309 | secondary_rack.system_id, parsed_vlan["secondary_rack"] |
792 | 257 | "id": Equals(vlan.id), | 310 | ) |
793 | 258 | "name": Equals(vlan.get_name()), | 311 | |
794 | 259 | "vid": Equals(vlan.vid), | 312 | def test_read_with_relay_vlan(self): |
795 | 260 | "space": Equals(space.get_name()), | 313 | relay_vlan = factory.make_VLAN(name="my-relay") |
796 | 261 | "resource_uri": Equals(get_vlan_uri(vlan)), | 314 | vlan = factory.make_VLAN(relay_vlan=relay_vlan) |
782 | 262 | } | ||
783 | 263 | ), | ||
784 | 264 | ) | ||
785 | 265 | |||
786 | 266 | def test_read_without_space_returns_undefined_space(self): | ||
787 | 267 | vlan = factory.make_VLAN(space=None) | ||
797 | 268 | uri = get_vlan_uri(vlan, vlan.fabric) | 315 | uri = get_vlan_uri(vlan, vlan.fabric) |
798 | 269 | response = self.client.get(uri) | 316 | response = self.client.get(uri) |
799 | 270 | 317 | ||
800 | @@ -274,17 +321,23 @@ class TestVlanAPI(APITestCase.ForUser): | |||
801 | 274 | parsed_vlan = json.loads( | 321 | parsed_vlan = json.loads( |
802 | 275 | response.content.decode(settings.DEFAULT_CHARSET) | 322 | response.content.decode(settings.DEFAULT_CHARSET) |
803 | 276 | ) | 323 | ) |
815 | 277 | self.assertThat( | 324 | self.assertEqual( |
816 | 278 | parsed_vlan, | 325 | { |
817 | 279 | ContainsDict( | 326 | "id": relay_vlan.id, |
818 | 280 | { | 327 | "name": "my-relay", |
819 | 281 | "id": Equals(vlan.id), | 328 | "vid": relay_vlan.vid, |
820 | 282 | "name": Equals(vlan.get_name()), | 329 | "fabric": relay_vlan.fabric.name, |
821 | 283 | "vid": Equals(vlan.vid), | 330 | "fabric_id": relay_vlan.fabric_id, |
822 | 284 | "space": Equals(Space.UNDEFINED), | 331 | "mtu": relay_vlan.mtu, |
823 | 285 | "resource_uri": Equals(get_vlan_uri(vlan)), | 332 | "primary_rack": None, |
824 | 286 | } | 333 | "secondary_rack": None, |
825 | 287 | ), | 334 | "dhcp_on": False, |
826 | 335 | "external_dhcp": None, | ||
827 | 336 | "relay_vlan": None, | ||
828 | 337 | "space": "undefined", | ||
829 | 338 | "resource_uri": f"/MAAS/api/2.0/vlans/{relay_vlan.id}/", | ||
830 | 339 | }, | ||
831 | 340 | parsed_vlan["relay_vlan"], | ||
832 | 288 | ) | 341 | ) |
833 | 289 | 342 | ||
834 | 290 | def test_read_404_when_bad_id(self): | 343 | def test_read_404_when_bad_id(self): |
835 | diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py | |||
836 | index afaabfe..99e5258 100644 | |||
837 | --- a/src/maasserver/testing/factory.py | |||
838 | +++ b/src/maasserver/testing/factory.py | |||
839 | @@ -1617,6 +1617,7 @@ class Factory(maastesting.factory.Factory): | |||
840 | 1617 | primary_rack=None, | 1617 | primary_rack=None, |
841 | 1618 | secondary_rack=None, | 1618 | secondary_rack=None, |
842 | 1619 | relay_vlan=None, | 1619 | relay_vlan=None, |
843 | 1620 | mtu=1500, | ||
844 | 1620 | ): | 1621 | ): |
845 | 1621 | assert vid != 0, "VID=0 VLANs are auto-created" | 1622 | assert vid != 0, "VID=0 VLANs are auto-created" |
846 | 1622 | if name is RANDOM: | 1623 | if name is RANDOM: |
847 | @@ -1636,6 +1637,7 @@ class Factory(maastesting.factory.Factory): | |||
848 | 1636 | primary_rack=primary_rack, | 1637 | primary_rack=primary_rack, |
849 | 1637 | secondary_rack=secondary_rack, | 1638 | secondary_rack=secondary_rack, |
850 | 1638 | relay_vlan=relay_vlan, | 1639 | relay_vlan=relay_vlan, |
851 | 1640 | mtu=mtu, | ||
852 | 1639 | ) | 1641 | ) |
853 | 1640 | vlan.save() | 1642 | vlan.save() |
854 | 1641 | for rack in [primary_rack, secondary_rack]: | 1643 | for rack in [primary_rack, secondary_rack]: |
UNIT TESTS
-b api-better-tests lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED maas-ci. internal: 8080/job/ maas/job/ branch- tester/ 12366/console 5657fd1db21c323 73ea32b9d7
LOG: http://
COMMIT: e91fd87abc9b6a0