def main(): parser = ArgumentParser(description=_PROG_HELP) parser.add_argument('--namespace') parser.add_argument('--manifest') parser.add_argument('--timeout', type=int, default=300) args = parser.parse_args() Command(''' kubectl apply --namespace="{}" --filename="{}" '''.format(args.namespace, args.manifest), print_call=True) resources = load_resources_yaml(args.manifest) for resource_def in resources: full_name = "{}/{}".format(resource_def['kind'], deep_get(resource_def, 'metadata', 'name')) if resource_def['kind'] != 'Pod': log("INFO Skip '{}'".format(full_name)) continue start_time = time.time() poll_interval = 4 tester_timeout = args.timeout while True: try: resource = Command(''' kubectl get "{}" --namespace="{}" -o=json '''.format(full_name, args.namespace), print_call=True).json() except CommandException as ex: log(str(ex)) log("INFO retrying") time.sleep(poll_interval) continue result = deep_get(resource, 'status', 'phase') if result == "Failed": print_logs(full_name, args.namespace) raise Exception("ERROR Tester '{}' failed".format(full_name)) if result == "Succeeded": print_logs(full_name, args.namespace) log("INFO Tester '{}' succeeded".format(full_name)) break if time.time() - start_time > tester_timeout: print_logs(full_name, args.namespace) raise Exception("ERROR Tester '{}' timeout".format(full_name)) time.sleep(poll_interval)
def test_command_success_json(self): cmd = Command( 'echo \'{"string": "mystring", "int": 1, "float": 1.5}\'') self.assertEqual(cmd.output, '{"string": "mystring", "int": 1, "float": 1.5}\n') self.assertEqual(cmd.exitcode, 0) self.assertEqual(cmd.json(), { "string": "mystring", "int": 1, "float": 1.5 })
def print_tester_logs(full_name, namespace): try: Command('kubectl logs {} --namespace="{}"'.format( full_name, namespace), print_call=True, print_result=True) except CommandException as ex: log.error(str(ex)) log.error("{} failed to get the tester logs.", LOG_SMOKE_TEST)
def _gcs_load(path): """Returns a gcs object's contents as a string.""" return Command("gsutil cat {}".format(path)).output
def main(): parser = ArgumentParser(description=_PROG_HELP) parser.add_argument('--name') parser.add_argument('--namespace') parser.add_argument('--timeout', type=float) args = parser.parse_args() log.info( "Wait {} seconds for the application '{}' to get into ready state", args.timeout, args.name) previous_healthy = False min_time_before_healthy = 30 poll_interval = 4 application = Command(''' kubectl get "applications.app.k8s.io/{}" --namespace="{}" --output=json '''.format(args.name, args.namespace), print_call=True).json() top_level_kinds = [ kind['kind'] for kind in application['spec']['componentKinds'] ] poll_start_time = time.time() while True: top_level_resources = [] for kind in top_level_kinds: resources = Command(''' kubectl get "{}" --namespace="{}" --selector app.kubernetes.io/name="{}" --output=json '''.format(kind, args.namespace, args.name)).json() top_level_resources.extend(resources['items']) if len(top_level_resources) == 0: raise Exception("ERROR no top level resources found") log.info("Top level resources: {}", len(top_level_resources)) healthy = True for resource in top_level_resources: healthy = is_healthy(resource) if not healthy: break if previous_healthy != healthy: log.info( "Initialization: Found applications.app.k8s.io/{} ready status to be {}.", args.name, healthy) previous_healthy = healthy if healthy: log.info( "Wait {} seconds to make sure app stays in healthy state.", min_time_before_healthy) healthy_start_time = time.time() if healthy: elapsed_healthy_time = time.time() - healthy_start_time if elapsed_healthy_time > min_time_before_healthy: break if time.time() - poll_start_time > args.timeout: raise Exception( "ERROR Application did not get ready before timeout of {} seconds" .format(args.timeout)) time.sleep(poll_interval)
def test_command_success(self): cmd = Command('echo Hello') self.assertEqual(cmd.output, 'Hello\n') self.assertEqual(cmd.exitcode, 0)
def test_command_failure(self): with self.assertRaises(CommandException) as context: Command('cat nonexistentfile') self.assertEqual(context.exception.exitcode, 1) self.assertEqual(str(context.exception), 'cat: nonexistentfile: No such file or directory\n')
def test_command_nonzero_exitcode(self): with self.assertRaises(CommandException) as context: Command('bash -c "exit 1"') self.assertEqual(context.exception.exitcode, 1)
def main(): parser = ArgumentParser(description=_PROG_HELP) parser.add_argument('--namespace') parser.add_argument('--manifest') parser.add_argument('--timeout', type=int, default=300) args = parser.parse_args() try: Command(''' kubectl apply --namespace="{}" --filename="{}" '''.format(args.namespace, args.manifest), print_call=True) except CommandException as ex: log.error("{} Failed to apply tester job. Reason: {}", LOG_SMOKE_TEST, ex.message) return resources = load_resources_yaml(args.manifest) for resource_def in resources: full_name = "{}/{}".format(resource_def['kind'], deep_get(resource_def, 'metadata', 'name')) if resource_def['kind'] != 'Pod': log.info("Skip '{}'", full_name) continue start_time = time.time() poll_interval = 4 tester_timeout = args.timeout while True: try: resource = Command(''' kubectl get "{}" --namespace="{}" -o=json '''.format(full_name, args.namespace), print_call=True).json() except CommandException as ex: log.info(str(ex)) log.info("retrying") time.sleep(poll_interval) continue result = deep_get(resource, 'status', 'phase') if result == "Failed": print_tester_logs(full_name, args.namespace) log.error("{} Tester '{}' failed.", LOG_SMOKE_TEST, full_name) break if result == "Succeeded": print_tester_logs(full_name, args.namespace) log.info("{} Tester '{}' succeeded.", LOG_SMOKE_TEST, full_name) break if time.time() - start_time > tester_timeout: print_tester_logs(full_name, args.namespace) log.error("{} Tester '{}' timeout.", LOG_SMOKE_TEST, full_name) time.sleep(poll_interval)
def print_logs(full_name, namespace): log(Command('''kubectl logs {} --namespace="{}"'''.format(full_name, namespace)).output)