def test_env_from_env_maps(mock_read): config_contents = ''' version: '1.0' envMaps: dbs: DSN: mysql://some_dsn webs: SECRET: this-will-be-overridden USER: jerry services: web1: run: java -jar /path/to/server.jar env: BAR: asdf SECRET: verysecret envFromMap: - dbs - webs ''' mock_read.return_value = config_contents conf = Config(FILE_NAME).parse() assert len(conf.services) == 1 assert conf.services[0].env == { 'DSN': 'mysql://some_dsn', 'SECRET': 'verysecret', 'BAR': 'asdf', 'USER': '******', }
def test_services_all_items_are_passed(mock_read): config_contents = ''' version: '1.0' services: web1: run: java -jar /path/to/server.jar color: red cwd: /usr/bin env: FOO: 123 BAR: asdf silent: yes shell: no ''' mock_read.return_value = config_contents conf = Config(FILE_NAME).parse() assert len(conf.services) == 1 web1 = conf.services[0] assert web1.name == 'web1' assert web1.cmd == 'java -jar /path/to/server.jar' assert web1.color == 'red' assert web1.cwd == '/usr/bin' assert 'FOO' in web1.env # check that everything is converted into string for valid shell ENV assert web1.env['FOO'] == '123' assert 'BAR' in web1.env assert web1.env['BAR'] == 'asdf' assert web1.quiet assert not web1.in_shell
def test_parse_with_non_existent_file(mock_read): conf = None mock_read.side_effect = IOError('File is missing in OS') with pytest.raises(Exception) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is None assert str(execinfo.value) == \ 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\nFile is missing in OS'
def test_parse_fails_with_empty_file(mock_read): conf = None mock_read.return_value = '' with pytest.raises(Exception) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is None assert str(execinfo.value) == \ 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\nFile is empty.'
def test_parse_fails_with_malformed_yaml_file(mock_read): mock_read.return_value = 'foo: {{{' conf = None with pytest.raises(Exception) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is None assert 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' in \ str(execinfo.value) assert 'while parsing' in str(execinfo.value)
def test_parse_minimal_required(mock_read): config_contents = ''' version: '123.0' ''' mock_read.return_value = config_contents conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is not None assert conf.version == '123.0' assert conf.settings == {} assert conf.services == []
def test_services_validate_cwd_not_specified(mock_read): config = ''' version: '1.0' services: web: run: ls . ''' mock_read.return_value = config conf = Config(FILE_NAME, '/path/workdir').parse() assert len(conf.services) == 1
def test_settings_property(mock_read): config_contents = ''' version: '1.0' settings: foo: 123 bar: asdf ''' mock_read.return_value = config_contents conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is not None assert conf.settings == {'bar': 'asdf', 'foo': 123}
def test_parse_fails_with_no_version_specified(mock_read): config_contents = ''' bar: 900 ''' mock_read.return_value = config_contents conf = None with pytest.raises(Exception) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is None assert 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' in \ str(execinfo.value) assert "'version' is a required property" in str(execinfo.value)
def test_services_work_dir(mock_read, set_current_dir_fixture, cwd_in_config, run_in_dir, expected): assert os.getcwd() == TMP_DIR config = ''' version: '1.0' services: web: run: ls . %s ''' % cwd_in_config mock_read.return_value = config conf = Config(filename=FILE_NAME, workdir=run_in_dir).parse() srv = conf.services[0] assert srv.cwd == expected
def test_services_validate_cwd_inexistent(mock_read): config = ''' version: '1.0' services: web: run: ls . cwd: /some/unknown/path ''' mock_read.return_value = config with pytest.raises(ConfigurationError) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() # conf.services assert str(execinfo.value) == \ 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' + \ 'Directory "/some/unknown/path" for service "web" not found'
def test_env_from_missing_map(mock_read): config = ''' version: '1.0' services: web: run: cat /etc/hosts envFromMap: - dbs - webs ''' mock_read.return_value = config with pytest.raises(ConfigurationError) as execinfo: Config(FILE_NAME, '/path/workdir').parse() ex_msg = str(execinfo.value) assert ex_msg == 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' + \ 'EnvMap "dbs" is unknown and is missing in the envMaps'
def test_services_property(mock_read): config_contents = ''' version: '1.0' services: web1: run: ruby server-script.rb web2: run: java -jar /path/to/server.jar ''' mock_read.return_value = config_contents conf = Config(FILE_NAME, '/path/workdir').parse() assert len(conf.services) == 2 assert 'web1' in list([s.name for s in conf.services]) assert 'web2' in list([s.name for s in conf.services]) assert isinstance(conf.services[0], Service) assert isinstance(conf.services[1], Service)
def test_validate_wrong_color(mock_read): config_contents = ''' version: '1.0' services: cat: run: cat /etc/hosts color: fancy-color ''' mock_read.return_value = config_contents conf = None with pytest.raises(Exception) as execinfo: conf = Config(FILE_NAME, '/path/workdir').parse() assert conf is None assert 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' in \ str(execinfo.value) assert "Color 'fancy-color' for service 'cat' is not allowed." in str( execinfo.value)
def test_ready_probe(mock_read): config_contents = ''' version: '1.0' services: web1: run: java -jar /path/to/server.jar readyProbe: tcpCheck: endpoint: aakshskahk httpCheck: url: aakshskahk retry: attempts: 12 ''' mock_read.return_value = config_contents conf = Config(FILE_NAME).parse() assert len(conf.services) == 1
def test_env_from_all_sources(mock_read, set_current_dir_fixture): config = ''' version: '1.0' envMaps: db: DB_USER: jim MAP_VAL: 'val in map db' BAR: 'from map db' smtp: SMTP_USER: Cory MAP_VAL: 'val in map smtp' BAR: 'from map smtp' services: web: run: cat /etc/hosts cwd: %s env: FOO: "it's me" BAR: "from env" envFromMap: - db - smtp envFromDotenv: true envFromOS: true ''' % TMP_DIR try: env_file = os.path.join(TMP_DIR, '.env') mock_read.return_value = config with open(env_file, 'w') as f: f.write('COMPOSE_PASSWORD=secret\n') f.write('BAR=from dotfile\n') os.environ['COMPOSE_TEST'] = 'hey' os.environ['BAR'] = 'from os' conf = Config(FILE_NAME, '/path/workdir').parse() envs = conf.services[0].env assert envs['BAR'] == 'from os' assert envs['COMPOSE_TEST'] == 'hey' assert envs['FOO'] == "it's me" assert envs['COMPOSE_PASSWORD'] == 'secret' assert envs['DB_USER'] == 'jim' assert envs['SMTP_USER'] == 'Cory' assert envs['MAP_VAL'] == 'val in map smtp' finally: os.remove(env_file) del os.environ['COMPOSE_TEST']
def test_bad_env(mock_read): config = ''' version: '1.0' services: web: run: cat /etc/hosts env: FOO: - the - array ''' mock_read.return_value = config with pytest.raises(ConfigurationError) as execinfo: Config(FILE_NAME, '/path/workdir').parse() ex_msg = str(execinfo.value) assert 'Configuration file "/path/workdir/unit-test-config-file.yaml" is invalid.\nErrors found:\n' in ex_msg assert 'On instance' in ex_msg assert "['the', 'array']" in ex_msg
def test_env_from_map_uses_array_order(mock_read, set_current_dir_fixture): config = ''' version: '1.0' envMaps: db: MAP_VAL: 'val in map db' smtp: MAP_VAL: 'val in map smtp' services: web: run: cat /etc/hosts envFromMap: - smtp - db ''' mock_read.return_value = config conf = Config(FILE_NAME, '/path/workdir').parse() envs = conf.services[0].env assert envs['MAP_VAL'] == 'val in map db'
def test_env_values_are_converted_to_string_before_run(mock_read): config_contents = ''' version: '1.0' services: web1: run: java -jar /path/to/server.jar env: FOO: 123 BAR: asdf BAR_ONE: "asdf" BAR_TWO: > i am a long text BAZ: 77.95 ''' mock_read.return_value = config_contents conf = Config(FILE_NAME).parse() web1 = conf.services[0] assert len(conf.services) == 1 assert web1.env['FOO'] == '123' assert web1.env['BAR'] == 'asdf' assert web1.env['BAR_ONE'] == 'asdf' assert web1.env['BAR_TWO'] == 'i am a long text\n' assert web1.env['BAZ'] == '77.95'
def test_config_example(): assert Config.example() == '''