def test_rename_unchanged(self): test_files = [ ( 'template.txt', '''\ {# Delete template.txt #} {% template_specialize_rename "template.txt" %} {# Rename the file and the sub-directory #} {% template_specialize_rename "subdir/subtemplate.txt", "subtemplate.txt" %} {% template_specialize_rename "subdir", "subdir" %} ''' ), (('subdir', 'subtemplate.txt'), 'agree, "{{foo}}" is the value of "foo"') ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: # Destination directory exists and is non-empty os.mkdir(os.path.join(output_dir, 'newdir')) os.mkdir(os.path.join(output_dir, 'newdir', 'newsubdir')) main([input_dir, output_dir, '--key', 'foo', 'bar']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') self.assertFalse(os.path.exists(os.path.join(output_dir, 'template.txt'))) self.assertTrue(os.path.exists(os.path.join(output_dir, 'subdir'))) with open(os.path.join(output_dir, 'subdir', 'subtemplate.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual(f_output.read(), 'agree, "bar" is the value of "foo"')
def test_unknown_environment(self): test_files = [ ( 'config.config', '''\ env: values: a: a: foo ''' ) ] with self.create_test_files(test_files) as input_dir: config_path = os.path.join(input_dir, 'config.config') for argv in [ ['-c', config_path, '-e', 'unknown', 'src.txt', 'dst.txt'], ['-e', 'unknown', 'src.txt', 'dst.txt'] ]: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main(argv) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '''\ unknown environment 'unknown' ''' )
def test_aws_parameter_store_error(self): test_files = [ ( 'template.txt', '''\ {% aws_parameter_store 'some/string' %} ''' ) ] with self.create_test_files(test_files) as input_dir: input_path = os.path.join(input_dir, 'template.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr, \ unittest_mock.patch('botocore.session') as mock_session: mock_session.get_session.return_value.create_client.return_value.get_parameter.side_effect = \ botocore.exceptions.ClientError({'Error': {'Code': 'SomeError'}}, 'GetParameter') with self.assertRaises(SystemExit) as cm_exc: main([input_path]) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '''\ Failed to retrieve value "some/string" from parameter store with error: SomeError ''' )
def test_keys_only(self): test_files = [ ( 'template.txt', '''\ a.a = {{a.a}} a.b = {{a.b}} a.c = {{a.c}} ''' ) ] with self.create_test_files(test_files) as input_dir, \ self.create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([ '--key', 'a', '--value', '{a: foo}', '--key', 'a', '--value', '{b: bar}', '--key', 'a', '--value', '{c: [3]}', input_path, output_path ]) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(os.path.join(output_dir, 'other.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual( f_output.read(), '''\ a.a = foo a.b = bar a.c = [3]''' )
def test_stdin_to_stdout(self): with unittest_mock.patch('sys.stdin', new=StringIO('the value of "foo" is "{{foo}}"')), \ unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main(['--key', 'foo', '--value', 'bar']) self.assertEqual(stdout.getvalue(), 'the value of "foo" is "bar"') self.assertEqual(stderr.getvalue(), '')
def test_environment_only(self): test_files = [ ( 'test.config', '''\ env1: values: a: a: "foo" c: [1, 2] env2: values: b: a: "nope" ''' ), ( 'test2.config', '''\ env3: parents: [env1] values: a: b: "bar" c: [4, 5, 3] ''' ), ( 'template.txt', '''\ a.a = {{a.a}} a.b = {{a.b}} a.c = {{a.c}} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: test_path = os.path.join(input_dir, 'test.config') test2_path = os.path.join(input_dir, 'test2.config') input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main(['-c', test_path, '-c', test2_path, '-e', 'env3', input_path, output_path]) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(os.path.join(output_dir, 'other.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual( f_output.read(), '''\ a.a = foo a.b = bar a.c = [4, 5, 3] ''' )
def test_stdin_to_file(self): with self.create_test_files([]) as output_dir: output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdin', new=StringIO('the value of "foo" is "{{foo}}"')), \ unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main(['-', output_path, '--key', 'foo', '--value', 'bar']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(output_path, 'r', encoding='utf-8') as f_output: self.assertEqual(f_output.read(), 'the value of "foo" is "bar"')
def test_file_to_stdout(self): test_files = [ ('template.txt', 'the value of "foo" is "{{foo}}"') ] with self.create_test_files(test_files) as input_dir: input_path = os.path.join(input_dir, 'template.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([input_path, '--key', 'foo', '--value', 'bar']) self.assertEqual(stdout.getvalue(), 'the value of "foo" is "bar"') self.assertEqual(stderr.getvalue(), '')
def test_environment_and_keys(self): test_files = [ ( 'config.config', '''\ env: values: a: a: foo b: bar c: [1] ''' ), ( 'template.txt', '''\ a.a = {{a.a}} a.b = {{a.b}} a.c = {{a.c}} ''' ) ] with self.create_test_files(test_files) as input_dir, \ self.create_test_files([]) as output_dir: config_path = os.path.join(input_dir, 'config.config') input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([ '-c', config_path, '-e', 'env', '--key', 'a', '--value', '{b: bonk}', '--key', 'a', '--value', '{c: [10]}', '--key', 'a', '--value', '{c: [12, 11]}', input_path, output_path ]) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(os.path.join(output_dir, 'other.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual( f_output.read(), '''\ a.a = foo a.b = bonk a.c = [12, 11]''' )
def test_version(self): for argv in [ ['-v'], ['--version'] ]: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main(argv) self.assertEqual(cm_exc.exception.code, 0) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), str(__version__) + '\n')
def test_file_not_exist(self): with self.create_test_files([]) as input_dir, \ self.create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([input_path, output_path, '--key', 'foo', '--value', 'bar']) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), "[Errno 2] No such file or directory: '{0}'\n".format(input_path)) self.assertFalse(os.path.exists(input_path)) self.assertFalse(os.path.exists(output_path))
def test_file_to_file(self): test_files = [ ('template.txt', 'the value of "foo" is "{{foo}}"') ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([input_path, output_path, '--key', 'foo', 'bar']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(os.path.join(output_dir, 'other.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual(f_output.read(), 'the value of "foo" is "bar"')
def test_aws_parameter_store(self): test_files = [ ( 'template.txt', '''\ {% filter tojson %}{% aws_parameter_store 'some/string' %}{% endfilter %} {% aws_parameter_store 'some/string' %} {% aws_parameter_store foo %} ''' ) ] def get_parameter(**kwargs): return { 'Parameter': { 'Value': f'{kwargs["Name"]}-{{value}}' } } with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr, \ unittest_mock.patch('botocore.session') as mock_session: mock_session.get_session.return_value.create_client.return_value.get_parameter.side_effect = get_parameter main([input_path, output_path, '--key', 'foo', 'a"[bar}']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(output_path, 'r', encoding='utf-8') as f_output: self.assertEqual( f_output.read(), '''\ "some/string-{value}" some/string-{value} a"[bar}-{value} ''' ) # get_parameter results should be cached between blocks. mock_session.get_session.return_value.create_client.return_value.assert_has_calls([ unittest_mock.call.get_parameter(Name='some/string', WithDecryption=True), unittest_mock.call.get_parameter(Name='a"[bar}', WithDecryption=True) ])
def test_invalid_keys_values(self): with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main(['--key', 'a', '--value', 'a: b: c']) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '''\ mapping values are not allowed here in "<unicode string>", line 1, column 5: a: b: c ^ ''' )
def test_dir_to_dir(self): test_files = [ ('template.txt', 'the value of "foo" is "{{foo}}"'), (('subdir', 'subtemplate.txt'), 'agree, "{{foo}}" is the value of "foo"') ] with self.create_test_files(test_files) as input_dir, \ self.create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([input_dir, output_dir, '--key', 'foo', '--value', 'bar']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') with open(os.path.join(output_dir, 'template.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual(f_output.read(), 'the value of "foo" is "bar"') with open(os.path.join(output_dir, 'subdir', 'subtemplate.txt'), 'r', encoding='utf-8') as f_output: self.assertEqual(f_output.read(), 'agree, "bar" is the value of "foo"')
def test_dir_to_file(self): test_files = [ (('subdir', 'template.txt'), 'the value of "foo" is "{{foo}}"'), ('other.txt', 'hello') ] with self.create_test_files(test_files) as input_dir: input_path = os.path.join(input_dir, 'subdir') output_path = os.path.join(input_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([input_path, output_path, '--key', 'foo', '--value', 'bar']) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), "[Errno 17] File exists: '{0}'\n".format(output_path)) self.assertTrue(os.path.isdir(input_path)) self.assertTrue(os.path.isfile(output_path))
def test_file_to_dir(self): test_files = [ ('template.txt', 'the value of "foo" is "{{foo}}"') ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, '') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([input_path, output_path, '--key', 'foo', 'bar']) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), f"{input_path}: error: [Errno 21] Is a directory: '{output_path}'\n") self.assertTrue(os.path.isfile(input_path)) self.assertTrue(os.path.isdir(output_path))
def test_rename_error_no_args(self): test_files = [ ( 'template.txt', '''\ {% template_specialize_rename %} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit): main([input_dir, output_dir]) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), f"{os.path.join(input_dir, 'template.txt')}:1: unexpected 'end of statement block'\n")
def test_rename_error_path_invalid(self): test_files = [ ( 'template.txt', '''\ {% template_specialize_rename '../bar.txt', 'foo.txt' %} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit): main([input_dir, output_dir]) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '''\ template_specialize_rename invalid path '../bar.txt\'''')
def test_dump(self): test_files = [ ( 'config.config', '''\ env: values: a: a: foo b: bar c: [1] ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') config_path = os.path.join(input_dir, 'config.config') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([ input_path, output_path, '-c', config_path, '-e', 'env', '--key', 'a', '{b: bonk}', '--key', 'a', '{c: [12, 11]}', '--dump' ]) self.assertEqual(cm_exc.exception.code, 0) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '''\ a: a: foo b: bonk c: - 12 - 11 ''')
def test_invalid_keys_values(self): with create_test_files([]) as input_dir, \ create_test_files([]) as output_dir: input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([input_path, output_path, '--key', 'a', 'a: b: c']) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '''\ mapping values are not allowed here in "<unicode string>", line 1, column 5: a: b: c ^ ''' )
def test_rename_error_name_dirname(self): test_files = [ ( 'template.txt', '''\ {% template_specialize_rename "template.txt", ' /foo.txt' %} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit): main([input_dir, output_dir]) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), f"{os.path.join(input_dir, 'template.txt')}: error: template_specialize_rename - invalid destination name ' /foo.txt'\n" )
def test_mismatched_keys_values(self): for argv in [ ['--key', 'a', 'src.txt', 'dst.txt'], ['--key', 'a', '--value', 'foo', '--key', 'b', 'src.txt', 'dst.txt'] ]: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main(argv) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '''\ usage: template-specialize [-h] [-c FILE] [-e ENV] [--key KEY] [--value VALUE] [--dump] [-v] [SRC] [DST] template-specialize: error: mismatched keys/values ''' )
def test_rename_error_dst_undefined(self): test_files = [ ( 'template.txt', '''\ {% template_specialize_rename "template.txt", foobar %} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit): main([input_dir, output_dir]) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), f"{os.path.join(input_dir, 'template.txt')}: error: 'foobar' is undefined\n" )
def test_rename_error_not_found(self): test_files = [ ( 'template.txt', '''\ {% template_specialize_rename 'missing.txt', 'bar.txt' %} ''' ) ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: output_missing = os.path.join(output_dir, 'missing.txt') output_bar = os.path.join(output_dir, 'bar.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit): main([input_dir, output_dir]) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), f"template_specialize_rename error: [Errno 2] No such file or directory: '{output_missing}' -> '{output_bar}'" )
def test_delete_directory(self): test_files = [ ( 'template.txt', '''\ {# Delete template.txt #} {% template_specialize_rename "template.txt" %} {# Delete the sub-directory #} {% template_specialize_rename "subdir" %} ''' ), (('subdir', 'subtemplate.txt'), 'agree, "{{foo}}" is the value of "foo"') ] with create_test_files(test_files) as input_dir, \ create_test_files([]) as output_dir: with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: main([input_dir, output_dir, '--key', 'foo', 'bar']) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') self.assertFalse(os.path.exists(os.path.join(output_dir, 'template.txt'))) self.assertFalse(os.path.exists(os.path.join(output_dir, 'subdir')))
def test_config_errors(self): test_files = [ ( 'test.config', '''\ env1: values: a: a: "env1 a.a" b: a: "env1 b.a" asdf1 env2: values: a: ["env2 a.0"] asdf2 ''' ), ( 'test2.config', '''\ env3: parents: [env1, env2] ''' ), ( 'template.txt', '''\ a.a = {{a.a}} b.a = {{b.a}} ''' ) ] with self.create_test_files(test_files) as input_dir, \ self.create_test_files([]) as output_dir: test_path = os.path.join(input_dir, 'test.config') test2_path = os.path.join(input_dir, 'test2.config') input_path = os.path.join(input_dir, 'template.txt') output_path = os.path.join(output_dir, 'other.txt') with unittest_mock.patch('sys.stdout', new=StringIO()) as stdout, \ unittest_mock.patch('sys.stderr', new=StringIO()) as stderr: with self.assertRaises(SystemExit) as cm_exc: main([ '-c', test_path, '-c', test2_path, '-e', 'env3', '--key', 'b', '--value', '[b0]', input_path, output_path ]) self.assertEqual(cm_exc.exception.code, 2) self.assertEqual(stdout.getvalue(), '') self.assertEqual( re.sub('^.+?test', 'test', stderr.getvalue(), flags=re.MULTILINE), '''\ while scanning a simple key test.config", line 7, column 5 could not find expected ':' test.config", line 9, column 1 ''' ) self.assertFalse(os.path.exists(output_path))