test_api.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. from __future__ import unicode_literals
  2. from django.urls import reverse
  3. from netaddr import IPNetwork
  4. from rest_framework import status
  5. from dcim.constants import IFACE_FF_VIRTUAL, IFACE_MODE_TAGGED
  6. from dcim.models import Interface
  7. from ipam.models import IPAddress, VLAN
  8. from utilities.testing import APITestCase
  9. from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
  10. class ClusterTypeTest(APITestCase):
  11. def setUp(self):
  12. super(ClusterTypeTest, self).setUp()
  13. self.clustertype1 = ClusterType.objects.create(name='Test Cluster Type 1', slug='test-cluster-type-1')
  14. self.clustertype2 = ClusterType.objects.create(name='Test Cluster Type 2', slug='test-cluster-type-2')
  15. self.clustertype3 = ClusterType.objects.create(name='Test Cluster Type 3', slug='test-cluster-type-3')
  16. def test_get_clustertype(self):
  17. url = reverse('virtualization-api:clustertype-detail', kwargs={'pk': self.clustertype1.pk})
  18. response = self.client.get(url, **self.header)
  19. self.assertEqual(response.data['name'], self.clustertype1.name)
  20. def test_list_clustertypes(self):
  21. url = reverse('virtualization-api:clustertype-list')
  22. response = self.client.get(url, **self.header)
  23. self.assertEqual(response.data['count'], 3)
  24. def test_create_clustertype(self):
  25. data = {
  26. 'name': 'Test Cluster Type 4',
  27. 'slug': 'test-cluster-type-4',
  28. }
  29. url = reverse('virtualization-api:clustertype-list')
  30. response = self.client.post(url, data, format='json', **self.header)
  31. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  32. self.assertEqual(ClusterType.objects.count(), 4)
  33. clustertype4 = ClusterType.objects.get(pk=response.data['id'])
  34. self.assertEqual(clustertype4.name, data['name'])
  35. self.assertEqual(clustertype4.slug, data['slug'])
  36. def test_create_clustertype_bulk(self):
  37. data = [
  38. {
  39. 'name': 'Test Cluster Type 4',
  40. 'slug': 'test-cluster-type-4',
  41. },
  42. {
  43. 'name': 'Test Cluster Type 5',
  44. 'slug': 'test-cluster-type-5',
  45. },
  46. {
  47. 'name': 'Test Cluster Type 6',
  48. 'slug': 'test-cluster-type-6',
  49. },
  50. ]
  51. url = reverse('virtualization-api:clustertype-list')
  52. response = self.client.post(url, data, format='json', **self.header)
  53. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  54. self.assertEqual(ClusterType.objects.count(), 6)
  55. self.assertEqual(response.data[0]['name'], data[0]['name'])
  56. self.assertEqual(response.data[1]['name'], data[1]['name'])
  57. self.assertEqual(response.data[2]['name'], data[2]['name'])
  58. def test_update_clustertype(self):
  59. data = {
  60. 'name': 'Test Cluster Type X',
  61. 'slug': 'test-cluster-type-x',
  62. }
  63. url = reverse('virtualization-api:clustertype-detail', kwargs={'pk': self.clustertype1.pk})
  64. response = self.client.put(url, data, format='json', **self.header)
  65. self.assertHttpStatus(response, status.HTTP_200_OK)
  66. self.assertEqual(ClusterType.objects.count(), 3)
  67. clustertype1 = ClusterType.objects.get(pk=response.data['id'])
  68. self.assertEqual(clustertype1.name, data['name'])
  69. self.assertEqual(clustertype1.slug, data['slug'])
  70. def test_delete_clustertype(self):
  71. url = reverse('virtualization-api:clustertype-detail', kwargs={'pk': self.clustertype1.pk})
  72. response = self.client.delete(url, **self.header)
  73. self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
  74. self.assertEqual(ClusterType.objects.count(), 2)
  75. class ClusterGroupTest(APITestCase):
  76. def setUp(self):
  77. super(ClusterGroupTest, self).setUp()
  78. self.clustergroup1 = ClusterGroup.objects.create(name='Test Cluster Group 1', slug='test-cluster-group-1')
  79. self.clustergroup2 = ClusterGroup.objects.create(name='Test Cluster Group 2', slug='test-cluster-group-2')
  80. self.clustergroup3 = ClusterGroup.objects.create(name='Test Cluster Group 3', slug='test-cluster-group-3')
  81. def test_get_clustergroup(self):
  82. url = reverse('virtualization-api:clustergroup-detail', kwargs={'pk': self.clustergroup1.pk})
  83. response = self.client.get(url, **self.header)
  84. self.assertEqual(response.data['name'], self.clustergroup1.name)
  85. def test_list_clustergroups(self):
  86. url = reverse('virtualization-api:clustergroup-list')
  87. response = self.client.get(url, **self.header)
  88. self.assertEqual(response.data['count'], 3)
  89. def test_create_clustergroup(self):
  90. data = {
  91. 'name': 'Test Cluster Group 4',
  92. 'slug': 'test-cluster-group-4',
  93. }
  94. url = reverse('virtualization-api:clustergroup-list')
  95. response = self.client.post(url, data, format='json', **self.header)
  96. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  97. self.assertEqual(ClusterGroup.objects.count(), 4)
  98. clustergroup4 = ClusterGroup.objects.get(pk=response.data['id'])
  99. self.assertEqual(clustergroup4.name, data['name'])
  100. self.assertEqual(clustergroup4.slug, data['slug'])
  101. def test_create_clustergroup_bulk(self):
  102. data = [
  103. {
  104. 'name': 'Test Cluster Group 4',
  105. 'slug': 'test-cluster-group-4',
  106. },
  107. {
  108. 'name': 'Test Cluster Group 5',
  109. 'slug': 'test-cluster-group-5',
  110. },
  111. {
  112. 'name': 'Test Cluster Group 6',
  113. 'slug': 'test-cluster-group-6',
  114. },
  115. ]
  116. url = reverse('virtualization-api:clustergroup-list')
  117. response = self.client.post(url, data, format='json', **self.header)
  118. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  119. self.assertEqual(ClusterGroup.objects.count(), 6)
  120. self.assertEqual(response.data[0]['name'], data[0]['name'])
  121. self.assertEqual(response.data[1]['name'], data[1]['name'])
  122. self.assertEqual(response.data[2]['name'], data[2]['name'])
  123. def test_update_clustergroup(self):
  124. data = {
  125. 'name': 'Test Cluster Group X',
  126. 'slug': 'test-cluster-group-x',
  127. }
  128. url = reverse('virtualization-api:clustergroup-detail', kwargs={'pk': self.clustergroup1.pk})
  129. response = self.client.put(url, data, format='json', **self.header)
  130. self.assertHttpStatus(response, status.HTTP_200_OK)
  131. self.assertEqual(ClusterGroup.objects.count(), 3)
  132. clustergroup1 = ClusterGroup.objects.get(pk=response.data['id'])
  133. self.assertEqual(clustergroup1.name, data['name'])
  134. self.assertEqual(clustergroup1.slug, data['slug'])
  135. def test_delete_clustergroup(self):
  136. url = reverse('virtualization-api:clustergroup-detail', kwargs={'pk': self.clustergroup1.pk})
  137. response = self.client.delete(url, **self.header)
  138. self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
  139. self.assertEqual(ClusterGroup.objects.count(), 2)
  140. class ClusterTest(APITestCase):
  141. def setUp(self):
  142. super(ClusterTest, self).setUp()
  143. cluster_type = ClusterType.objects.create(name='Test Cluster Type 1', slug='test-cluster-type-1')
  144. cluster_group = ClusterGroup.objects.create(name='Test Cluster Group 1', slug='test-cluster-group-1')
  145. self.cluster1 = Cluster.objects.create(name='Test Cluster 1', type=cluster_type, group=cluster_group)
  146. self.cluster2 = Cluster.objects.create(name='Test Cluster 2', type=cluster_type, group=cluster_group)
  147. self.cluster3 = Cluster.objects.create(name='Test Cluster 3', type=cluster_type, group=cluster_group)
  148. def test_get_cluster(self):
  149. url = reverse('virtualization-api:cluster-detail', kwargs={'pk': self.cluster1.pk})
  150. response = self.client.get(url, **self.header)
  151. self.assertEqual(response.data['name'], self.cluster1.name)
  152. def test_list_clusters(self):
  153. url = reverse('virtualization-api:cluster-list')
  154. response = self.client.get(url, **self.header)
  155. self.assertEqual(response.data['count'], 3)
  156. def test_create_cluster(self):
  157. data = {
  158. 'name': 'Test Cluster 4',
  159. 'type': ClusterType.objects.first().pk,
  160. 'group': ClusterGroup.objects.first().pk,
  161. }
  162. url = reverse('virtualization-api:cluster-list')
  163. response = self.client.post(url, data, format='json', **self.header)
  164. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  165. self.assertEqual(Cluster.objects.count(), 4)
  166. cluster4 = Cluster.objects.get(pk=response.data['id'])
  167. self.assertEqual(cluster4.name, data['name'])
  168. self.assertEqual(cluster4.type.pk, data['type'])
  169. self.assertEqual(cluster4.group.pk, data['group'])
  170. def test_create_cluster_bulk(self):
  171. data = [
  172. {
  173. 'name': 'Test Cluster 4',
  174. 'type': ClusterType.objects.first().pk,
  175. 'group': ClusterGroup.objects.first().pk,
  176. },
  177. {
  178. 'name': 'Test Cluster 5',
  179. 'type': ClusterType.objects.first().pk,
  180. 'group': ClusterGroup.objects.first().pk,
  181. },
  182. {
  183. 'name': 'Test Cluster 6',
  184. 'type': ClusterType.objects.first().pk,
  185. 'group': ClusterGroup.objects.first().pk,
  186. },
  187. ]
  188. url = reverse('virtualization-api:cluster-list')
  189. response = self.client.post(url, data, format='json', **self.header)
  190. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  191. self.assertEqual(Cluster.objects.count(), 6)
  192. self.assertEqual(response.data[0]['name'], data[0]['name'])
  193. self.assertEqual(response.data[1]['name'], data[1]['name'])
  194. self.assertEqual(response.data[2]['name'], data[2]['name'])
  195. def test_update_cluster(self):
  196. cluster_type2 = ClusterType.objects.create(name='Test Cluster Type 2', slug='test-cluster-type-2')
  197. cluster_group2 = ClusterGroup.objects.create(name='Test Cluster Group 2', slug='test-cluster-group-2')
  198. data = {
  199. 'name': 'Test Cluster X',
  200. 'type': cluster_type2.pk,
  201. 'group': cluster_group2.pk,
  202. }
  203. url = reverse('virtualization-api:cluster-detail', kwargs={'pk': self.cluster1.pk})
  204. response = self.client.put(url, data, format='json', **self.header)
  205. self.assertHttpStatus(response, status.HTTP_200_OK)
  206. self.assertEqual(Cluster.objects.count(), 3)
  207. cluster1 = Cluster.objects.get(pk=response.data['id'])
  208. self.assertEqual(cluster1.name, data['name'])
  209. self.assertEqual(cluster1.type.pk, data['type'])
  210. self.assertEqual(cluster1.group.pk, data['group'])
  211. def test_delete_cluster(self):
  212. url = reverse('virtualization-api:cluster-detail', kwargs={'pk': self.cluster1.pk})
  213. response = self.client.delete(url, **self.header)
  214. self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
  215. self.assertEqual(Cluster.objects.count(), 2)
  216. class VirtualMachineTest(APITestCase):
  217. def setUp(self):
  218. super(VirtualMachineTest, self).setUp()
  219. cluster_type = ClusterType.objects.create(name='Test Cluster Type 1', slug='test-cluster-type-1')
  220. cluster_group = ClusterGroup.objects.create(name='Test Cluster Group 1', slug='test-cluster-group-1')
  221. self.cluster1 = Cluster.objects.create(name='Test Cluster 1', type=cluster_type, group=cluster_group)
  222. self.virtualmachine1 = VirtualMachine.objects.create(name='Test Virtual Machine 1', cluster=self.cluster1)
  223. self.virtualmachine2 = VirtualMachine.objects.create(name='Test Virtual Machine 2', cluster=self.cluster1)
  224. self.virtualmachine3 = VirtualMachine.objects.create(name='Test Virtual Machine 3', cluster=self.cluster1)
  225. def test_get_virtualmachine(self):
  226. url = reverse('virtualization-api:virtualmachine-detail', kwargs={'pk': self.virtualmachine1.pk})
  227. response = self.client.get(url, **self.header)
  228. self.assertEqual(response.data['name'], self.virtualmachine1.name)
  229. def test_list_virtualmachines(self):
  230. url = reverse('virtualization-api:virtualmachine-list')
  231. response = self.client.get(url, **self.header)
  232. self.assertEqual(response.data['count'], 3)
  233. def test_create_virtualmachine(self):
  234. data = {
  235. 'name': 'Test Virtual Machine 4',
  236. 'cluster': self.cluster1.pk,
  237. }
  238. url = reverse('virtualization-api:virtualmachine-list')
  239. response = self.client.post(url, data, format='json', **self.header)
  240. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  241. self.assertEqual(VirtualMachine.objects.count(), 4)
  242. virtualmachine4 = VirtualMachine.objects.get(pk=response.data['id'])
  243. self.assertEqual(virtualmachine4.name, data['name'])
  244. self.assertEqual(virtualmachine4.cluster.pk, data['cluster'])
  245. def test_create_virtualmachine_bulk(self):
  246. data = [
  247. {
  248. 'name': 'Test Virtual Machine 4',
  249. 'cluster': self.cluster1.pk,
  250. },
  251. {
  252. 'name': 'Test Virtual Machine 5',
  253. 'cluster': self.cluster1.pk,
  254. },
  255. {
  256. 'name': 'Test Virtual Machine 6',
  257. 'cluster': self.cluster1.pk,
  258. },
  259. ]
  260. url = reverse('virtualization-api:virtualmachine-list')
  261. response = self.client.post(url, data, format='json', **self.header)
  262. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  263. self.assertEqual(VirtualMachine.objects.count(), 6)
  264. self.assertEqual(response.data[0]['name'], data[0]['name'])
  265. self.assertEqual(response.data[1]['name'], data[1]['name'])
  266. self.assertEqual(response.data[2]['name'], data[2]['name'])
  267. def test_update_virtualmachine(self):
  268. interface = Interface.objects.create(name='Test Interface 1', virtual_machine=self.virtualmachine1)
  269. ip4_address = IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), interface=interface)
  270. ip6_address = IPAddress.objects.create(address=IPNetwork('2001:db8::1/64'), interface=interface)
  271. cluster2 = Cluster.objects.create(
  272. name='Test Cluster 2',
  273. type=ClusterType.objects.first(),
  274. group=ClusterGroup.objects.first()
  275. )
  276. data = {
  277. 'name': 'Test Virtual Machine X',
  278. 'cluster': cluster2.pk,
  279. 'primary_ip4': ip4_address.pk,
  280. 'primary_ip6': ip6_address.pk,
  281. }
  282. url = reverse('virtualization-api:virtualmachine-detail', kwargs={'pk': self.virtualmachine1.pk})
  283. response = self.client.put(url, data, format='json', **self.header)
  284. self.assertHttpStatus(response, status.HTTP_200_OK)
  285. self.assertEqual(VirtualMachine.objects.count(), 3)
  286. virtualmachine1 = VirtualMachine.objects.get(pk=response.data['id'])
  287. self.assertEqual(virtualmachine1.name, data['name'])
  288. self.assertEqual(virtualmachine1.cluster.pk, data['cluster'])
  289. self.assertEqual(virtualmachine1.primary_ip4.pk, data['primary_ip4'])
  290. self.assertEqual(virtualmachine1.primary_ip6.pk, data['primary_ip6'])
  291. def test_delete_virtualmachine(self):
  292. url = reverse('virtualization-api:virtualmachine-detail', kwargs={'pk': self.virtualmachine1.pk})
  293. response = self.client.delete(url, **self.header)
  294. self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
  295. self.assertEqual(VirtualMachine.objects.count(), 2)
  296. class InterfaceTest(APITestCase):
  297. def setUp(self):
  298. super(InterfaceTest, self).setUp()
  299. clustertype = ClusterType.objects.create(name='Test Cluster Type 1', slug='test-cluster-type-1')
  300. cluster = Cluster.objects.create(name='Test Cluster 1', type=clustertype)
  301. self.virtualmachine = VirtualMachine.objects.create(cluster=cluster, name='Test VM 1')
  302. self.interface1 = Interface.objects.create(
  303. virtual_machine=self.virtualmachine,
  304. name='Test Interface 1',
  305. form_factor=IFACE_FF_VIRTUAL
  306. )
  307. self.interface2 = Interface.objects.create(
  308. virtual_machine=self.virtualmachine,
  309. name='Test Interface 2',
  310. form_factor=IFACE_FF_VIRTUAL
  311. )
  312. self.interface3 = Interface.objects.create(
  313. virtual_machine=self.virtualmachine,
  314. name='Test Interface 3',
  315. form_factor=IFACE_FF_VIRTUAL
  316. )
  317. self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1)
  318. self.vlan2 = VLAN.objects.create(name="Test VLAN 2", vid=2)
  319. self.vlan3 = VLAN.objects.create(name="Test VLAN 3", vid=3)
  320. def test_get_interface(self):
  321. url = reverse('virtualization-api:interface-detail', kwargs={'pk': self.interface1.pk})
  322. response = self.client.get(url, **self.header)
  323. self.assertEqual(response.data['name'], self.interface1.name)
  324. def test_list_interfaces(self):
  325. url = reverse('virtualization-api:interface-list')
  326. response = self.client.get(url, **self.header)
  327. self.assertEqual(response.data['count'], 3)
  328. def test_create_interface(self):
  329. data = {
  330. 'virtual_machine': self.virtualmachine.pk,
  331. 'name': 'Test Interface 4',
  332. }
  333. url = reverse('virtualization-api:interface-list')
  334. response = self.client.post(url, data, format='json', **self.header)
  335. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  336. self.assertEqual(Interface.objects.count(), 4)
  337. interface4 = Interface.objects.get(pk=response.data['id'])
  338. self.assertEqual(interface4.virtual_machine_id, data['virtual_machine'])
  339. self.assertEqual(interface4.name, data['name'])
  340. def test_create_interface_with_802_1q(self):
  341. data = {
  342. 'virtual_machine': self.virtualmachine.pk,
  343. 'name': 'Test Interface 4',
  344. 'mode': IFACE_MODE_TAGGED,
  345. 'untagged_vlan': self.vlan3.id,
  346. 'tagged_vlans': [self.vlan1.id, self.vlan2.id],
  347. }
  348. url = reverse('virtualization-api:interface-list')
  349. response = self.client.post(url, data, format='json', **self.header)
  350. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  351. self.assertEqual(Interface.objects.count(), 4)
  352. self.assertEqual(response.data['virtual_machine']['id'], data['virtual_machine'])
  353. self.assertEqual(response.data['name'], data['name'])
  354. self.assertEqual(response.data['untagged_vlan']['id'], data['untagged_vlan'])
  355. self.assertEqual([v['id'] for v in response.data['tagged_vlans']], data['tagged_vlans'])
  356. def test_create_interface_bulk(self):
  357. data = [
  358. {
  359. 'virtual_machine': self.virtualmachine.pk,
  360. 'name': 'Test Interface 4',
  361. },
  362. {
  363. 'virtual_machine': self.virtualmachine.pk,
  364. 'name': 'Test Interface 5',
  365. },
  366. {
  367. 'virtual_machine': self.virtualmachine.pk,
  368. 'name': 'Test Interface 6',
  369. },
  370. ]
  371. url = reverse('virtualization-api:interface-list')
  372. response = self.client.post(url, data, format='json', **self.header)
  373. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  374. self.assertEqual(Interface.objects.count(), 6)
  375. self.assertEqual(response.data[0]['name'], data[0]['name'])
  376. self.assertEqual(response.data[1]['name'], data[1]['name'])
  377. self.assertEqual(response.data[2]['name'], data[2]['name'])
  378. def test_create_interface_802_1q_bulk(self):
  379. data = [
  380. {
  381. 'virtual_machine': self.virtualmachine.pk,
  382. 'name': 'Test Interface 4',
  383. 'mode': IFACE_MODE_TAGGED,
  384. 'untagged_vlan': self.vlan2.id,
  385. 'tagged_vlans': [self.vlan1.id],
  386. },
  387. {
  388. 'virtual_machine': self.virtualmachine.pk,
  389. 'name': 'Test Interface 5',
  390. 'mode': IFACE_MODE_TAGGED,
  391. 'untagged_vlan': self.vlan2.id,
  392. 'tagged_vlans': [self.vlan1.id],
  393. },
  394. {
  395. 'virtual_machine': self.virtualmachine.pk,
  396. 'name': 'Test Interface 6',
  397. 'mode': IFACE_MODE_TAGGED,
  398. 'untagged_vlan': self.vlan2.id,
  399. 'tagged_vlans': [self.vlan1.id],
  400. },
  401. ]
  402. url = reverse('virtualization-api:interface-list')
  403. response = self.client.post(url, data, format='json', **self.header)
  404. self.assertHttpStatus(response, status.HTTP_201_CREATED)
  405. self.assertEqual(Interface.objects.count(), 6)
  406. for i in range(0, 3):
  407. self.assertEqual(response.data[i]['name'], data[i]['name'])
  408. self.assertEqual([v['id'] for v in response.data[i]['tagged_vlans']], data[i]['tagged_vlans'])
  409. self.assertEqual(response.data[i]['untagged_vlan']['id'], data[i]['untagged_vlan'])
  410. def test_update_interface(self):
  411. data = {
  412. 'virtual_machine': self.virtualmachine.pk,
  413. 'name': 'Test Interface X',
  414. }
  415. url = reverse('virtualization-api:interface-detail', kwargs={'pk': self.interface1.pk})
  416. response = self.client.put(url, data, format='json', **self.header)
  417. self.assertHttpStatus(response, status.HTTP_200_OK)
  418. self.assertEqual(Interface.objects.count(), 3)
  419. interface1 = Interface.objects.get(pk=response.data['id'])
  420. self.assertEqual(interface1.name, data['name'])
  421. def test_delete_interface(self):
  422. url = reverse('dcim-api:interface-detail', kwargs={'pk': self.interface1.pk})
  423. response = self.client.delete(url, **self.header)
  424. self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
  425. self.assertEqual(Interface.objects.count(), 2)