def test_apply_command_failed_to_execute_verbose(self, mock_ensure_object): params = { 'commands': [ 'rm test', ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'], } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e', '-v']) self.assertEqual(result.exit_code, 1) self.assertTrue( "rm: cannot remove 'test': No such file or directory\n" in result.output)
def test_apply_raise_errors(self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', ] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e']) self.assertTrue(result.exit_code in [128, 1])
def test_apply_command_failed_to_execute(self, mock_ensure_object): params = { 'commands': [ 'rm test', ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'], } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e']) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Applying {params['commands']} to repos {params['actual_repositories']}\n" f"Executing rm test in {params['actual_repositories'][0]}\n" f"Error: CalledProcessError.Command '['rm', 'test']' returned non-zero exit status 1. " f"occurred when executing command ['rm', 'test'] in gameta\n")
def test_apply_command_to_all_repositories(self, mock_ensure_object): params = { 'commands': ['git fetch --all --tags --prune'], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'] } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, ['--command', params['commands'][0]]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Applying {params['commands']} to repos {params['actual_repositories']}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][0]}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][1]}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][2]}\n" )
def test_apply_command_with_python_interpreter_invalid_python_script( self, mock_ensure_object): params = { 'commands': [ 'from random import choice\n' 'from string import ascii_lowercase, ascii_uppercase, digits, punctuation\n' 'with open("{ENCRYPTION_FILE_NAME}", "w") as f:\n' ' f.write(".join([choice(ascii_lowercase + ascii_uppercase + digits + punctuation) ' # Missing one " 'for _ in range({KEY_LEN})]))', 'from os import getcwd\n' 'from os.path import join, exists\n' 'from shutil import copyfile\n' 'for repo, details in {__repos__}.items():\n' ' if not exists(join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}")):\n' ' copyfile("{ENCRYPTION_FILE_NAME}", join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}"))' ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Error: One of the commands in {params['commands']} is not a valid Python script\n" )
def test_cli_printing_version(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.cli, ["-v"]) self.assertEqual(result.exit_code, 0) self.assertEqual(result.output, f"Gameta version: {__version__}\n")
def test_constants_delete_an_non_existent_constant(self, mock_ensure_object): params = {'name': 'hello'} with self.runner.isolated_filesystem() as f: with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({'constants': {'TEST': "hello_world"}}) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete, ['-n', params['name']]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Deleting constant {params['name']}\n" f"Error: Constant {params['name']} does not exist in .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } }, "constants": { "TEST": "hello_world" } })
def test_constants_add_valid_constant(self, mock_ensure_object): params = {'name': 'test', 'type': 'int', 'value': 1} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.add, [ '-n', params['name'], '-t', params['type'], '-v', params['value'] ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Adding constant {params['name']}\n" f"Successfully added constant {params['name'].upper()}: {params['value']} (type: {params['type']}) " f"to .meta file\n") with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } }, "constants": { "TEST": 1 } })
def test_apply_command_with_python_interpreter_shell_command_passed( self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Error: One of the commands in {params['commands']} is not a valid Python script\n" )
def test_constants_add_constant_with_invalid_type_bool( self, mock_ensure_object): params = {'name': 'test', 'type': 'bool', 'value': 'hello_world'} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.add, [ '-n', params['name'], '-t', params['type'], '-v', params['value'] ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Adding constant {params['name']}\n" f"Error: BadParameter.{params['value']} is not a valid boolean\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } } })
def test_constants_delete_constant_from_empty_meta_file( self, mock_ensure_object): params = {'name': 'hello'} with self.runner.isolated_filesystem() as f: with open(join(f, '.meta'), 'w+') as m: json.dump({}, m) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete, ['-n', params['name']]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Deleting constant {params['name']}\n" f"Error: Constant {params['name']} does not exist in .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual(json.load(m), {})
def test_apply_multiple_commands_to_all_repositories_with_parameter_substitution( self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', 'git checkout {BRANCH}', 'mkdir {$TMP}/{test_dir}', 'cp -r . {$TMP}/{test_dir}' ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'] } tempdir = mkdtemp() with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output['projects']['gameta'].update( {'test_dir': 'test_gameta'}) output['projects']['gitdb'].update( {'test_dir': 'test_gitdb'}) output['projects']['GitPython'].update( {'test_dir': 'test_gitpython'}) output.update({'constants': {'BRANCH': 'master'}}) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() context.env_vars['$TMP'] = tempdir mock_ensure_object.return_value = context output = [ c for repo, c in context.apply(list(params['commands']), shell=True) ] result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--command', params['commands'][2], '--command', params['commands'][3], ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, "Multiple commands detected, executing in a separate shell\n" f"Applying {params['commands']} to repos {params['actual_repositories']} in a separate shell\n" f"Executing {' '.join(output[0])} in {params['actual_repositories'][0]}\n" f"Executing {' '.join(output[1])} in {params['actual_repositories'][1]}\n" f"Executing {' '.join(output[2])} in {params['actual_repositories'][2]}\n" ) self.assertCountEqual( listdir(tempdir), ['test_gitdb', 'test_gitpython', 'test_gameta']) self.assertTrue( all(i in listdir(join(tempdir, 'test_gameta')) for i in ['.git', '.meta', 'GitPython', 'core'])) self.assertTrue( all(i in listdir(join(tempdir, 'test_gitpython')) for i in ['git', 'doc', 'test'])) self.assertTrue( all(i in listdir(join(tempdir, 'test_gitdb')) for i in ['gitdb', 'doc', 'setup.py'])) rmtree(tempdir)
def test_apply_command_with_python_interpreter(self, mock_ensure_object): params = { 'commands': [ 'from random import choice\n' 'from string import ascii_lowercase, ascii_uppercase, digits, punctuation\n' 'with open("{ENCRYPTION_FILE_NAME}", "w") as f:\n' ' f.write("".join([choice(ascii_lowercase + ascii_uppercase + digits + punctuation) ' 'for _ in range({KEY_LEN})]))', 'from os import getcwd\n' 'from os.path import join, exists\n' 'from shutil import copyfile\n' 'for repo, details in {__repos__}.items():\n' ' if not exists(join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}")):\n' ' copyfile("{ENCRYPTION_FILE_NAME}", join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}"))' ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context output = [ c for c in context.apply(params['commands'], python=True) ] result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, "Multiple commands detected, executing in a separate shell\n" f"Applying {params['commands']} to repos {params['actual_repositories']} in a separate shell\n" f"Executing {output[0][1][0]} {output[0][1][1]} {output[0][1][2]} in " f"{params['actual_repositories'][0]}\n") for path in [f, join(f, 'GitPython'), join(f, 'core', 'gitdb')]: self.assertTrue( exists(join(path, params['encryption_file_name']))) with open(join(path, params['encryption_file_name'])) as e: self.assertEqual(len(e.read()), params['key_len'])