class TestSetupChronosJob: fake_docker_image = 'test_docker:1.0' fake_client = mock.MagicMock() fake_service = 'test_service' fake_instance = 'test' fake_cluster = 'fake_test_cluster' fake_config_dict = { 'name': 'test_service test gitsha config', 'description': 'This is a test Chronos job.', 'command': '/bin/sleep 40', 'bounce_method': 'graceful', 'epsilon': 'PT30M', 'retries': 5, 'owner': '*****@*****.**', 'async': False, 'cpus': 5.5, 'mem': 1024.4, 'disk': 2048.5, 'disabled': 'true', 'schedule': 'R/2015-03-25T19:36:35Z/PT5M', 'schedule_time_zone': 'Zulu', } fake_branch_dict = { 'docker_image': f'paasta-{fake_service}-{fake_cluster}', 'git_sha': 'fake_sha', 'force_bounce': None, 'desired_state': 'start', } fake_chronos_job_config = chronos_tools.ChronosJobConfig( service=fake_service, cluster=fake_cluster, instance=fake_instance, config_dict=fake_config_dict, branch_dict=fake_branch_dict, ) fake_docker_registry = 'remote_registry.com' fake_args = mock.MagicMock( service_instance=compose_job_id(fake_service, fake_instance), soa_dir='no_more', verbose=False, ) def test_config_with_historical_stats(self): with mock.patch( 'paasta_tools.setup_chronos_job.chronos_tools.lookup_chronos_jobs', autospec=True, ) as mock_lookup_chronos_jobs: ret = [{ 'lastSuccess': '2017-04-01T00:00:00Z', 'lastError': '2017-04-02T00:00:00Z', 'successCount': 1, 'errorCount': 1, }] mock_lookup_chronos_jobs.return_value = ret init_config = { 'name': 'foo bar', } expected_merge = { 'name': 'foo bar', 'lastSuccess': '2017-04-01T00:00:00Z', 'lastError': '2017-04-02T00:00:00Z', 'successCount': 1, 'errorCount': 1, } actual = setup_chronos_job.config_with_historical_stats( chronos_client=mock.Mock(), service='foo', instance='bar', job_config=init_config, ) assert actual == expected_merge def test_config_with_historical_stats_no_existing(self): with mock.patch( 'paasta_tools.setup_chronos_job.chronos_tools.lookup_chronos_jobs', autospec=True, ) as mock_lookup_chronos_jobs: ret = [] mock_lookup_chronos_jobs.return_value = ret init_config = { 'name': 'foo bar', } expected_merge = { 'name': 'foo bar', } actual = setup_chronos_job.config_with_historical_stats( chronos_client=mock.Mock(), service='foo', instance='bar', job_config=init_config, ) assert actual == expected_merge def test_main_success(self): expected_status = 0 expected_output = 'it_is_finished' fake_complete_job_config = {'foo': 'bar'} with mock.patch( 'paasta_tools.setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True, ) as parse_args_patch, mock.patch( 'paasta_tools.chronos_tools.load_chronos_config', autospec=True, ) as load_chronos_config_patch, mock.patch( 'paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True, ) as get_client_patch, mock.patch( 'paasta_tools.chronos_tools.create_complete_config', return_value=fake_complete_job_config, autospec=True, ), mock.patch( 'paasta_tools.setup_chronos_job.setup_job', return_value=(expected_status, expected_output), autospec=True, ) as setup_job_patch, mock.patch( 'paasta_tools.setup_chronos_job.send_event', autospec=True, ) as send_event_patch, mock.patch( 'paasta_tools.setup_chronos_job.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'sys.exit', autospec=True, ) as sys_exit_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) setup_chronos_job.main() parse_args_patch.assert_called_once_with() get_client_patch.assert_called_once_with( load_chronos_config_patch.return_value) setup_job_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, complete_job_config=fake_complete_job_config, client=self.fake_client, cluster=self.fake_cluster, ) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=expected_status, output=expected_output, ) sys_exit_patch.assert_called_once_with(0) def test_main_no_deployments(self): with mock.patch( 'paasta_tools.setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.load_chronos_config', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.create_complete_config', return_value={}, autospec=True, side_effect=NoDeploymentsAvailable, ), mock.patch( 'paasta_tools.setup_chronos_job.setup_job', return_value=(0, 'it_is_finished'), autospec=True, ), mock.patch( 'paasta_tools.setup_chronos_job.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.setup_chronos_job.send_event', autospec=True, ): load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 def test_main_bad_chronos_job_config_notifies_user(self): with mock.patch( 'paasta_tools.setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.load_chronos_config', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.create_complete_config', autospec=True, side_effect=NoConfigurationForServiceError( 'test bad configuration'), ), mock.patch( 'paasta_tools.setup_chronos_job.setup_job', return_value=(0, 'it_is_finished'), autospec=True, ), mock.patch( 'paasta_tools.setup_chronos_job.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.setup_chronos_job.send_event', autospec=True, ) as send_event_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 expected_error_msg = ( "Could not read chronos configuration file for %s in cluster %s\nError was: test bad configuration" % (compose_job_id(self.fake_service, self.fake_instance), self.fake_cluster)) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=Status.CRITICAL, output=expected_error_msg, ) def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with mock.patch( 'paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok'), ) as mock_bounce_chronos_job, mock.patch( 'paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=fake_existing_jobs, ), mock.patch( 'paasta_tools.utils.load_system_paasta_config', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = None load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = \ 'file:///root/.dockercfg' complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value def test_setup_job_with_previously_enabled_job(self): fake_existing_job = { 'name': 'fake_job', 'disabled': False, } with mock.patch( 'paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok'), ) as mock_bounce_chronos_job, mock.patch( 'paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True, ) as mock_lookup_chronos_jobs, mock.patch( 'paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job], ), mock.patch( 'paasta_tools.utils.load_system_paasta_config', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = None load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = \ "file:///root/.dockercfg" complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_setup_job_does_nothing_with_only_existing_app(self): fake_existing_job = copy.deepcopy(self.fake_config_dict) with mock.patch( 'paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok'), ) as mock_bounce_chronos_job, mock.patch( 'paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True, return_value=[fake_existing_job], ) as mock_lookup_chronos_jobs, mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = copy.deepcopy(self.fake_config_dict) # Force the complete_config's name to match the return value of # lookup_chronos_jobs to simulate that they have the same name complete_config["name"] = fake_existing_job["name"] actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=None, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_send_event(self): fake_status = '42' fake_output = 'something went wrong' fake_soa_dir = '' expected_check_name = 'setup_chronos_job.%s' % compose_job_id( self.fake_service, self.fake_instance) with mock.patch( "paasta_tools.monitoring_tools.send_event", autospec=True, ) as mock_send_event, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, ) as mock_load_chronos_job_config, mock.patch( "paasta_tools.setup_chronos_job.load_system_paasta_config", autospec=True, ) as mock_load_system_paasta_config: mock_load_system_paasta_config.return_value.get_cluster = mock.Mock( return_value='fake_cluster') mock_load_chronos_job_config.return_value.get_monitoring.return_value = {} setup_chronos_job.send_event( service=self.fake_service, instance=self.fake_instance, soa_dir=fake_soa_dir, status=fake_status, output=fake_output, ) mock_send_event.assert_called_once_with( service=self.fake_service, check_name=expected_check_name, overrides={ 'alert_after': '10m', 'check_every': '10s' }, status=fake_status, output=fake_output, soa_dir=fake_soa_dir, ) mock_load_chronos_job_config.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=mock_load_system_paasta_config.return_value. get_cluster.return_value, soa_dir=fake_soa_dir, load_deployments=False, ) def test_bounce_chronos_job_takes_actions(self): fake_job_to_update = {'name': 'job_to_update'} with mock.patch( "paasta_tools.setup_chronos_job._log", autospec=True, ) as mock_log, mock.patch( "paasta_tools.chronos_tools.update_job", autospec=True, ) as mock_update_job: setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=fake_job_to_update, client=self.fake_client, ) mock_log.assert_any_call( line=mock.ANY, level='debug', instance=self.fake_instance, cluster=self.fake_cluster, component='deploy', service=self.fake_service, ) mock_log.assert_any_call( line="Updated Chronos job: job_to_update", level='event', instance=self.fake_instance, cluster=self.fake_cluster, component='deploy', service=self.fake_service, ) mock_update_job.assert_called_once_with(job=fake_job_to_update, client=self.fake_client) def test_bounce_chronos_job_doesnt_log_when_nothing_to_do(self): with mock.patch( "paasta_tools.setup_chronos_job._log", autospec=True, ) as mock_log, mock.patch( "paasta_tools.chronos_tools.update_job", autospec=True, ) as mock_update_job: setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=None, client=self.fake_client, ) assert not mock_log.called assert not mock_update_job.called
class TestMonitoring_Tools: general_page = True fake_general_service_config = { 'team': 'general_test_team', 'runbook': 'y/general_test_runbook', 'tip': 'general_test_tip', 'notification_email': 'general_test_notification_email', 'page': general_page } empty_service_config = marathon_tools.MarathonServiceConfig( service='myservicename', cluster='mycluster', instance='myinstance', config_dict={}, branch_dict={}, ) job_page = False fake_marathon_job_config = marathon_tools.MarathonServiceConfig( service='myservicename', cluster='myclustername', instance='myinstance', config_dict={ 'team': 'job_test_team', 'runbook': 'y/job_test_runbook', 'tip': 'job_test_tip', 'notification_email': 'job_test_notification_email', 'page': job_page }, branch_dict={}, ) fake_chronos_job_config = chronos_tools.ChronosJobConfig( service='myservicename', cluster='myclustername', instance='myinstance', config_dict={ 'team': 'job_test_team', 'runbook': 'y/job_test_runbook', 'tip': 'job_test_tip', 'notification_email': 'job_test_notification_email', 'page': job_page }, branch_dict={}, ) empty_job_config = {} monitor_page = True fake_monitor_config = { 'team': 'monitor_test_team', 'runbook': 'y/monitor_test_runbook', 'tip': 'monitor_test_tip', 'notification_email': 'monitor_test_notification_email', 'page': monitor_page } empty_monitor_config = {} framework = 'fake_framework' overrides = {} instance = 'fake_instance' service = 'fake_service' soa_dir = '/fake/soa/dir' def test_get_team(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'team', self.overrides, self.service, self.soa_dir) def test_get_runbook(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_runbook(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'runbook', self.overrides, self.service, self.soa_dir) def test_get_tip(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_tip(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'tip', self.overrides, self.service, self.soa_dir) def test_get_notification_email(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_notification_email(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'notification_email', self.overrides, self.service, self.soa_dir) def test_get_page(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_page(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'page', self.overrides, self.service, self.soa_dir) def test_get_alert_after(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_alert_after(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'alert_after', self.overrides, self.service, self.soa_dir) def test_get_realert_every(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_realert_every(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'realert_every', self.overrides, self.service, self.soa_dir) def test_get_check_every(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_check_every(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'check_every', self.overrides, self.service, self.soa_dir) def test_get_irc_channels(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_irc_channels(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'irc_channels', self.overrides, self.service, self.soa_dir) def test_get_dependencies(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_dependencies(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'dependencies', self.overrides, self.service, self.soa_dir) def test_get_ticket(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_ticket(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'ticket', self.overrides, self.service, self.soa_dir) def test_get_project(self): with mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_project(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( 'project', self.overrides, self.service, self.soa_dir) def test_get_monitoring_config_value_with_monitor_config(self): expected = 'monitor_test_team' with contextlib.nested( mock.patch( 'service_configuration_lib.read_service_configuration', autospec=True, return_value=self.fake_general_service_config), mock.patch( 'paasta_tools.monitoring_tools.read_monitoring_config', autospec=True, return_value=self.fake_monitor_config), mock.patch( 'paasta_tools.monitoring_tools.load_system_paasta_config', autospec=True), ) as ( service_configuration_lib_patch, read_monitoring_patch, load_system_paasta_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value='fake_cluster') actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_get_monitoring_config_value_with_service_config(self): expected = 'general_test_team' with contextlib.nested( mock.patch( 'service_configuration_lib.read_service_configuration', autospec=True, return_value=self.fake_general_service_config), mock.patch( 'paasta_tools.monitoring_tools.read_monitoring_config', autospec=True, return_value=self.empty_monitor_config), mock.patch( 'paasta_tools.monitoring_tools.load_system_paasta_config', autospec=True), ) as ( service_configuration_lib_patch, read_monitoring_patch, load_system_paasta_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value='fake_cluster') actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_get_monitoring_config_value_with_defaults(self): expected = None with contextlib.nested( mock.patch( 'service_configuration_lib.read_service_configuration', autospec=True, return_value=self.empty_job_config), mock.patch( 'paasta_tools.monitoring_tools.read_monitoring_config', autospec=True, return_value=self.empty_monitor_config), mock.patch( 'paasta_tools.monitoring_tools.load_system_paasta_config', autospec=True), ) as ( service_configuration_lib_patch, read_monitoring_patch, load_system_paasta_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value='fake_cluster') actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_get_team_email_address_uses_override_if_specified(self): fake_email = 'fake_email' with contextlib.nested( mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True), ) as (mock_get_monitoring_config_value, ): mock_get_monitoring_config_value.return_value = 'fake_email' actual = monitoring_tools.get_team_email_address( 'fake_service', {'notification_email': fake_email}) assert actual == fake_email def test_get_team_email_address_uses_instance_config_if_specified(self): expected = 'fake_email' with contextlib.nested( mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True), ) as (mock_get_monitoring_config_value, ): mock_get_monitoring_config_value.return_value = 'fake_email' actual = monitoring_tools.get_team_email_address('fake_service') assert actual == expected def test_get_team_email_address_uses_team_data_as_last_resort(self): expected = 'team_data_email' with contextlib.nested( mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True), mock.patch('paasta_tools.monitoring_tools.get_sensu_team_data', autospec=True), mock.patch('paasta_tools.monitoring_tools.get_team', autospec=True), ) as ( mock_get_monitoring_config_value, mock_get_sensu_team_data, mock_get_team, ): mock_get_team.return_value = 'test_team' mock_get_monitoring_config_value.return_value = False mock_get_sensu_team_data.return_value = { 'notification_email': expected } actual = monitoring_tools.get_team_email_address('fake_service') assert actual == expected def test_get_team_email_address_returns_none_if_not_available(self): with contextlib.nested( mock.patch( 'paasta_tools.monitoring_tools.__get_monitoring_config_value', autospec=True), mock.patch('paasta_tools.monitoring_tools.get_sensu_team_data', autospec=True), mock.patch('paasta_tools.monitoring_tools.get_team', autospec=True), ) as ( mock_get_monitoring_config_value, mock_get_sensu_team_data, mock_get_team, ): mock_get_team.return_value = 'test_team' mock_get_monitoring_config_value.return_value = False mock_get_sensu_team_data.return_value = {} actual = monitoring_tools.get_team_email_address('fake_service') assert actual is None def test_send_event(self): fake_service = 'fake_service' fake_monitoring_overrides = {} fake_check_name = 'fake_check_name' fake_status = '42' fake_output = 'The http port is not open' fake_team = 'fake_team' fake_tip = 'fake_tip' fake_notification_email = 'fake@notify' fake_irc = '#fake' fake_soa_dir = '/fake/soa/dir' self.fake_cluster = 'fake_cluster' fake_sensu_host = 'fake_sensu_host' fake_sensu_port = 12345 expected_runbook = 'http://y/paasta-troubleshooting' expected_check_name = fake_check_name expected_kwargs = { 'tip': fake_tip, 'notification_email': fake_notification_email, 'irc_channels': fake_irc, 'project': None, 'ticket': False, 'page': True, 'alert_after': '5m', 'check_every': '1m', 'realert_every': -1, 'source': 'paasta-fake_cluster', 'ttl': None, } with contextlib.nested( mock.patch( "paasta_tools.monitoring_tools.get_team", return_value=fake_team, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_tip", return_value=fake_tip, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_notification_email", return_value=fake_notification_email, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_irc_channels", return_value=fake_irc, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_ticket", return_value=False, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_project", return_value=None, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_page", return_value=True, autospec=True, ), mock.patch("pysensu_yelp.send_event", autospec=True), mock.patch( 'paasta_tools.monitoring_tools.load_system_paasta_config', autospec=True), ) as ( get_team_patch, get_tip_patch, get_notification_email_patch, get_irc_patch, get_ticket_patch, get_project_patch, get_page_patch, pysensu_yelp_send_event_patch, load_system_paasta_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value=self.fake_cluster) load_system_paasta_config_patch.return_value.get_sensu_host = mock.Mock( return_value=fake_sensu_host) load_system_paasta_config_patch.return_value.get_sensu_port = mock.Mock( return_value=fake_sensu_port) monitoring_tools.send_event(fake_service, fake_check_name, fake_monitoring_overrides, fake_status, fake_output, fake_soa_dir) get_team_patch.assert_called_once_with( fake_monitoring_overrides, fake_service, fake_soa_dir, ) get_tip_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_notification_email_patch.assert_called_once_with( fake_monitoring_overrides, fake_service, fake_soa_dir) get_irc_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_page_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) pysensu_yelp_send_event_patch.assert_called_once_with( expected_check_name, expected_runbook, fake_status, fake_output, fake_team, sensu_host=fake_sensu_host, sensu_port=fake_sensu_port, **expected_kwargs) load_system_paasta_config_patch.return_value.get_cluster.assert_called_once_with( ) def test_send_event_sensu_host_is_None(self): fake_service = 'fake_service' fake_monitoring_overrides = {} fake_check_name = 'fake_check_name' fake_status = '42' fake_output = 'The http port is not open' fake_soa_dir = '/fake/soa/dir' self.fake_cluster = 'fake_cluster' fake_sensu_port = 12345 with contextlib.nested( mock.patch("paasta_tools.monitoring_tools.get_team", autospec=True), mock.patch("paasta_tools.monitoring_tools.get_tip", autospec=True), mock.patch( "paasta_tools.monitoring_tools.get_notification_email", autospec=True), mock.patch("paasta_tools.monitoring_tools.get_irc_channels", autospec=True), mock.patch("paasta_tools.monitoring_tools.get_ticket", autospec=True), mock.patch("paasta_tools.monitoring_tools.get_project", autospec=True), mock.patch("paasta_tools.monitoring_tools.get_page", autospec=True), mock.patch("pysensu_yelp.send_event", autospec=True), mock.patch( 'paasta_tools.monitoring_tools.load_system_paasta_config', autospec=True), ) as ( get_team_patch, get_tip_patch, get_notification_email_patch, get_irc_patch, get_ticket_patch, get_project_patch, get_page_patch, pysensu_yelp_send_event_patch, load_system_paasta_config_patch, ): load_system_paasta_config_patch.return_value.get_sensu_host = mock.Mock( return_value=None) load_system_paasta_config_patch.return_value.get_sensu_port = mock.Mock( return_value=fake_sensu_port) monitoring_tools.send_event(fake_service, fake_check_name, fake_monitoring_overrides, fake_status, fake_output, fake_soa_dir) assert pysensu_yelp_send_event_patch.call_count == 0 def test_read_monitoring_config(self): fake_name = 'partial' fake_fname = 'acronyms' fake_path = 'ever_patched' fake_soa_dir = '/nail/cte/oas' fake_dict = {'e': 'quail', 'v': 'snail'} with contextlib.nested( mock.patch('os.path.abspath', autospec=True, return_value=fake_path), mock.patch('os.path.join', autospec=True, return_value=fake_fname), mock.patch('service_configuration_lib.read_monitoring', autospec=True, return_value=fake_dict)) as (abspath_patch, join_patch, read_monitoring_patch): actual = monitoring_tools.read_monitoring_config( fake_name, fake_soa_dir) assert fake_dict == actual abspath_patch.assert_called_once_with(fake_soa_dir) join_patch.assert_called_once_with(fake_path, fake_name, 'monitoring.yaml') read_monitoring_patch.assert_called_once_with(fake_fname)
import sys from behave import when, then sys.path.append('../') from paasta_tools import setup_chronos_job from paasta_tools import chronos_tools fake_service_name = 'test-service' fake_instance_name = 'test-instance' fake_job_id = 'fake_job_id' fake_service_job_config = chronos_tools.ChronosJobConfig( fake_service_name, fake_instance_name, {}, { 'docker_image': 'test-image', 'desired_state': 'start' }, ) # TODO DRY out in PAASTA-1174 fake_service_config = { "retries": 1, "container": { "image": "localhost/fake_docker_url", "type": "DOCKER", "network": "BRIDGE",
class TestSetupChronosJob: @pytest.fixture(autouse=True) def mock_read_monitoring_config(self): with mock.patch( "paasta_tools.utils.get_pipeline_deploy_groups", mock.Mock(return_value=["fake_deploy_group"]), autospec=None, ) as f: yield f fake_docker_image = "test_docker:1.0" fake_client = mock.MagicMock() fake_service = "test_service" fake_instance = "test" fake_cluster = "fake_test_cluster" fake_config_dict = { "name": "test_service test gitsha config", "description": "This is a test Chronos job.", "command": "/bin/sleep 40", "bounce_method": "graceful", "epsilon": "PT30M", "retries": 5, "owner": "*****@*****.**", "async": False, "cpus": 5.5, "mem": 1024.4, "disk": 2048.5, "disabled": "true", "schedule": "R/2015-03-25T19:36:35Z/PT5M", "schedule_time_zone": "Zulu", "deploy_group": "fake_deploy_group", } fake_branch_dict = { "docker_image": f"paasta-{fake_service}-{fake_cluster}", "git_sha": "fake_sha", "force_bounce": None, "desired_state": "start", } fake_chronos_job_config = chronos_tools.ChronosJobConfig( service=fake_service, cluster=fake_cluster, instance=fake_instance, config_dict=fake_config_dict, branch_dict=fake_branch_dict, ) fake_docker_registry = "remote_registry.com" fake_args = mock.MagicMock( service_instance=compose_job_id(fake_service, fake_instance), soa_dir="no_more", verbose=False, ) def test_config_with_historical_stats(self): with mock.patch( "paasta_tools.setup_chronos_job.chronos_tools.lookup_chronos_jobs", autospec=True, ) as mock_lookup_chronos_jobs: ret = [{ "lastSuccess": "2017-04-01T00:00:00Z", "lastError": "2017-04-02T00:00:00Z", "successCount": 1, "errorCount": 1, }] mock_lookup_chronos_jobs.return_value = ret init_config = {"name": "foo bar"} expected_merge = { "name": "foo bar", "lastSuccess": "2017-04-01T00:00:00Z", "lastError": "2017-04-02T00:00:00Z", "successCount": 1, "errorCount": 1, } actual = setup_chronos_job.config_with_historical_stats( chronos_client=mock.Mock(), service="foo", instance="bar", job_config=init_config, ) assert actual == expected_merge def test_config_with_historical_stats_no_existing(self): with mock.patch( "paasta_tools.setup_chronos_job.chronos_tools.lookup_chronos_jobs", autospec=True, ) as mock_lookup_chronos_jobs: ret = [] mock_lookup_chronos_jobs.return_value = ret init_config = {"name": "foo bar"} expected_merge = {"name": "foo bar"} actual = setup_chronos_job.config_with_historical_stats( chronos_client=mock.Mock(), service="foo", instance="bar", job_config=init_config, ) assert actual == expected_merge def test_main_success(self): expected_status = 0 expected_output = "it_is_finished" fake_complete_job_config = {"foo": "bar"} with mock.patch( "paasta_tools.setup_chronos_job.parse_args", return_value=self.fake_args, autospec=True, ) as parse_args_patch, mock.patch( "paasta_tools.chronos_tools.load_chronos_config", autospec=True ) as load_chronos_config_patch, mock.patch( "paasta_tools.chronos_tools.get_chronos_client", return_value=self.fake_client, autospec=True, ) as get_client_patch, mock.patch( "paasta_tools.chronos_tools.create_complete_config", return_value=fake_complete_job_config, autospec=True, ), mock.patch( "paasta_tools.setup_chronos_job.setup_job", return_value=(expected_status, expected_output), autospec=True, ) as setup_job_patch, mock.patch( "paasta_tools.setup_chronos_job.send_event", autospec=True ) as send_event_patch, mock.patch( "paasta_tools.setup_chronos_job.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch, mock.patch( "sys.exit", autospec=True) as sys_exit_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) setup_chronos_job.main() parse_args_patch.assert_called_once_with() get_client_patch.assert_called_once_with( load_chronos_config_patch.return_value) setup_job_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, complete_job_config=fake_complete_job_config, client=self.fake_client, cluster=self.fake_cluster, ) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=expected_status, output=expected_output, ) sys_exit_patch.assert_called_once_with(0) def test_main_no_deployments(self): with mock.patch( "paasta_tools.setup_chronos_job.parse_args", return_value=self.fake_args, autospec=True, ), mock.patch( "paasta_tools.chronos_tools.load_chronos_config", autospec=True ), mock.patch( "paasta_tools.chronos_tools.get_chronos_client", return_value=self.fake_client, autospec=True, ), mock.patch( "paasta_tools.chronos_tools.create_complete_config", return_value={}, autospec=True, side_effect=NoDeploymentsAvailable, ), mock.patch( "paasta_tools.setup_chronos_job.setup_job", return_value=(0, "it_is_finished"), autospec=True, ), mock.patch( "paasta_tools.setup_chronos_job.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch, mock.patch( "paasta_tools.setup_chronos_job.send_event", autospec=True): load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 def test_main_bad_chronos_job_config_notifies_user(self): with mock.patch( "paasta_tools.setup_chronos_job.parse_args", return_value=self.fake_args, autospec=True, ), mock.patch( "paasta_tools.chronos_tools.load_chronos_config", autospec=True ), mock.patch( "paasta_tools.chronos_tools.get_chronos_client", return_value=self.fake_client, autospec=True, ), mock.patch( "paasta_tools.chronos_tools.create_complete_config", autospec=True, side_effect=NoConfigurationForServiceError( "test bad configuration"), ), mock.patch( "paasta_tools.setup_chronos_job.setup_job", return_value=(0, "it_is_finished"), autospec=True, ), mock.patch( "paasta_tools.setup_chronos_job.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch, mock.patch( "paasta_tools.setup_chronos_job.send_event", autospec=True) as send_event_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 expected_error_msg = ( "Could not read chronos configuration file for %s in cluster %s\nError was: test bad configuration" % ( compose_job_id(self.fake_service, self.fake_instance), self.fake_cluster, )) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=Status.CRITICAL, output=expected_error_msg, ) def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with mock.patch( "paasta_tools.setup_chronos_job.bounce_chronos_job", autospec=True, return_value=(0, "ok"), ) as mock_bounce_chronos_job, mock.patch( "paasta_tools.chronos_tools.lookup_chronos_jobs", autospec=True), mock.patch( "paasta_tools.chronos_tools.sort_jobs", autospec=True, return_value=fake_existing_jobs, ), mock.patch( "paasta_tools.utils.load_system_paasta_config", autospec=True), mock.patch( "paasta_tools.chronos_tools.load_system_paasta_config", autospec=True ) as load_system_paasta_config_patch, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = ( self.fake_cluster) load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = ( None) load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = ( "file:///root/.dockercfg") complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value def test_setup_job_with_previously_enabled_job(self): fake_existing_job = {"name": "fake_job", "disabled": False} with mock.patch( "paasta_tools.setup_chronos_job.bounce_chronos_job", autospec=True, return_value=(0, "ok"), ) as mock_bounce_chronos_job, mock.patch( "paasta_tools.chronos_tools.lookup_chronos_jobs", autospec=True) as mock_lookup_chronos_jobs, mock.patch( "paasta_tools.chronos_tools.sort_jobs", autospec=True, return_value=[fake_existing_job], ), mock.patch( "paasta_tools.utils.load_system_paasta_config", autospec=True), mock.patch( "paasta_tools.chronos_tools.load_system_paasta_config", autospec=True ) as load_system_paasta_config_patch, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = ( self.fake_cluster) load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = ( None) load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = ( "file:///root/.dockercfg") complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_setup_job_does_nothing_with_only_existing_app(self): fake_existing_job = copy.deepcopy(self.fake_config_dict) with mock.patch( "paasta_tools.setup_chronos_job.bounce_chronos_job", autospec=True, return_value=(0, "ok"), ) as mock_bounce_chronos_job, mock.patch( "paasta_tools.chronos_tools.lookup_chronos_jobs", autospec=True, return_value=[fake_existing_job], ) as mock_lookup_chronos_jobs, mock.patch( "paasta_tools.chronos_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = ( self.fake_cluster) complete_config = copy.deepcopy(self.fake_config_dict) # Force the complete_config's name to match the return value of # lookup_chronos_jobs to simulate that they have the same name complete_config["name"] = fake_existing_job["name"] actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=None, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_send_event(self): fake_status = "42" fake_output = "something went wrong" fake_soa_dir = "" expected_check_name = "setup_chronos_job.%s" % compose_job_id( self.fake_service, self.fake_instance) with mock.patch( "paasta_tools.monitoring_tools.send_event", autospec=True ) as mock_send_event, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True) as mock_load_chronos_job_config, mock.patch( "paasta_tools.setup_chronos_job.load_system_paasta_config", autospec=True) as mock_load_system_paasta_config: mock_load_system_paasta_config.return_value.get_cluster = mock.Mock( return_value="fake_cluster") mock_load_chronos_job_config.return_value.get_monitoring.return_value = {} setup_chronos_job.send_event( service=self.fake_service, instance=self.fake_instance, soa_dir=fake_soa_dir, status=fake_status, output=fake_output, ) mock_send_event.assert_called_once_with( service=self.fake_service, check_name=expected_check_name, overrides={ "alert_after": "10m", "check_every": "10s" }, status=fake_status, output=fake_output, soa_dir=fake_soa_dir, ) mock_load_chronos_job_config.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=mock_load_system_paasta_config.return_value. get_cluster.return_value, soa_dir=fake_soa_dir, load_deployments=False, ) def test_bounce_chronos_job_takes_actions(self): fake_job_to_update = {"name": "job_to_update"} with mock.patch("paasta_tools.setup_chronos_job._log", autospec=True) as mock_log, mock.patch( "paasta_tools.chronos_tools.update_job", autospec=True) as mock_update_job: setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=fake_job_to_update, client=self.fake_client, ) mock_log.assert_any_call( line=mock.ANY, level="debug", instance=self.fake_instance, cluster=self.fake_cluster, component="deploy", service=self.fake_service, ) mock_log.assert_any_call( line="Updated Chronos job: job_to_update", level="event", instance=self.fake_instance, cluster=self.fake_cluster, component="deploy", service=self.fake_service, ) mock_update_job.assert_called_once_with(job=fake_job_to_update, client=self.fake_client) def test_bounce_chronos_job_doesnt_log_when_nothing_to_do(self): with mock.patch("paasta_tools.setup_chronos_job._log", autospec=True) as mock_log, mock.patch( "paasta_tools.chronos_tools.update_job", autospec=True) as mock_update_job: setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=None, client=self.fake_client, ) assert not mock_log.called assert not mock_update_job.called
class TestMonitoring_Tools: general_page = True fake_general_service_config = { "team": "general_test_team", "runbook": "y/general_test_runbook", "tip": "general_test_tip", "notification_email": "general_test_notification_email", "page": general_page, } empty_service_config = marathon_tools.MarathonServiceConfig( service="myservicename", cluster="mycluster", instance="myinstance", config_dict={}, branch_dict=None, ) job_page = False fake_marathon_job_config = marathon_tools.MarathonServiceConfig( service="myservicename", cluster="myclustername", instance="myinstance", config_dict={ "team": "job_test_team", "runbook": "y/job_test_runbook", "tip": "job_test_tip", "notification_email": "job_test_notification_email", "page": job_page, }, branch_dict=None, ) fake_chronos_job_config = chronos_tools.ChronosJobConfig( service="myservicename", cluster="myclustername", instance="myinstance", config_dict={ "team": "job_test_team", "runbook": "y/job_test_runbook", "tip": "job_test_tip", "notification_email": "job_test_notification_email", "page": job_page, }, branch_dict=None, ) empty_job_config = {} monitor_page = True fake_monitor_config = { "team": "monitor_test_team", "runbook": "y/monitor_test_runbook", "tip": "monitor_test_tip", "notification_email": "monitor_test_notification_email", "page": monitor_page, } empty_monitor_config = {} framework = "fake_framework" overrides = {} instance = "fake_instance" service = "fake_service" soa_dir = "/fake/soa/dir" def test_get_team(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "team", self.overrides, self.service, self.soa_dir) def test_get_runbook(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_runbook(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "runbook", self.overrides, self.service, self.soa_dir) def test_get_tip(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_tip(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "tip", self.overrides, self.service, self.soa_dir) def test_get_notification_email(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_notification_email(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "notification_email", self.overrides, self.service, self.soa_dir) def test_get_page(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_page(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "page", self.overrides, self.service, self.soa_dir) def test_get_alert_after(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_alert_after(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "alert_after", self.overrides, self.service, self.soa_dir) def test_get_realert_every(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_defaults = mock.Mock() monitoring_tools.get_realert_every(self.overrides, self.service, self.soa_dir, monitoring_defaults) get_monitoring_config_value_patch.assert_called_once_with( "realert_every", self.overrides, self.service, self.soa_dir, monitoring_defaults, ) def test_get_check_every(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_check_every(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "check_every", self.overrides, self.service, self.soa_dir) def test_get_irc_channels(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_irc_channels(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "irc_channels", self.overrides, self.service, self.soa_dir) def test_get_slack_channels(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_slack_channels(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "slack_channels", self.overrides, self.service, self.soa_dir) def test_get_dependencies(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_dependencies(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "dependencies", self.overrides, self.service, self.soa_dir) def test_get_ticket(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_ticket(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "ticket", self.overrides, self.service, self.soa_dir) def test_get_project(self): with mock.patch( "paasta_tools.monitoring_tools.__get_monitoring_config_value", autospec=True) as get_monitoring_config_value_patch: monitoring_tools.get_project(self.overrides, self.service, self.soa_dir) get_monitoring_config_value_patch.assert_called_once_with( "project", self.overrides, self.service, self.soa_dir) def test_get_monitoring_config_value_with_monitor_config(self): expected = "monitor_test_team" with mock.patch( "service_configuration_lib.read_service_configuration", autospec=True, return_value=self.fake_general_service_config, ) as service_configuration_lib_patch, mock.patch( "paasta_tools.monitoring_tools.read_monitoring_config", autospec=True, return_value=self.fake_monitor_config, ) as read_monitoring_patch, mock.patch( "paasta_tools.monitoring_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value="fake_cluster") actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_get_monitoring_config_value_with_service_config(self): expected = "general_test_team" with mock.patch( "service_configuration_lib.read_service_configuration", autospec=True, return_value=self.fake_general_service_config, ) as service_configuration_lib_patch, mock.patch( "paasta_tools.monitoring_tools.read_monitoring_config", autospec=True, return_value=self.empty_monitor_config, ) as read_monitoring_patch, mock.patch( "paasta_tools.monitoring_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value="fake_cluster") actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_get_monitoring_config_value_with_defaults(self): expected = None with mock.patch( "service_configuration_lib.read_service_configuration", autospec=True, return_value=self.empty_job_config, ) as service_configuration_lib_patch, mock.patch( "paasta_tools.monitoring_tools.read_monitoring_config", autospec=True, return_value=self.empty_monitor_config, ) as read_monitoring_patch, mock.patch( "paasta_tools.monitoring_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value="fake_cluster") actual = monitoring_tools.get_team(self.overrides, self.service, self.soa_dir) assert expected == actual service_configuration_lib_patch.assert_called_once_with( self.service, soa_dir=self.soa_dir) read_monitoring_patch.assert_called_once_with(self.service, soa_dir=self.soa_dir) def test_send_event(self): fake_service = "fake_service" fake_monitoring_overrides = {} fake_check_name = "fake_check_name" fake_status = "42" fake_output = "The http port is not open" fake_team = "fake_team" fake_tip = "fake_tip" fake_notification_email = "fake@notify" fake_irc = "#fake" fake_slack = "#fake_slack" fake_soa_dir = "/fake/soa/dir" self.fake_cluster = "fake_cluster" fake_sensu_host = "fake_sensu_host" fake_sensu_port = 12345 expected_runbook = "http://y/paasta-troubleshooting" expected_check_name = fake_check_name expected_kwargs = { "name": expected_check_name, "runbook": expected_runbook, "status": fake_status, "output": fake_output, "team": fake_team, "page": True, "tip": fake_tip, "notification_email": fake_notification_email, "check_every": "1m", "realert_every": -1, "alert_after": "5m", "irc_channels": fake_irc, "slack_channels": fake_slack, "ticket": False, "project": None, "priority": None, "source": "paasta-fake_cluster", "tags": [], "ttl": None, "sensu_host": fake_sensu_host, "sensu_port": fake_sensu_port, "component": None, "description": None, } with mock.patch( "paasta_tools.monitoring_tools.get_team", return_value=fake_team, autospec=True, ) as get_team_patch, mock.patch( "paasta_tools.monitoring_tools.get_tip", return_value=fake_tip, autospec=True, ) as get_tip_patch, mock.patch( "paasta_tools.monitoring_tools.get_notification_email", return_value=fake_notification_email, autospec=True, ) as get_notification_email_patch, mock.patch( "paasta_tools.monitoring_tools.get_irc_channels", return_value=fake_irc, autospec=True, ) as get_irc_patch, mock.patch( "paasta_tools.monitoring_tools.get_slack_channels", return_value=fake_slack, autospec=True, ) as get_slack_patch, mock.patch( "paasta_tools.monitoring_tools.get_ticket", return_value=False, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_project", return_value=None, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_page", return_value=True, autospec=True) as get_page_patch, mock.patch( "paasta_tools.monitoring_tools.get_priority", return_value=None, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_tags", return_value=[], autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_component", return_value=None, autospec=True, ), mock.patch( "paasta_tools.monitoring_tools.get_description", return_value=None, autospec=True, ), mock.patch( "pysensu_yelp.send_event", autospec=True ) as pysensu_yelp_send_event_patch, mock.patch( "paasta_tools.monitoring_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch: load_system_paasta_config_patch.return_value.get_cluster = mock.Mock( return_value=self.fake_cluster) load_system_paasta_config_patch.return_value.get_sensu_host = mock.Mock( return_value=fake_sensu_host) load_system_paasta_config_patch.return_value.get_sensu_port = mock.Mock( return_value=fake_sensu_port) monitoring_tools.send_event( fake_service, fake_check_name, fake_monitoring_overrides, fake_status, fake_output, fake_soa_dir, ) get_team_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_tip_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_notification_email_patch.assert_called_once_with( fake_monitoring_overrides, fake_service, fake_soa_dir) get_irc_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_slack_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) get_page_patch.assert_called_once_with(fake_monitoring_overrides, fake_service, fake_soa_dir) pysensu_yelp_send_event_patch.assert_called_once_with( **expected_kwargs) load_system_paasta_config_patch.return_value.get_cluster.assert_called_once_with( ) def test_send_event_sensu_host_is_None(self): fake_service = "fake_service" fake_monitoring_overrides = {} fake_check_name = "fake_check_name" fake_status = "42" fake_output = "The http port is not open" fake_soa_dir = "/fake/soa/dir" self.fake_cluster = "fake_cluster" fake_sensu_port = 12345 with mock.patch( "paasta_tools.monitoring_tools.get_team", autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_tip", autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_notification_email", autospec=True), mock.patch( "paasta_tools.monitoring_tools.get_irc_channels", autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_ticket", autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_project", autospec=True ), mock.patch( "paasta_tools.monitoring_tools.get_page", autospec=True ), mock.patch( "pysensu_yelp.send_event", autospec=True ) as pysensu_yelp_send_event_patch, mock.patch( "paasta_tools.monitoring_tools.load_system_paasta_config", autospec=True) as load_system_paasta_config_patch: load_system_paasta_config_patch.return_value.get_sensu_host = mock.Mock( return_value=None) load_system_paasta_config_patch.return_value.get_sensu_port = mock.Mock( return_value=fake_sensu_port) monitoring_tools.send_event( fake_service, fake_check_name, fake_monitoring_overrides, fake_status, fake_output, fake_soa_dir, ) assert pysensu_yelp_send_event_patch.call_count == 0 def test_read_monitoring_config(self): fake_name = "partial" fake_fname = "acronyms" fake_path = "ever_patched" fake_soa_dir = "/nail/cte/oas" fake_dict = {"e": "quail", "v": "snail"} with mock.patch("os.path.abspath", autospec=True, return_value=fake_path) as abspath_patch, mock.patch( "os.path.join", autospec=True, return_value=fake_fname) as join_patch, mock.patch( "service_configuration_lib.read_monitoring", autospec=True, return_value=fake_dict, ) as read_monitoring_patch: actual = monitoring_tools.read_monitoring_config( fake_name, fake_soa_dir) assert fake_dict == actual abspath_patch.assert_called_once_with(fake_soa_dir) join_patch.assert_called_once_with(fake_path, fake_name, "monitoring.yaml") read_monitoring_patch.assert_called_once_with(fake_fname)
class TestSetupChronosJob: fake_docker_image = 'test_docker:1.0' fake_client = mock.MagicMock() fake_service = 'test_service' fake_instance = 'test' fake_cluster = 'fake_test_cluster' fake_config_dict = { 'name': 'test_service test gitsha config', 'description': 'This is a test Chronos job.', 'command': '/bin/sleep 40', 'bounce_method': 'graceful', 'epsilon': 'PT30M', 'retries': 5, 'owner': '*****@*****.**', 'async': False, 'cpus': 5.5, 'mem': 1024.4, 'disk': 2048.5, 'disabled': 'true', 'schedule': 'R/2015-03-25T19:36:35Z/PT5M', 'schedule_time_zone': 'Zulu', } fake_branch_dict = { 'docker_image': 'paasta-%s-%s' % (fake_service, fake_cluster), } fake_chronos_job_config = chronos_tools.ChronosJobConfig( fake_service, fake_instance, fake_config_dict, fake_branch_dict) fake_docker_registry = 'remote_registry.com' fake_args = mock.MagicMock( service_instance=compose_job_id(fake_service, fake_instance), soa_dir='no_more', verbose=False, ) def test_main_success(self): expected_status = 0 expected_output = 'it_is_finished' fake_complete_job_config = {'foo': 'bar'} with contextlib.nested( mock.patch('setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_config', autospec=True), mock.patch('paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', return_value=self.fake_chronos_job_config, autospec=True), mock.patch('paasta_tools.chronos_tools.create_complete_config', return_value=fake_complete_job_config, autospec=True), mock.patch('setup_chronos_job.setup_job', return_value=(expected_status, expected_output), autospec=True), mock.patch('setup_chronos_job.send_event', autospec=True), mock.patch('setup_chronos_job.load_system_paasta_config', autospec=True), mock.patch('sys.exit', autospec=True), ) as ( parse_args_patch, load_chronos_config_patch, get_client_patch, load_chronos_job_config_patch, create_complete_config_patch, setup_job_patch, send_event_patch, load_system_paasta_config_patch, sys_exit_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) setup_chronos_job.main() parse_args_patch.assert_called_once_with() get_client_patch.assert_called_once_with( load_chronos_config_patch.return_value) load_chronos_job_config_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, soa_dir=self.fake_args.soa_dir, ) setup_job_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=fake_complete_job_config, client=self.fake_client, cluster=self.fake_cluster, ) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=expected_status, output=expected_output, ) sys_exit_patch.assert_called_once_with(0) def test_main_no_deployments(self): with contextlib.nested( mock.patch('setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_config', autospec=True), mock.patch('paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', return_value=self.fake_chronos_job_config, autospec=True, side_effect=NoDeploymentsAvailable), mock.patch('setup_chronos_job.setup_job', return_value=(0, 'it_is_finished'), autospec=True), mock.patch('setup_chronos_job.load_system_paasta_config', autospec=True), mock.patch('setup_chronos_job.send_event', autospec=True), ) as (parse_args_patch, load_chronos_config_patch, get_client_patch, load_chronos_job_config_patch, setup_job_patch, load_system_paasta_config_patch, send_event_patch): load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 def test_main_bad_chronos_job_config_notifies_user(self): with contextlib.nested( mock.patch('setup_chronos_job.parse_args', return_value=self.fake_args, autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_config', autospec=True), mock.patch('paasta_tools.chronos_tools.get_chronos_client', return_value=self.fake_client, autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', return_value=self.fake_chronos_job_config, autospec=True, side_effect=chronos_tools.InvalidChronosConfigError( 'test bad configuration')), mock.patch('setup_chronos_job.setup_job', return_value=(0, 'it_is_finished'), autospec=True), mock.patch('setup_chronos_job.load_system_paasta_config', autospec=True), mock.patch('setup_chronos_job.send_event', autospec=True), ) as ( parse_args_patch, load_chronos_config_patch, get_client_patch, load_chronos_job_config_patch, setup_job_patch, load_system_paasta_config_patch, send_event_patch, ): load_system_paasta_config_patch.return_value.get_cluster = mock.MagicMock( return_value=self.fake_cluster) with raises(SystemExit) as excinfo: setup_chronos_job.main() assert excinfo.value.code == 0 expected_error_msg = ( "Could not read chronos configuration file for %s in cluster %s\nError was: test bad configuration" % (compose_job_id(self.fake_service, self.fake_instance), self.fake_cluster)) send_event_patch.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, soa_dir=self.fake_args.soa_dir, status=Status.CRITICAL, output=expected_error_msg) def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=fake_existing_jobs), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, lookup_chronos_jobs_patch, sort_jobs_patch, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[], job_to_create=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value def test_setup_job_with_previously_enabled_job(self): fake_existing_job = { 'name': 'fake_job', 'disabled': False, } with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[fake_existing_job], job_to_create=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_setup_job_does_nothing_with_only_existing_app(self): fake_existing_job = self.fake_config_dict with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir) # Force the complete_config's name to match the return value of # lookup_chronos_jobs to simulate that they have the same name complete_config["name"] = fake_existing_job["name"] actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[], job_to_create=None, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value def test_send_event(self): fake_status = '42' fake_output = 'something went wrong' fake_soa_dir = '' expected_check_name = 'setup_chronos_job.%s' % compose_job_id( self.fake_service, self.fake_instance) with contextlib.nested( mock.patch("paasta_tools.monitoring_tools.send_event", autospec=True), mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True), mock.patch("setup_chronos_job.load_system_paasta_config", autospec=True), ) as ( mock_send_event, mock_load_chronos_job_config, mock_load_system_paasta_config, ): mock_load_system_paasta_config.return_value.get_cluster = mock.Mock( return_value='fake_cluster') mock_load_chronos_job_config.return_value.get_monitoring.return_value = {} setup_chronos_job.send_event( service=self.fake_service, instance=self.fake_instance, soa_dir=fake_soa_dir, status=fake_status, output=fake_output, ) mock_send_event.assert_called_once_with( service=self.fake_service, check_name=expected_check_name, overrides={ 'alert_after': '10m', 'check_every': '10s' }, status=fake_status, output=fake_output, soa_dir=fake_soa_dir) mock_load_chronos_job_config.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=mock_load_system_paasta_config.return_value. get_cluster.return_value, soa_dir=fake_soa_dir, ) def test_bounce_chronos_job_takes_actions(self): fake_jobs_to_disable = [{'name': 'job_to_disable'}] fake_jobs_to_delete = [{'name': 'job_to_delete'}] fake_job_to_create = {'name': 'job_to_create'} with contextlib.nested( mock.patch("setup_chronos_job._log", autospec=True), mock.patch("paasta_tools.chronos_tools.disable_job", autospec=True), mock.patch("paasta_tools.chronos_tools.delete_job", autospec=True), mock.patch("paasta_tools.chronos_tools.create_job", autospec=True), ) as ( mock_log, mock_disable_job, mock_delete_job, mock_create_job, ): setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_disable=fake_jobs_to_disable, jobs_to_delete=fake_jobs_to_delete, job_to_create=fake_job_to_create, client=self.fake_client, ) mock_log.assert_any_call( line=mock.ANY, level='debug', instance=self.fake_instance, cluster=self.fake_cluster, component='deploy', service=self.fake_service, ) mock_log.assert_any_call( line="Created new Chronos job: job_to_create", level='event', instance=self.fake_instance, cluster=self.fake_cluster, component='deploy', service=self.fake_service, ) mock_disable_job.assert_called_once_with( job=fake_jobs_to_disable[0], client=self.fake_client) mock_delete_job.assert_called_once_with(job=fake_jobs_to_delete[0], client=self.fake_client) mock_create_job.assert_called_once_with(job=fake_job_to_create, client=self.fake_client) def test_bounce_chronos_job_doesnt_log_when_nothing_to_do(self): fake_jobs_to_disable = [] fake_jobs_to_delete = [] fake_job_to_create = [] with contextlib.nested( mock.patch("setup_chronos_job._log", autospec=True), mock.patch("paasta_tools.chronos_tools.disable_job", autospec=True), mock.patch("paasta_tools.chronos_tools.delete_job", autospec=True), mock.patch("paasta_tools.chronos_tools.create_job", autospec=True), ) as ( mock_log, mock_disable_job, mock_delete_job, mock_create_job, ): setup_chronos_job.bounce_chronos_job( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_disable=fake_jobs_to_disable, jobs_to_delete=fake_jobs_to_delete, job_to_create=fake_job_to_create, client=self.fake_client, ) assert not mock_log.called assert not mock_disable_job.called assert not mock_delete_job.called assert not mock_create_job.called