def test_version_written(self, *mocks): """ Ensures that version in env is written to the docker config """ docker_mock = mocks[-1] docker_mock.get_config.return_value = ( "FOO=1\nBAR=2\nVERSION=1.0\nDOCKER_IMAGE=foo:dev") utils_mock = mocks[0] utils_mock.get_tag_version.return_value = "0.0.1-test" utils_mock.render.side_effect = lambda x, **kwargs: x command = shlex.split("-e dev deploy") workflow = Workflow(argv=command) workflow.environment.write = mock.Mock() workflow.profile.check = mock.Mock() workflow.run() # make sure the environment write call is made workflow.environment.write.assert_called() # make sure the profile is checked workflow.profile.check.assert_called()
def test_update_version(self, *mocks): """ Ensures that version in env is updated when the publish command is run """ settings_mock = mocks[2] settings_mock.DOCKER_IMAGE_PREFIX = "test.registry" settings_mock.LOGGING = {"version": 1, "loggers": {"compose_flow": {}}} version = "1.2.3" new_version = "0.9.999" docker_image = "foo:bar" utils_mock = mocks[1] utils_mock.get_tag_version.return_value = new_version utils_mock.render = utils.render command = shlex.split("-e dev publish") flow = Workflow(argv=command) publish = flow.subcommand publish.get_built_docker_images = mock.Mock() publish.get_built_docker_images.return_value = [] flow.run() env = flow.environment self.assertEqual(utils_mock.get_tag_version.return_value, env.data["VERSION"]) self.assertEqual(f"test.registry/testdirname:{new_version}", env.data["DOCKER_IMAGE"])
def test_checks_called(self, *mocks): """ Ensure constraint checks are called on deploy """ profile_data_mock = mocks[0] profile_data_mock.return_value = { "services": { "app": { "image": "foo:test" } } } command = shlex.split("-e dev deploy") workflow = Workflow(argv=command) workflow.environment.write = mock.Mock() # mock out all check methods all_checks = Profile.get_all_checks() self.assertEqual(3, len(all_checks), all_checks) for name in all_checks: _check_mock = mock.Mock() _check_mock.return_value = [] setattr(workflow.profile, name, _check_mock) workflow.run() for name in all_checks: _check_mock = getattr(workflow.profile, name) self.assertGreater(_check_mock.call_count, 0, f"{name} not called")
def test_update_version(self, *mocks): """ Ensures that version in env is updated when the publish command is run """ version = '1.2.3' new_version = '0.9.999' docker_image = 'foo:bar' docker_mock = mocks[0] docker_mock.get_config.return_value = ( f"FOO=1\nBAR=2\nVERSION={version}\nDOCKER_IMAGE={docker_image}") utils_mock = mocks[1] utils_mock.get_tag_version.return_value = new_version utils_mock.render = utils.render command = shlex.split('-e dev publish') flow = Workflow(argv=command) publish = flow.subcommand publish.get_built_docker_images = mock.Mock() publish.get_built_docker_images.return_value = [] flow.run() env = flow.environment self.assertEqual(utils_mock.get_tag_version.return_value, env.data['VERSION']) self.assertEqual(f'foo:{new_version}', env.data['DOCKER_IMAGE'])
def test_load_ro(self, *mocks): """ Ensures that env.load does not reset the VERSION var The DOCKER_IMAGE and VERSION vars should only be modified when publishing an image In all other commands, the environment should be read-only """ version = '1.2.3' docker_image = 'foo:bar' docker_mock = mocks[0] docker_mock.get_config.return_value = ( f"FOO=1\nBAR=2\nVERSION={version}\nDOCKER_IMAGE={docker_image}" ) command = shlex.split('-e dev env cat') flow = Workflow(argv=command) flow.run() env = flow.subcommand self.assertEqual(version, env.data['VERSION']) self.assertEqual(docker_image, env.data['DOCKER_IMAGE']) self.assertEqual( ['BAR', 'DOCKER_IMAGE', 'FOO', 'VERSION'], sorted(env._persistable_keys) )
def test_load_runtime(self, *mocks): """ Ensures that runtime variables are able to be viewed/edited without being set """ version = "1.2.3" docker_image = "foo:bar" bar_env_val = "bar" os.environ["BAR"] = bar_env_val get_backend_mock = mocks[0] get_backend_mock.return_value.read.return_value = ( f"FOO={RUNTIME_PLACEHOLDER}\nBAR={RUNTIME_PLACEHOLDER}\n" f"VERSION={version}\nDOCKER_IMAGE={docker_image}" ) command = shlex.split("-e dev env cat") flow = Workflow(argv=command) flow.run() env = flow.subcommand self.assertEqual(RUNTIME_PLACEHOLDER, env.data["FOO"]) self.assertEqual(bar_env_val, env.data["BAR"])
def test_load_ro(self, *mocks): """ Ensures that env.load does not reset the VERSION var The DOCKER_IMAGE and VERSION vars should only be modified when publishing an image In all other commands, the environment should be read-only """ version = "1.2.3" docker_image = "foo:bar" get_backend_mock = mocks[0] get_backend_mock.return_value.read.return_value = ( f"FOO=1\nBAR=2\nVERSION={version}\nDOCKER_IMAGE={docker_image}" ) command = shlex.split("-e dev env cat") flow = Workflow(argv=command) flow.run() env = flow.subcommand self.assertEqual(version, env.data["VERSION"]) self.assertEqual(docker_image, env.data["DOCKER_IMAGE"]) self.assertEqual( ["BAR", "DOCKER_IMAGE", "FOO", "VERSION"], sorted(env._persistable_keys) )
def test_rancher_no_namespaces_defined(self, *mocks): """ Ensures that Rancher namespaces are not created when none are defined """ command = shlex.split("-e dev deploy rancher") workflow = Workflow(argv=command) workflow.environment.write = mock.Mock() workflow.profile.check = mock.Mock() workflow.run() # make sure the new namespace is created mock_create_ns = mocks[0] mock_create_ns.assert_not_called()
def test_rancher_namespace_created(self, *mocks): """ Ensures that Rancher namespaces are created when they do not exist """ command = shlex.split("-e dev deploy rancher") workflow = Workflow(argv=command) workflow.environment.write = mock.Mock() workflow.profile.check = mock.Mock() workflow.run() # make sure the new namespace is created mock_create_ns = mocks[0] mock_create_ns.assert_called_once_with("my-namespace", False)
def test_version(self, *mocks): """ Ensure the --version arg just returns the version """ version = "0.0.0-test" pkg_resources_mock = mocks[0] pkg_resources_mock.require.return_value = [mock.Mock(version=version)] command = shlex.split("--version") workflow = Workflow(argv=command) workflow.run() print_mock = mocks[1] print_mock.assert_called_with(version)
def test_rancher_url_manifest(self, *mocks): """ Ensure that manifests can be deployed to Rancher from external URLs """ command = shlex.split("-e dev deploy rancher") workflow = Workflow(argv=command) workflow.environment.write = mock.Mock() workflow.profile.check = mock.Mock() workflow.run() command = mocks[0].call_args[0][0] # make sure the command contains the manifest URL self.assertTrue(MANIFEST_URL in command)
def test_exec_pod_without_specified_container(self, *mocks): """ Test that the command works when no container is specified """ argv = shlex.split("-e test pod exec generic-workers /bin/bash") workflow = Workflow(argv=argv) pod = workflow.subcommand pod.list_pods = mock.MagicMock() pod.list_pods.return_value = self._get_mock_pod_list_raw() workflow.run() target_command = f"rancher kubectl -n {workflow.project_name} exec -it generic-workers-6c744b8fb8-7sjb8 -- /bin/bash" self.assertEqual(target_command, mocks[1].call_args[0][0])
def test_e2e_happy_path_publish_with_auto_tags(self, *mocks): new_version = "3.5.9" utils_mock = mocks[1] utils_mock.get_tag_version.return_value = new_version utils_mock.render = utils.render command = shlex.split("-e prod publish --tag-major-minor") flow = Workflow(argv=command) publish = flow.subcommand execute_mock = mock.MagicMock() publish.execute = execute_mock flow.run() target_executions = [ ("docker push localhost.localdomain/testdirname:3.5.9", { "_fg": True }), ( "docker tag localhost.localdomain/testdirname:3.5.9 localhost.localdomain/testdirname:3", {}, ), ("docker push localhost.localdomain/testdirname:3", { "_fg": True }), ( "docker tag localhost.localdomain/testdirname:3.5.9 localhost.localdomain/testdirname:3.5", {}, ), ("docker push localhost.localdomain/testdirname:3.5", { "_fg": True }), ] call_target_tuples = list( zip(execute_mock.call_args_list, target_executions)) self.assertEqual(len(target_executions), len(call_target_tuples)) for call, target_call in zip(execute_mock.call_args_list, target_executions): args, kwargs = call target_args, target_kwargs = target_call self.assertEqual((target_args, ), args) self.assertEqual(target_kwargs, kwargs)
def test_exec_pod_with_specified_namespace(self, *mocks): """ Test that we can override the namespace with --namespace. """ argv = shlex.split( "-e test pod exec --namespace foobar generic-workers /bin/bash") workflow = Workflow(argv=argv) pod = workflow.subcommand pod.list_pods = mock.MagicMock() pod.list_pods.return_value = self._get_mock_pod_list_raw() workflow.run() target_command = "rancher kubectl -n foobar exec -it generic-workers-6c744b8fb8-7sjb8 -- /bin/bash" self.assertEqual(target_command, mocks[1].call_args[0][0])
def test_profile_env(self, *mocks): """ Ensure the VERSION is updated """ utils_mock = mocks[1] utils_mock.get_tag_version.return_value = "0.0.1" utils_mock.render = utils.render command = shlex.split("-e dev publish") flow = Workflow(argv=command) flow.subcommand.build = mock.Mock() flow.subcommand.push = mock.Mock() flow.run() env_data = flow.environment.data self.assertEqual(True, "VERSION" in env_data)
def test_publish_with_missing_env_vars(self, *mocks): command = shlex.split('publish') flow = Workflow(argv=command) flow.subcommand.build = mock.Mock() flow.subcommand.check = mock.Mock() flow.subcommand.push = mock.Mock() with mock.patch( 'compose_flow.commands.workflow.Workflow.profile', new_callable=mock.PropertyMock, ) as profile_mock: flow.run() profile_mock.return_value.write.assert_called_with() flow.subcommand.push.assert_called() # make sure check is not called flow.subcommand.check.assert_not_called()
def test_exec_pod_with_specified_container_and_index(self, *mocks): """ Basic test to ensure the command runs as expected """ argv = shlex.split( "-e test pod exec generic-workers --container generic-workers -i 2 /bin/bash" ) workflow = Workflow(argv=argv) pod = workflow.subcommand pod.list_pods = mock.MagicMock() pod.list_pods.return_value = self._get_mock_pod_list_raw() workflow.run() target_command = ( f"rancher kubectl -n {workflow.project_name} exec -it generic-workers-6c744b8fb8-c66gl " "--container generic-workers -- /bin/bash") self.assertEqual(target_command, mocks[1].call_args[0][0])
def test_profile_env(self, *mocks): """ Ensure the VERSION is updated """ docker_mock = mocks[0] docker_mock.get_config.return_value = "FOO=1\nBAR=2" utils_mock = mocks[1] utils_mock.get_tag_version.return_value = '0.0.1' utils_mock.render = utils.render command = shlex.split('-e dev publish') flow = Workflow(argv=command) flow.subcommand.build = mock.Mock() flow.subcommand.push = mock.Mock() flow.run() env_data = flow.environment.data self.assertEqual(True, 'VERSION' in env_data)
def test_runs(self, *mocks): """ Basic test to ensure the command runs as expected """ argv = shlex.split('-e test service exec app /bin/bash') workflow = Workflow(argv=argv) service = workflow.subcommand service.select_container = mock.MagicMock() service.select_container.return_value = ( 'container_id service_name something test_hostname') workflow.run() ssh_mock = self.sh_mock.ssh ssh_args = ssh_mock.mock_calls[0][1] args_s = ' '.join(ssh_args) command_re = re.compile( r'docker exec .* service_name\.container_id /bin/bash') self.assertEqual(True, command_re.search(args_s) is not None)