def test_marathon_validate_schema_healthcheck_cmd_has_cmd( mock_stdout, mock_get_file_contents ): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd """ mock_get_file_contents.return_value = marathon_content assert not validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_INVALID in output marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd healthcheck_cmd: '/bin/true' """ mock_get_file_contents.return_value = marathon_content mock_stdout.truncate(0) assert validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_VALID in output
def test_marathon_validate_schema_healthcheck_cmd_has_cmd( mock_get_file_contents, capfd, ): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd """ mock_get_file_contents.return_value = marathon_content assert not validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_INVALID in output marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd healthcheck_cmd: '/bin/true' """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_schema_healthcheck_non_cmd(mock_stdout, mock_get_file_contents): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: tcp """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_VALID in output marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content mock_stdout.truncate(0) assert validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_VALID in output
def test_marathon_validate_schema_healthcheck_non_cmd(mock_get_file_contents, capsys): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: tcp """ mock_get_file_contents.return_value = marathon_content for schema_type in ["marathon", "kubernetes"]: assert validate_schema("unused_service_path.yaml", schema_type) output, _ = capsys.readouterr() assert SCHEMA_VALID in output marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content for schema_type in ["marathon", "kubernetes"]: assert validate_schema("unused_service_path.yaml", schema_type) output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_schema_list_hashes_good( mock_stdout, mock_get_file_contents ): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd main_http: cpus: 0.1 instances: 2 mem: 250 disk: 512 """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_VALID in output
def test_marathon_validate_schema_list_hashes_good( mock_get_file_contents, capfd, ): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd healthcheck_cmd: '/bin/true' _main_http: cpus: 0.1 instances: 2 mem: 250 disk: 512 registrations: ['foo.bar', 'bar.baz'] """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output
def test_tron_validate_schema_good( mock_get_file_contents, capfd, ): tron_content = """ jobs: - name: test_job node: batch_box service: my_service deploy_group: prod allow_overlap: false monitoring: team: my_team schedule: type: cron value: "0 7 * * 5" actions: - name: first command: echo hello world - name: second command: sleep 10 expected_runtime: 15 sec executor: paasta cluster: paasta-cluster-1 cpus: 0.5 mem: 100 pool: custom """ mock_get_file_contents.return_value = tron_content assert validate_schema('unused_service_path.yaml', 'tron') output, _ = capfd.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_schema_keys_outside_instance_blocks_bad( mock_stdout, mock_get_file_contents ): mock_get_file_contents.return_value = """ { "main": { "instances": 5 }, "page": false } """ validate_schema('unused_service_path.json', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_INVALID in output
def test_chronos_validate_schema_keys_outside_instance_blocks_bad( mock_stdout, mock_get_file_contents ): mock_get_file_contents.return_value = """ { "daily_job": { "schedule": "bar" }, "page": false } """ validate_schema('unused_service_path.json', 'chronos') output = mock_stdout.getvalue() assert SCHEMA_INVALID in output
def test_rollback_validate_schema_invalid(mock_content, capsys): with mock.patch( "paasta_tools.cli.cmds.validate.get_file_contents", autospec=True, return_value=mock_content, ): assert not validate_schema("rollback-not-real.yaml", "rollback") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def validate_auto_config_file(filepath: str, schema_subdir: str): basename = os.path.basename(filepath) for file_type in KNOWN_CONFIG_TYPES: schema_path = f"{schema_subdir}/{file_type}" if schema_subdir else file_type if basename.startswith(file_type): return bool(validate_schema(filepath, schema_path)) else: logging.info( f"{filepath} is invalid because it has no validator defined") return False
def test_chronos_validate_schema_list_hashes_good( mock_stdout, mock_get_file_contents ): mock_get_file_contents.return_value = """ { "daily_job": { "schedule": "bar" }, "wheekly": { "schedule": "baz" } } """ validate_schema('unused_service_path.json', 'chronos') output = mock_stdout.getvalue() assert SCHEMA_VALID in output
def validate_auto_config_file(filepath: str): basename = os.path.basename(filepath) for file_type in KNOWN_CONFIG_TYPES: if basename.startswith(file_type): return bool( validate_schema(filepath, f"{AUTO_SOACONFIG_SUBDIR}/{file_type}") ) else: logging.info(f"{filepath} is invalid because it has no validator defined") return False
def test_marathon_validate_schema_security_bad(mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ main: dependencies_reference: main security: outbound_firewall: bblock """ assert not validate_schema("unused_service_path.yaml", "marathon") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def test_marathon_validate_invalid_key_bad(mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ { "main": { "fake_key": 5 } } """ assert not validate_schema("unused_service_path.json", "marathon") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def test_chronos_validate_schema_security_good(mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ some_batch: schedule: foo dependencies_reference: main security: outbound_firewall: block """ assert validate_schema("unused_service_path.yaml", "chronos") output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_invalid_key_bad(mock_stdout, mock_get_file_contents): mock_get_file_contents.return_value = """ { "main": { "fake_key": 5 } } """ assert not validate_schema("unused_service_path.json", "marathon") output = mock_stdout.getvalue() assert SCHEMA_INVALID in output
def test_rollback_validate_schema(mock_content, capsys): # TODO: if we wanted to get fancy, we could use some advanced pytest # parametrization to get an exhaustive test of all sources (in this # test and in test_rollback_validate_schema_invalid), but that doesn't # seem worth it at the moment with mock.patch( "paasta_tools.cli.cmds.validate.get_file_contents", autospec=True, return_value=mock_content, ): assert validate_schema("rollback-not-real.yaml", "rollback") output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_schema_keys_outside_instance_blocks_bad( mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ { "main": { "instances": 5 }, "page": false } """ assert not validate_schema("unused_service_path.json", "marathon") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def test_marathon_validate_invalid_key_bad(mock_stdout, mock_get_file_contents): mock_get_file_contents.return_value = """ { "main": { "fake_key": 5 } } """ assert not validate_schema('unused_service_path.json', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_INVALID in output
def test_chronos_validate_schema_keys_outside_instance_blocks_bad( mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ { "daily_job": { "schedule": "bar" }, "page": false } """ assert not validate_schema("unused_service_path.json", "chronos") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def test_tron_validate_schema_job_extra_properties_bad(mock_get_file_contents, capsys): tron_content = """ test_job: node: batch_box schedule: "daily 04:00:00" unexpected: 100 actions: first: command: echo hello world """ mock_get_file_contents.return_value = tron_content assert not validate_schema("unused_service_path.yaml", "tron") output, _ = capsys.readouterr() assert SCHEMA_INVALID in output
def test_marathon_validate_schema_security_good( mock_get_file_contents, capfd, ): mock_get_file_contents.return_value = """ main: dependencies_reference: main security: outbound_firewall: block """ assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_schema_list_hashes_good( mock_stdout, mock_get_file_contents ): marathon_content = """ --- main_worker: cpus: 0.1 instances: 2 mem: 250 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py healthcheck_mode: cmd main_http: cpus: 0.1 instances: 2 mem: 250 """ mock_get_file_contents.return_value = marathon_content validate_schema('unused_service_path.yaml', 'marathon') output = mock_stdout.getvalue() assert SCHEMA_VALID in output
def test_chronos_validate_schema_security_bad( mock_get_file_contents, capfd, ): mock_get_file_contents.return_value = """ some_batch: schedule: foo dependencies_reference: main security: outbound_firewall: bblock """ assert not validate_schema('unused_service_path.yaml', 'chronos') output, _ = capfd.readouterr() assert SCHEMA_INVALID in output
def test_chronos_validate_schema_list_hashes_good(mock_get_file_contents, capsys): mock_get_file_contents.return_value = """ { "daily_job": { "schedule": "bar" }, "wheekly": { "schedule": "baz" } } """ assert validate_schema("unused_service_path.json", "chronos") output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_marathon_validate_understands_underscores(mock_get_file_contents, capsys): marathon_content = """ --- _template: &template foo: bar main: cpus: 0.1 instances: 2 env: <<: *template """ mock_get_file_contents.return_value = marathon_content assert validate_schema("unused_service_path.yaml", "marathon") output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_tron_validate_schema_understands_underscores(mock_get_file_contents, capsys): tron_content = """ _my_template: &a_template actions: first: command: echo hello world test_job: node: batch_box schedule: type: cron value: "0 7 * * 5" <<: *a_template """ mock_get_file_contents.return_value = tron_content assert validate_schema("unused_service_path.yaml", "tron") output, _ = capsys.readouterr() assert SCHEMA_VALID in output
def test_tron_validate_schema_actions_extra_properties_bad( mock_get_file_contents, capfd, ): tron_content = """ jobs: - name: test_job node: batch_box schedule: "daily 04:00:00" actions: - name: first command: echo hello world something_else: true """ mock_get_file_contents.return_value = tron_content assert not validate_schema('unused_service_path.yaml', 'tron') output, _ = capfd.readouterr() assert SCHEMA_INVALID in output
def test_check_parallel_fails(mock_get_config_file_dict): # only "parallel" is allowed to have nested steps inside it mock_get_config_file_dict.return_value = { "pipeline": [{ "invalid-prop": [ { "step": "somecluster.something", }, { "step": "somesecurity.check", }, ], "step": "anothercluster.something", "wait_for_deployment": False, "timeout": 3600, }], } assert validate_schema("my/fake-service", "deploy") is False
def test_check_parallel_works(mock_get_config_file_dict): # Parallel steps is seen as valid mock_get_config_file_dict.return_value = { "pipeline": [{ "parallel": [ { "step": "somecluster.something", }, { "step": "somesecurity.check", }, ], "step": "anothercluster.something", "wait_for_deployment": False, "timeout": 3600, }], } assert validate_schema("my/fake-service", "deploy") is True
def test_marathon_validate_id( mock_get_file_contents, capfd, ): marathon_content = """ --- valid: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output marathon_content = """ --- this_is_okay_too_1: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output marathon_content = """ --- dashes-are-okay-too: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content assert validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_VALID in output marathon_content = """ --- main_worker_CAPITALS_INVALID: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content assert not validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_INVALID in output marathon_content = """ --- $^&*()(&*^%&definitely_not_okay: cpus: 0.1 instances: 2 mem: 250 disk: 512 cmd: virtualenv_run/bin/python adindexer/adindex_worker.py """ mock_get_file_contents.return_value = marathon_content assert not validate_schema('unused_service_path.yaml', 'marathon') output, _ = capfd.readouterr() assert SCHEMA_INVALID in output