1 # Copyright (c) 2019 Sawyer Bergeron, Parker Berberian, and others.
3 # All rights reserved. This program and the accompanying materials
4 # are made available under the terms of the Apache License, Version 2.0
5 # which accompanies this distribution, and is available at
6 # http://www.apache.org/licenses/LICENSE-2.0
7 ##############################################################################
9 from api.models import (
20 from resource_inventory.models import (
26 from django.test import TestCase, Client
28 from dashboard.testing_utils import (
37 make_complete_host_profile,
42 class ValidBookingCreatesValidJob(TestCase):
44 def setUpTestData(cls):
45 cls.user = make_user(False, username="newtestuser", password="testpassword")
46 cls.userprofile = make_user_profile(cls.user)
49 cls.host_profile = make_complete_host_profile(cls.lab)
50 cls.scenario = make_scenario()
51 cls.installer = make_installer([cls.scenario])
52 os = make_os([cls.installer])
53 cls.image = make_image(cls.lab, 1, cls.user, os, cls.host_profile)
55 make_host(cls.host_profile, cls.lab, name="host" + str(i), labid="host" + str(i))
59 self.booking, self.compute_hostnames, self.jump_hostname = self.create_multinode_generic_booking()
61 def create_multinode_generic_booking(self):
64 compute_hostnames = ["cmp01", "cmp02", "cmp03"]
66 host_type = HostProfile.objects.first()
68 universal_networks = [
69 {"name": "public", "tagged": False, "public": True},
70 {"name": "admin", "tagged": True, "public": False}]
71 compute_networks = [{"name": "private", "tagged": True, "public": False}]
72 jumphost_networks = [{"name": "external", "tagged": True, "public": True}]
74 # generate a bunch of extra networks
76 net = {"tagged": False, "public": False}
77 net["name"] = "net" + str(i)
78 universal_networks.append(net)
82 "role": OPNFVRole.objects.get_or_create(name="Jumphost")[0],
83 "nets": self.make_networks(host_type, jumphost_networks + universal_networks),
86 topology["jump"] = jumphost_info
88 for hostname in compute_hostnames:
91 "role": OPNFVRole.objects.get_or_create(name="Compute")[0],
92 "nets": self.make_networks(host_type, compute_networks + universal_networks),
95 topology[hostname] = host_info
97 booking = make_booking(
101 installer=self.installer,
102 scenario=self.scenario
105 if not booking.resource:
106 raise Exception("Booking does not have a resource when trying to pass to makeCompleteJob")
107 return booking, compute_hostnames, "jump"
109 def make_networks(self, hostprofile, nets):
111 Distribute nets accross hostprofile's interfaces.
116 count = hostprofile.interfaceprofile.all().count()
117 for i in range(count):
118 network_struct.append([])
120 index = len(nets) % count
121 network_struct[index].append(nets.pop())
123 return network_struct
125 #################################################################
127 #################################################################
129 def test_complete_job_makes_access_configs(self):
130 JobFactory.makeCompleteJob(self.booking)
131 job = Job.objects.get(booking=self.booking)
132 self.assertIsNotNone(job)
134 access_configs = AccessConfig.objects.filter(accessrelation__job=job)
136 vpn_configs = access_configs.filter(access_type="vpn")
137 ssh_configs = access_configs.filter(access_type="ssh")
139 self.assertFalse(AccessConfig.objects.exclude(access_type__in=["vpn", "ssh"]).exists())
141 all_users = list(self.booking.collaborators.all())
142 all_users.append(self.booking.owner)
144 for user in all_users:
145 self.assertTrue(vpn_configs.filter(user=user).exists())
146 self.assertTrue(ssh_configs.filter(user=user).exists())
148 def test_complete_job_makes_network_configs(self):
149 JobFactory.makeCompleteJob(self.booking)
150 job = Job.objects.get(booking=self.booking)
151 self.assertIsNotNone(job)
153 booking_hosts = self.booking.resource.hosts.all()
155 netrelations = HostNetworkRelation.objects.filter(job=job)
156 netconfigs = [r.config for r in netrelations]
158 netrelation_hosts = [r.host for r in netrelations]
160 for config in netconfigs:
161 for interface in config.interfaces.all():
162 self.assertTrue(interface.host in booking_hosts)
164 # if no interfaces are referenced that shouldn't have vlans,
165 # and no vlans exist outside those accounted for in netconfigs,
166 # then the api is faithfully representing networks
167 # as netconfigs reference resource_inventory models directly
169 # this test relies on the assumption that
170 # every interface is configured, whether it does or does not have vlans
171 # if this is not true, the test fails
173 for host in booking_hosts:
174 self.assertTrue(host in netrelation_hosts)
175 relation = HostNetworkRelation.objects.filter(job=job).get(host=host)
177 # do 2 direction matching that interfaces are one to one
178 config = relation.config
179 for interface in config.interfaces.all():
180 self.assertTrue(interface in host.interfaces)
181 for interface in host.interfaces.all():
182 self.assertTrue(interface in config.interfaces)
184 for host in netrelation_hosts:
185 self.assertTrue(host in booking_hosts)
187 def test_complete_job_makes_hardware_configs(self):
188 JobFactory.makeCompleteJob(self.booking)
189 job = Job.objects.get(booking=self.booking)
190 self.assertIsNotNone(job)
192 hardware_relations = HostHardwareRelation.objects.filter(job=job)
194 job_hosts = [r.host for r in hardware_relations]
196 booking_hosts = self.booking.resource.hosts.all()
198 self.assertEqual(len(booking_hosts), len(job_hosts))
200 for relation in hardware_relations:
201 self.assertTrue(relation.host in booking_hosts)
202 self.assertEqual(relation.status, JobStatus.NEW)
203 config = relation.config
205 self.assertEqual(config.get_delta()["hostname"], host.template.resource.name)
207 def test_complete_job_makes_software_configs(self):
208 JobFactory.makeCompleteJob(self.booking)
209 job = Job.objects.get(booking=self.booking)
210 self.assertIsNotNone(job)
212 srelation = SoftwareRelation.objects.filter(job=job).first()
213 self.assertIsNotNone(srelation)
215 sconfig = srelation.config
216 self.assertIsNotNone(sconfig)
218 oconfig = sconfig.opnfv
219 self.assertIsNotNone(oconfig)
221 # not onetoone in models, but first() is safe here based on how ConfigBundle and a matching OPNFVConfig are created
222 # this should, however, be made explicit
223 self.assertEqual(oconfig.installer, self.booking.config_bundle.opnfv_config.first().installer.name)
224 self.assertEqual(oconfig.scenario, self.booking.config_bundle.opnfv_config.first().scenario.name)
226 for host in oconfig.roles.all():
227 role_name = host.config.host_opnfv_config.first().role.name
228 if str(role_name).lower() == "jumphost":
229 self.assertEqual(host.template.resource.name, self.jump_hostname)
230 elif str(role_name).lower() == "compute":
231 self.assertTrue(host.template.resource.name in self.compute_hostnames)
233 self.fail(msg="Host with non-configured role name related to job: " + str(role_name))
235 def test_make_snapshot_task(self):
236 host = self.booking.resource.hosts.first()
237 image = make_image(self.lab, -1, None, None, host.profile)
239 Job.objects.create(booking=self.booking)
241 JobFactory.makeSnapshotTask(image, self.booking, host)
243 snap_relation = SnapshotRelation.objects.get(job=self.booking.job)
244 config = snap_relation.config
245 self.assertEqual(host.id, config.host.id)
246 self.assertEqual(config.dashboard_id, image.id)
247 self.assertEqual(snap_relation.snapshot.id, image.id)
249 def test_make_hardware_configs(self):
250 hosts = self.booking.resource.hosts.all()
251 job = Job.objects.create(booking=self.booking)
252 JobFactory.makeHardwareConfigs(hosts=hosts, job=job)
254 hardware_relations = HostHardwareRelation.objects.filter(job=job)
256 self.assertEqual(hardware_relations.count(), hosts.count())
258 host_set = set([h.id for h in hosts])
260 for relation in hardware_relations:
262 host_set.remove(relation.host.id)
264 self.fail("Hardware Relation/Config not created for host " + str(relation.host))
265 # TODO: ConfigState needs to be fixed in factory methods
266 relation.config.state = ConfigState.NEW
267 self.assertEqual(relation.config.get_delta()["power"], "on")
268 self.assertTrue(relation.config.get_delta()["ipmi_create"])
269 # TODO: the rest of hwconf attrs
271 self.assertEqual(len(host_set), 0)