X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=tests%2Fbase.py;h=a0a2b789d2b247e08221a962dc8bf17ef4fe81c6;hp=0959059c8731e2b06ffd308f4824cfe193b25a24;hb=b2c234b2056b9d8cb9f6eda268c2cf1845f88371;hpb=ea14f890f054d5eb85416a5b6c8c7713e2506ad8 diff --git a/tests/base.py b/tests/base.py index 0959059..a0a2b78 100644 --- a/tests/base.py +++ b/tests/base.py @@ -25,8 +25,7 @@ here = os.path.dirname(os.path.realpath(__file__)) def is_bootstrapped(): result = subprocess.run(['juju', 'switch'], stdout=subprocess.PIPE) return ( - result.returncode == 0 and - len(result.stdout.decode().strip()) > 0) + result.returncode == 0 and len(result.stdout.decode().strip()) > 0) bootstrapped = pytest.mark.skipif( @@ -65,9 +64,9 @@ def debug(msg): logging.debug( "[{}] {}".format(now.strftime('%Y-%m-%dT%H:%M:%S'), msg) ) - # print( - # "[{}] {}".format(now.strftime('%Y-%m-%dT%H:%M:%S'), msg) - # ) + print( + "[{}] {}".format(now.strftime('%Y-%m-%dT%H:%M:%S'), msg) + ) def get_charm_path(): @@ -231,6 +230,25 @@ def create_lxd_container(public_key=None, name="test_name"): ) ) + try: + waitcount = 0 + while waitcount <= 5: + if is_sshd_running(container): + break + waitcount += 1 + time.sleep(1) + if waitcount >= 5: + debug("couldn't detect sshd running") + raise Exception("Unable to verify container sshd") + + except Exception as ex: + debug( + "Error checking sshd status on {}: {}".format( + test_machine, + ex, + ) + ) + # HACK: We need to give sshd a chance to bind to the interface, # and pylxd's container.execute seems to be broken and fails and/or # hangs trying to properly check if the service is up. @@ -247,6 +265,28 @@ def create_lxd_container(public_key=None, name="test_name"): return container +def is_sshd_running(container): + """Check if sshd is running in the container. + + Check to see if the sshd process is running and listening on port 22. + + :param container: The container to check + :return boolean: True if sshd is running. + """ + debug("Container: {}".format(container)) + try: + (rc, stdout, stderr) = container.execute( + ["service", "ssh", "status"] + ) + # If the status is a) found and b) running, the exit code will be 0 + if rc == 0: + return True + except Exception as ex: + debug("Failed to check sshd service status: {}".format(ex)) + + return False + + def destroy_lxd_container(container): """Stop and delete a LXD container. @@ -432,9 +472,6 @@ class TestN2VC(object): self.ns_name = self.nsd['name'] self.vnf_name = self.vnfd['name'] - # Hard-coded to default for now, but this may change in the future. - self.model = "default" - self.charms = {} self.parse_vnf_descriptor() assert self.charms is not {} @@ -553,7 +590,7 @@ class TestN2VC(object): # Make sure the charm snap is installed try: subprocess.check_call(['which', 'charm']) - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: raise Exception("charm snap not installed.") if charm not in self.artifacts: @@ -565,19 +602,24 @@ class TestN2VC(object): builds = get_charm_path() if not os.path.exists("{}/builds/{}".format(builds, charm)): - cmd = "charm build {}/{} -o {}/".format( + cmd = "charm build --no-local-layers {}/{} -o {}/".format( get_layer_path(), charm, builds, ) subprocess.check_call(shlex.split(cmd)) - self.artifacts[charm] = { - 'tmpdir': builds, - 'charm': "{}/builds/{}".format(builds, charm), - } except subprocess.CalledProcessError as e: - raise Exception("charm build failed: {}.".format(e)) + # charm build will return error code 100 if the charm fails + # the auto-run of charm proof, which we can safely ignore for + # our CI charms. + if e.returncode != 100: + raise Exception("charm build failed: {}.".format(e)) + + self.artifacts[charm] = { + 'tmpdir': builds, + 'charm': "{}/builds/{}".format(builds, charm), + } return self.artifacts[charm]['charm'] @@ -590,6 +632,9 @@ class TestN2VC(object): if not self.n2vc: self.n2vc = get_n2vc(loop=loop) + debug("Creating model for Network Service {}".format(self.ns_name)) + await self.n2vc.CreateNetworkService(self.ns_name) + application = self.n2vc.FormatApplicationName( self.ns_name, self.vnf_name, @@ -889,15 +934,26 @@ class TestN2VC(object): self._running = False self._stopping = True + # Destroy the network service + try: + await self.n2vc.DestroyNetworkService(self.ns_name) + except Exception as e: + debug( + "Error Destroying Network Service \"{}\": {}".format( + self.ns_name, + e, + ) + ) + + # Wait for the applications to be removed and delete the containers for application in self.charms: try: - await self.n2vc.RemoveCharms(self.model, application) while True: # Wait for the application to be removed await asyncio.sleep(10) if not await self.n2vc.HasApplication( - self.model, + self.ns_name, application, ): break @@ -962,7 +1018,7 @@ class TestN2VC(object): ) await self.n2vc.ExecutePrimitive( - self.model, + self.ns_name, application, "config", None, @@ -987,7 +1043,7 @@ class TestN2VC(object): Re-run those actions so we can inspect the status. """ uuids = await self.n2vc.ExecuteInitialPrimitives( - self.model, + self.ns_name, application, init_config, ) @@ -1019,7 +1075,7 @@ class TestN2VC(object): debug("Collecting metrics for {}".format(application)) metrics = await self.n2vc.GetMetrics( - self.model, + self.ns_name, application, ) @@ -1069,7 +1125,7 @@ class TestN2VC(object): debug("Getting status of {} ({})...".format(uid, status)) status = await self.n2vc.GetPrimitiveStatus( - self.model, + self.ns_name, uid, ) debug("...state of {} is {}".format(uid, status)) @@ -1112,6 +1168,14 @@ class TestN2VC(object): debug("{} is done".format(application)) return + if status in ['error']: + # To test broken charms, if a charm enters an error state we should + # end the test + debug("{} is in an error state, stop the test.".format(application)) + # asyncio.ensure_future(self.stop()) + self.state[application]['done'] = True + assert False + if status in ["blocked"] and self.isproxy(application): if self.state[application]['phase'] == "deploy": debug("Configuring proxy charm for {}".format(application))