test_api.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. from django.contrib.contenttypes.models import ContentType
  2. from django.test import override_settings
  3. from django.urls import reverse
  4. from rest_framework import status
  5. from dcim.choices import InterfaceModeChoices
  6. from extras.models import Graph
  7. from ipam.models import VLAN
  8. from utilities.testing import APITestCase, APIViewTestCases
  9. from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
  10. class AppTest(APITestCase):
  11. def test_root(self):
  12. url = reverse('virtualization-api:api-root')
  13. response = self.client.get('{}?format=api'.format(url), **self.header)
  14. self.assertEqual(response.status_code, 200)
  15. class ClusterTypeTest(APIViewTestCases.APIViewTestCase):
  16. model = ClusterType
  17. brief_fields = ['cluster_count', 'id', 'name', 'slug', 'url']
  18. create_data = [
  19. {
  20. 'name': 'Cluster Type 4',
  21. 'slug': 'cluster-type-4',
  22. },
  23. {
  24. 'name': 'Cluster Type 5',
  25. 'slug': 'cluster-type-5',
  26. },
  27. {
  28. 'name': 'Cluster Type 6',
  29. 'slug': 'cluster-type-6',
  30. },
  31. ]
  32. @classmethod
  33. def setUpTestData(cls):
  34. cluster_types = (
  35. ClusterType(name='Cluster Type 1', slug='cluster-type-1'),
  36. ClusterType(name='Cluster Type 2', slug='cluster-type-2'),
  37. ClusterType(name='Cluster Type 3', slug='cluster-type-3'),
  38. )
  39. ClusterType.objects.bulk_create(cluster_types)
  40. class ClusterGroupTest(APIViewTestCases.APIViewTestCase):
  41. model = ClusterGroup
  42. brief_fields = ['cluster_count', 'id', 'name', 'slug', 'url']
  43. create_data = [
  44. {
  45. 'name': 'Cluster Group 4',
  46. 'slug': 'cluster-type-4',
  47. },
  48. {
  49. 'name': 'Cluster Group 5',
  50. 'slug': 'cluster-type-5',
  51. },
  52. {
  53. 'name': 'Cluster Group 6',
  54. 'slug': 'cluster-type-6',
  55. },
  56. ]
  57. @classmethod
  58. def setUpTestData(cls):
  59. cluster_Groups = (
  60. ClusterGroup(name='Cluster Group 1', slug='cluster-type-1'),
  61. ClusterGroup(name='Cluster Group 2', slug='cluster-type-2'),
  62. ClusterGroup(name='Cluster Group 3', slug='cluster-type-3'),
  63. )
  64. ClusterGroup.objects.bulk_create(cluster_Groups)
  65. class ClusterTest(APIViewTestCases.APIViewTestCase):
  66. model = Cluster
  67. brief_fields = ['id', 'name', 'url', 'virtualmachine_count']
  68. @classmethod
  69. def setUpTestData(cls):
  70. cluster_types = (
  71. ClusterType(name='Cluster Type 1', slug='cluster-type-1'),
  72. ClusterType(name='Cluster Type 2', slug='cluster-type-2'),
  73. )
  74. ClusterType.objects.bulk_create(cluster_types)
  75. cluster_groups = (
  76. ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
  77. ClusterGroup(name='Cluster Group 2', slug='cluster-group-2'),
  78. )
  79. ClusterGroup.objects.bulk_create(cluster_groups)
  80. clusters = (
  81. Cluster(name='Cluster 1', type=cluster_types[0], group=cluster_groups[0]),
  82. Cluster(name='Cluster 2', type=cluster_types[0], group=cluster_groups[0]),
  83. Cluster(name='Cluster 3', type=cluster_types[0], group=cluster_groups[0]),
  84. )
  85. Cluster.objects.bulk_create(clusters)
  86. cls.create_data = [
  87. {
  88. 'name': 'Cluster 4',
  89. 'type': cluster_types[1].pk,
  90. 'group': cluster_groups[1].pk,
  91. },
  92. {
  93. 'name': 'Cluster 5',
  94. 'type': cluster_types[1].pk,
  95. 'group': cluster_groups[1].pk,
  96. },
  97. {
  98. 'name': 'Cluster 6',
  99. 'type': cluster_types[1].pk,
  100. 'group': cluster_groups[1].pk,
  101. },
  102. ]
  103. class VirtualMachineTest(APIViewTestCases.APIViewTestCase):
  104. model = VirtualMachine
  105. brief_fields = ['id', 'name', 'url']
  106. @classmethod
  107. def setUpTestData(cls):
  108. clustertype = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
  109. clustergroup = ClusterGroup.objects.create(name='Cluster Group 1', slug='cluster-group-1')
  110. clusters = (
  111. Cluster(name='Cluster 1', type=clustertype, group=clustergroup),
  112. Cluster(name='Cluster 2', type=clustertype, group=clustergroup),
  113. )
  114. Cluster.objects.bulk_create(clusters)
  115. virtual_machines = (
  116. VirtualMachine(name='Virtual Machine 1', cluster=clusters[0], local_context_data={'A': 1}),
  117. VirtualMachine(name='Virtual Machine 2', cluster=clusters[0], local_context_data={'B': 2}),
  118. VirtualMachine(name='Virtual Machine 3', cluster=clusters[0], local_context_data={'C': 3}),
  119. )
  120. VirtualMachine.objects.bulk_create(virtual_machines)
  121. cls.create_data = [
  122. {
  123. 'name': 'Virtual Machine 4',
  124. 'cluster': clusters[1].pk,
  125. },
  126. {
  127. 'name': 'Virtual Machine 5',
  128. 'cluster': clusters[1].pk,
  129. },
  130. {
  131. 'name': 'Virtual Machine 6',
  132. 'cluster': clusters[1].pk,
  133. },
  134. ]
  135. def test_config_context_included_by_default_in_list_view(self):
  136. """
  137. Check that config context data is included by default in the virtual machines list.
  138. """
  139. virtualmachine = VirtualMachine.objects.first()
  140. url = '{}?id={}'.format(reverse('virtualization-api:virtualmachine-list'), virtualmachine.pk)
  141. self.add_permissions('virtualization.view_virtualmachine')
  142. response = self.client.get(url, **self.header)
  143. self.assertEqual(response.data['results'][0].get('config_context', {}).get('A'), 1)
  144. def test_config_context_excluded(self):
  145. """
  146. Check that config context data can be excluded by passing ?exclude=config_context.
  147. """
  148. url = reverse('virtualization-api:virtualmachine-list') + '?exclude=config_context'
  149. self.add_permissions('virtualization.view_virtualmachine')
  150. response = self.client.get(url, **self.header)
  151. self.assertFalse('config_context' in response.data['results'][0])
  152. def test_unique_name_per_cluster_constraint(self):
  153. """
  154. Check that creating a virtual machine with a duplicate name fails.
  155. """
  156. data = {
  157. 'name': 'Virtual Machine 1',
  158. 'cluster': Cluster.objects.first().pk,
  159. }
  160. url = reverse('virtualization-api:virtualmachine-list')
  161. self.add_permissions('virtualization.add_virtualmachine')
  162. response = self.client.post(url, data, format='json', **self.header)
  163. self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
  164. class VMInterfaceTest(APIViewTestCases.APIViewTestCase):
  165. model = VMInterface
  166. brief_fields = ['id', 'name', 'url', 'virtual_machine']
  167. @classmethod
  168. def setUpTestData(cls):
  169. clustertype = ClusterType.objects.create(name='Test Cluster Type 1', slug='test-cluster-type-1')
  170. cluster = Cluster.objects.create(name='Test Cluster 1', type=clustertype)
  171. virtualmachine = VirtualMachine.objects.create(cluster=cluster, name='Test VM 1')
  172. interfaces = (
  173. VMInterface(virtual_machine=virtualmachine, name='Interface 1'),
  174. VMInterface(virtual_machine=virtualmachine, name='Interface 2'),
  175. VMInterface(virtual_machine=virtualmachine, name='Interface 3'),
  176. )
  177. VMInterface.objects.bulk_create(interfaces)
  178. vlans = (
  179. VLAN(name='VLAN 1', vid=1),
  180. VLAN(name='VLAN 2', vid=2),
  181. VLAN(name='VLAN 3', vid=3),
  182. )
  183. VLAN.objects.bulk_create(vlans)
  184. cls.create_data = [
  185. {
  186. 'virtual_machine': virtualmachine.pk,
  187. 'name': 'Interface 4',
  188. 'mode': InterfaceModeChoices.MODE_TAGGED,
  189. 'tagged_vlans': [vlans[0].pk, vlans[1].pk],
  190. 'untagged_vlan': vlans[2].pk,
  191. },
  192. {
  193. 'virtual_machine': virtualmachine.pk,
  194. 'name': 'Interface 5',
  195. 'mode': InterfaceModeChoices.MODE_TAGGED,
  196. 'tagged_vlans': [vlans[0].pk, vlans[1].pk],
  197. 'untagged_vlan': vlans[2].pk,
  198. },
  199. {
  200. 'virtual_machine': virtualmachine.pk,
  201. 'name': 'Interface 6',
  202. 'mode': InterfaceModeChoices.MODE_TAGGED,
  203. 'tagged_vlans': [vlans[0].pk, vlans[1].pk],
  204. 'untagged_vlan': vlans[2].pk,
  205. },
  206. ]
  207. @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
  208. def test_get_vminterface_graphs(self):
  209. """
  210. Test retrieval of Graphs assigned to VM interfaces.
  211. """
  212. ct = ContentType.objects.get_for_model(VMInterface)
  213. graphs = (
  214. Graph(type=ct, name='Graph 1', source='http://example.com/graphs.py?interface={{ obj.name }}&foo=1'),
  215. Graph(type=ct, name='Graph 2', source='http://example.com/graphs.py?interface={{ obj.name }}&foo=2'),
  216. Graph(type=ct, name='Graph 3', source='http://example.com/graphs.py?interface={{ obj.name }}&foo=3'),
  217. )
  218. Graph.objects.bulk_create(graphs)
  219. self.add_permissions('virtualization.view_vminterface')
  220. url = reverse('virtualization-api:vminterface-graphs', kwargs={
  221. 'pk': VMInterface.objects.first().pk
  222. })
  223. response = self.client.get(url, **self.header)
  224. self.assertEqual(len(response.data), 3)
  225. self.assertEqual(response.data[0]['embed_url'], 'http://example.com/graphs.py?interface=Interface 1&foo=1')