def test_build_errors(popen_mock, progress_bar_mock, prevent_deadlock_mock, open_mock, init_mock): popen_mock.return_value.poll.return_value = 1 # set to 1 for error output_str = "normal output..." error_str = "error message..." build_output = MagicMock() build_output.decode.return_value = output_str error_output = MagicMock() error_output.decode.return_value = error_str popen_mock.return_value.communicate.return_value = (build_output, error_output) build = BuildCommand({'build': True, '--watch': False, '--verbose': False}) build.config = MagicMock() with catch_stdout() as caught_output: with pytest.raises(SystemExit): build.action() output = caught_output.getvalue() # assert that we got the normal output and then the error output output_location = output.find(output_str) error_location = output.find(error_str) assert all(var >= 0 for var in (output_location, error_location)) assert output_location < error_location
def test_no_gcloud_or_registry(open_mock, process_helpers, copytree_mock, check_output_mock, config_helpers_mock, error): """No such file or directory" OSError to simulate gcloud not found With and without the error `No such file or directory` If there was a file or dir, then we `raise` the error triggered """ check_output_mock.side_effect = OSError(error) new_dir = str(uuid.uuid4()) init_dict = { 'init': True, '--template': 'tf-dist-mnist', '--template-repo': project.basedir(), '--namespace': 'test-namespace', '<name>': new_dir, '--registry': False, '--skip-crd-check': False, '--enable-sync': False } init = InitCommand(init_dict) with catch_stdout() as output: if "No such file or directory" in error: init.action() output = output.getvalue() assert "No registry name was provided and gcloud was not "\ "found. Please set your container registry name" in output else: # raising OSError triggers a sys.exit(1) call in action() with pytest.raises(SystemExit): init.action() assert init.app_name == new_dir
def test_image_push_error(walk_mock, progress_bar, popen_mock, open_mock, template, kube_helpers, process_helpers, verify_build, verify_init, fetch_action_arg, json_mock): json_mock.load.return_value = { 'last_remote_container': 'gcr.io/app_name:container_id', 'last_push_duration': 0.18889} # setup mock to induce and error during the deploy popen_mock.return_value.poll.return_value = 1 output_str = "normal output..." error_str = "error message..." build_output = MagicMock() build_output.decode.return_value = output_str error_output = MagicMock() error_output.decode.return_value = error_str popen_mock.return_value.communicate.return_value = (build_output, error_output) deploy_cmd = DeployCommand({'deploy': True, '--skip-crd-check': True, '--no-push': False}) deploy_cmd.config = {'name': 'app', 'namespace': 'namespace'} deploy_cmd.config.update({'gceProject': 'gcr://projectfoo'}) with catch_stdout() as caught_output: with pytest.raises(SystemExit): deploy_cmd.action() output = caught_output.getvalue() # assert that we got the normal output, followed by the error message output_location = output.find(output_str) error_location = output.find(error_str) assert all(var >= 0 for var in (output_location, error_location)) assert output_location < error_location
def test_logs_command_not_found(json_mock, open_mock, sleep_mock, check_for_pods_readiness_mock, verify_init, process_helpers, os_path_mock): run_id = str(uuid.uuid4()) os_path_mock.exists.return_value = True json_mock_data = { 'last_remote_container': 'gcr.io/app_name:container_id', 'last_push_duration': 0.18889, 'app_run_id': run_id } json_mock.load.return_value = json_mock_data logs_command = LogsCommand({'logs': True, '--since': '1m', '--retries': 5}) logs_command.config = {'name': 'app', 'namespace': 'namespace'} check_for_pods_readiness_mock.return_value = True command_not_found = '/bin/sh: kubetail: command not found' process_helpers.return_value.stdout.readline.return_value = '' process_helpers.return_value.poll.return_value = 1 process_helpers.return_value.\ stderr.readline.side_effect = Exception(command_not_found) with catch_stdout() as caught_output: with pytest.raises(SystemExit): logs_command.action() output = caught_output.getvalue() assert 'It is a prerequisite' in output
def test_needs_init_command_bad_init(): with catch_stdout() as output: with pytest.raises(SystemExit) as bad_init: load_config() assert output.getvalue() == "This command requires you to" \ " be in an `mlt init` built directory" assert bad_init.value.code == 1
def test_events_get_events(json_mock, open_mock, verify_init, process_helpers, os_path_mock): run_id = str(uuid.uuid4()) os_path_mock.exists.return_value = True json_mock_data = { 'last_remote_container': 'gcr.io/app_name:container_id', 'last_push_duration': 0.18889, 'app_run_id': run_id } json_mock.load.return_value = json_mock_data events_command = EventsCommand({'events': True}) events_command.config = {'name': 'app', 'namespace': 'namespace'} head_value = "LAST SEEN FIRST SEEN COUNT" event_value = '-'.join(['app', run_id]) process_helpers.return_value.stdout.readline.side_effect = [ head_value, event_value, '' ] process_helpers.return_value.poll.return_value = 1 process_helpers.return_value.stderr.readline.return_value = '' with catch_stdout() as caught_output: events_command.action() output = caught_output.getvalue() assert head_value in output assert event_value in output
def test_init_dir_exists(open_mock, process_helpers, copytree_mock, check_output_mock, config_helpers_mock, colored_mock, traceback_mock, errno_op): new_dir = str(uuid.uuid4()) init_dict = { 'init': True, '--template': 'hello-world', '<name>': new_dir, '--skip-crd-check': True, '--template-repo': project.basedir() } copytree_mock.side_effect = OSError(errno_op, 'error') with catch_stdout() as caught_output: with pytest.raises(SystemExit) as bad_init: InitCommand(init_dict).action() assert bad_init.value.code == 1 if errno_op == errno.EEXIST: assert \ caught_output.getvalue().strip() == \ "Directory '{}' already exists: delete ".format( new_dir) + "before trying to initialize new " \ "application" else: traceback_mock.print_exc.assert_called_once()
def test_init_ksync_missing(open_mock, process_helpers, copytree_mock, check_output_mock, config_helpers_mock, copyfile_mock, listdir_mock, binary_path_mock): check_output_mock.return_value.decode.return_value = 'bar' new_dir = str(uuid.uuid4()) init_dict = { 'init': True, '--template': 'hello-world', '--template-repo': project.basedir(), '--registry': None, '--namespace': None, '--skip-crd-check': True, '--enable-sync': True, '<name>': new_dir } binary_path_mock.return_value = False config_helpers_mock.get_template_parameters_from_file.return_value = \ [{"name": "greeting", "value": "hello"}] with catch_stdout() as caught_output: with pytest.raises(SystemExit) as bad_init: InitCommand(init_dict).action() assert \ caught_output.getvalue() == "ksync is not installed on " \ "localhost" assert bad_init.value.code == 1
def test_checking_crds_on_k8_exception(proc_helpers): proc_helpers.run_popen.side_effect = Exception('Something went wrong.') with catch_stdout() as output: crds = checking_crds_on_k8({'tfjob', 'pytorchjob'}) output = output.getvalue().strip() assert output == "Crd_Checking - Exception: Something went wrong." assert crds == set()
def test_build_get_template_parameters(progress_bar_mock, popen_mock, prevent_deadlock_mock, open_mock, init_mock, template_parameters, get_template_parameters_mock): progress_bar_mock.duration_progress.side_effect = \ lambda x, y, z: print('Building') build = BuildCommand({'build': True, '--watch': False, '--verbose': False}) build.config = MagicMock() get_template_parameters_mock.return_value = template_parameters with catch_stdout() as caught_output: build.action() output = caught_output.getvalue() # assert that we started build, then did build process, then built starting = output.find('Starting build') building = output.find('Building') built = output.find('Built') assert all(var >= 0 for var in (starting, building, built)) assert starting < building < built
def deploy(no_push, skip_crd_check, interactive, extra_config_args, retries=5, template='test', logs=False, verbose=False, catch_exception=None): deploy = DeployCommand({ 'deploy': True, '--no-push': no_push, '--skip-crd-check': skip_crd_check, '--interactive': interactive, '--retries': retries, '--logs': logs, '--verbose': verbose }) deploy.config = { 'name': 'app', 'namespace': 'namespace', 'template': template } deploy.config.update(extra_config_args) with catch_stdout() as caught_output: with conditional(catch_exception, pytest.raises(catch_exception)): deploy.action() output = caught_output.getvalue() return output
def test_dispatch(call, open_mock): """normal file event handling""" event_handler = EventHandler(lambda: 'foo') event_handler.timer = None with catch_stdout() as caught_output: event_handler.dispatch(MagicMock(src_path='/foo')) output = caught_output.getvalue() assert output == 'event.src_path /foo\n'
def status(): status_cmd = StatusCommand({}) status_cmd.config = {'name': 'app', 'namespace': 'namespace'} with catch_stdout() as caught_output: status_cmd.action() output = caught_output.getvalue() return output
def test_undeploy_by_bad_job_name(remove_job_dir_mock, get_deployed_jobs_mock): """tests `mlt undeploy --job-name` with a non existing job name.""" remove_job_dir_mock.input_value = 'k8s/job1' get_deployed_jobs_mock.return_value = ["job1"] command = {'undeploy': True, '--job-name': 'job2'} with catch_stdout() as output: with pytest.raises(SystemExit): UndeployCommand(command).action() assert "Job name job2 not found" in output.getvalue()
def get_events(catch_exception=None, job_name=None): events_command = EventsCommand({'events': True, '--job-name': job_name}) events_command.config = {'name': 'app', 'namespace': 'namespace'} with catch_stdout() as caught_output: with conditional(catch_exception, pytest.raises(catch_exception)): events_command.action() output = caught_output.getvalue().strip() return output
def config(list=False, set=False, remove=False, name=None, value=None): config_cmd = TemplateConfigCommand( {"list": list, "set": set, "remove": remove, "<name>": name, "<value>": value}) with catch_stdout() as caught_output: config_cmd.action() output = caught_output.getvalue() return output
def status(count=1, catch_exception=None): status_cmd = StatusCommand({'<count>': count}) status_cmd.config = {'name': 'app', 'namespace': 'namespace'} with catch_stdout() as caught_output: with conditional(catch_exception, pytest.raises(catch_exception)): status_cmd.action() output = caught_output.getvalue() return output
def test_get_only_one_job_job_not_found(get_deployed_jobs_mock): """If we request a job with --job-name flag and it doesn't exist""" get_deployed_jobs_mock.return_value = ['k8s/job-asdf'] with catch_stdout() as output: with pytest.raises(SystemExit): get_only_one_job('not-a-job', '') output = output.getvalue().strip() assert output == "Job not-a-job not found.\nJobs to choose from are:\n" + \ 'k8s/job-asdf'
def test_get_only_one_job_many_jobs(get_deployed_jobs_mock): """if we want 1 job but get many returned we throw valueerror""" get_deployed_jobs_mock.return_value = ['k8s/job-asdf', 'k8s/job-jkl;'] with catch_stdout() as output: with pytest.raises(SystemExit): get_only_one_job(None, 'too many jobs, pick one') output = output.getvalue().strip() assert output == "too many jobs, pick one\nJobs to choose from are:\n" + \ "k8s/job-asdf\nk8s/job-jkl;"
def test_template_list(valid_template_dir, copy_tree_mock): args = { 'template': 'test', 'list': True, '--template-repo': valid_template_dir } templates = TemplatesCommand(args) with catch_stdout() as caught_output: templates.action() assert caught_output.getvalue() is not None
def test_template_list(): args = { 'template': 'test', 'list': True, '--template-repo': project.basedir() } templates = TemplatesCommand(args) with catch_stdout() as caught_output: templates.action() assert caught_output.getvalue() is not None
def test_main_bad_flags(flag_input, mock_gfile, mock_flags): """Asserts passing in bad input causes return of -1""" mock_gfile.Exists.return_value = False mock_flags.input = flag_input with catch_stdout() as output: func_return = main(["--flag", "arg"]) output = output.getvalue() assert func_return == -1 assert output == "Input graph file '{}' does not exist!\n".format( flag_input)
def test_main_uncaught_exception(docopt_mock, run_command_mock): """tests what happens when some part of the program fails""" run_command_mock.side_effect = Exception with catch_stdout() as output: with pytest.raises(Exception): main() output = output.getvalue() assert "You've discovered a bug! Please make an issue on " + \ "https://github.com/IntelAI/mlt/issues if one does not " + \ "exist already." in output, output
def sync(create=False, reload=False, delete=False): sync_cmd = SyncCommand({ "create": create, "reload": reload, "delete": delete }) with catch_stdout() as caught_output: sync_cmd.action() output = caught_output.getvalue() return output
def test_uninitialized_status(): """ Tests calling the status command before the app has been initialized. """ with catch_stdout() as caught_output: with pytest.raises(SystemExit): StatusCommand({}) output = caught_output.getvalue() expected_error = "This command requires you to be in an `mlt init` " \ "built directory" assert expected_error in output
def test_run_error(check_output): """There was a bad command made, therefore no output""" check_output.side_effect = CalledProcessError(returncode=2, cmd='Bad Command!') with catch_stdout() as caught_output: with pytest.raises(SystemExit): run('ls') output = caught_output.getvalue().strip() # since we're mocking CalledProcessError call, not sure we can simulate # exception raised by actual check_output call, so e.output is None assert output == 'None'
def test_run_popen_failed_cmd(popen_mock): """If the cmd isn't valid assert some sort of error output + SystemExit""" bad_cmd = "foo bar" bad_cmd_output = "Not a valid command" popen_mock.side_effect = CalledProcessError(returncode=2, cmd=bad_cmd, output=bad_cmd_output) with catch_stdout() as caught_output: with pytest.raises(SystemExit): run_popen(bad_cmd) output = caught_output.getvalue().strip() assert output == bad_cmd_output
def test_events_no_push_json_file(open_mock, verify_init, process_helpers, os_path_mock): os_path_mock.exists.return_value = False events_command = EventsCommand({'events': True}) events_command.config = {'name': 'app', 'namespace': 'namespace'} with catch_stdout() as caught_output: with pytest.raises(SystemExit): events_command.action() output = caught_output.getvalue() assert "This app has not been deployed yet" in output
def test_logs_check_for_pods_readiness_max_retries_reached(process_helpers, sleep_mock): run_id = str(uuid.uuid4()).split("-") filter_tag = "-".join(["app", run_id[0], run_id[1]]) process_helpers.return_value.stdout.read.return_value = "\n".join(["random-pod1", "random-pod2"]) with catch_stdout() as caught_output: found = check_for_pods_readiness(namespace='namespace', filter_tag=filter_tag, retries=5) output = caught_output.getvalue() assert found == False assert "Max retries Reached." in output
def test_logs_no_push_json_file(open_mock, verify_init, sleep_mock, process_helpers, os_path_mock): os_path_mock.exists.return_value = False logs_command = LogsCommand({'logs': True, '--since': '1m', '--retries':5}) logs_command.config = {'name': 'app', 'namespace': 'namespace'} with catch_stdout() as caught_output: with pytest.raises(SystemExit): logs_command.action() output = caught_output.getvalue() assert "This app has not been deployed yet" in output