def test_live_rollout_updates_population_percent(self): experiment = ExperimentFactory.create( type=Experiment.TYPE_ROLLOUT, status=Experiment.STATUS_LIVE, normandy_id=1234, population_percent=decimal.Decimal("25.000"), ) mock_response_data = { "approved_revision": { "enabled": True, "filter_object": [{ "type": "bucketSample", "count": 5000, "total": 10000 }], } } mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.population_percent, decimal.Decimal("50.000"))
def test_update_accepted_experiment_task(self): experiment = ExperimentFactory.create( status=Experiment.STATUS_ACCEPTED, normandy_id=1234, proposed_enrollment=60, proposed_duration=60, ) tasks.update_launched_experiments() recipe = self.buildMockSuccessEnabledResponse().json( )["approved_revision"] self.mock_tasks_add_start_date_comment.delay.assert_called_with( experiment.id) self.mock_tasks_set_is_paused_value.delay.assert_called_with( experiment.id, recipe) self.mock_tasks_comp_experiment_update_res.delay.assert_not_called() self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].recipients(), [experiment.owner.email, experiment.analysis_owner], )
def test_send_experiment_ending_email(self): ExperimentFactory.create( status=Experiment.STATUS_LIVE, normandy_id=1234, proposed_start_date=date.today(), proposed_enrollment=0, proposed_duration=5, ) ExperimentFactory.create( status=Experiment.STATUS_LIVE, normandy_id=1234, proposed_start_date=date.today(), proposed_duration=30, proposed_enrollment=0, ) exp_3 = ExperimentFactory.create( status=Experiment.STATUS_LIVE, normandy_id=1234, proposed_start_date=date.today(), proposed_duration=4, proposed_enrollment=0, ) ExperimentEmail.objects.create( experiment=exp_3, type=ExperimentConstants.EXPERIMENT_ENDS) tasks.update_launched_experiments() self.assertEqual(len(mail.outbox), 1)
def test_one_failure_does_not_affect_other_experiment_status_updates(self): self.setUpMockNormandyFailWithSpecifiedID("1234") ExperimentFactory.create_with_status( target_status=Experiment.STATUS_ACCEPTED, normandy_id=1234) ExperimentFactory.create_with_status( target_status=Experiment.STATUS_ACCEPTED, normandy_id=1235) tasks.update_launched_experiments() updated_experiment = Experiment.objects.get(normandy_id=1234) updated_experiment2 = Experiment.objects.get(normandy_id=1235) self.assertEqual(updated_experiment.status, Experiment.STATUS_ACCEPTED) self.assertEqual(updated_experiment2.status, Experiment.STATUS_LIVE) self.assertFalse( updated_experiment.changes.filter( changed_by__email="*****@*****.**", old_status=Experiment.STATUS_ACCEPTED, new_status=Experiment.STATUS_LIVE, ).exists()) self.assertTrue( updated_experiment2.changes.filter( changed_by__email="*****@*****.**", old_status=Experiment.STATUS_ACCEPTED, new_status=Experiment.STATUS_LIVE, ).exists())
def test_live_isHighPopulation_update(self): experiment = ExperimentFactory.create( type=Experiment.TYPE_PREF, status=Experiment.STATUS_LIVE, normandy_id=1234, ) mock_response_data = { "approved_revision": { "enabled": True, "arguments": { "isHighPopulation": True }, } } mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.assertFalse(experiment.is_high_population) self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.is_high_population, True)
def test_experiment_with_no_creator_in_recipe(self): experiment = ExperimentFactory.create_with_status( target_status=Experiment.STATUS_ACCEPTED, normandy_id=1234) mock_response_data = { "approved_revision": { "enabled": True, "enabled_states": [{ "creator": None }] } } mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.status, Experiment.STATUS_LIVE) self.assertTrue( experiment.changes.filter( changed_by__email="*****@*****.**", old_status=Experiment.STATUS_ACCEPTED, new_status=Experiment.STATUS_LIVE, ).exists())
def test_firefox_version_no_updates_when_no_change(self): experiment = ExperimentFactory.create( status=Experiment.STATUS_LIVE, normandy_id=1234, firefox_min_version="79.0", firefox_max_version="82.0", ) mock_response_data = { "approved_revision": { "enabled": True, "filter_object": [{ "type": "version", "versions": [79, 80, 81, 82] }], } } mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.firefox_min_version, "79.0") self.assertEqual(experiment.firefox_max_version, "82.0") self.assertFalse( experiment.changes.filter(message="Added Version(s)").exists())
def test_experiment_with_no_recipe_data(self): ExperimentFactory.create_with_status( target_status=Experiment.STATUS_ACCEPTED, normandy_id=1234 ) mock_response_data = {"approved_revision": None} mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.status, Experiment.STATUS_ACCEPTED) self.assertFalse( experiment.changes.filter( changed_by__email="*****@*****.**", old_status=Experiment.STATUS_ACCEPTED, new_status=Experiment.STATUS_LIVE, ).exists() )
def test_update_live_experiment_not_updated(self): ExperimentFactory.create_with_status( target_status=Experiment.STATUS_LIVE, normandy_id=1234) tasks.update_launched_experiments() self.mock_tasks_add_start_date_comment.delay.assert_not_called() self.mock_tasks_comp_experiment_update_res.delay.assert_not_called() self.mock_tasks_set_is_paused_value.delay.assert_called()
def test_update_live_experiment_task(self): experiment = ExperimentFactory.create_with_status( target_status=Experiment.STATUS_LIVE, normandy_id=1234) self.mock_normandy_requests_get.return_value = ( self.buildMockSuccessDisabledResponse()) tasks.update_launched_experiments() self.mock_tasks_comp_experiment_update_res.delay.assert_called_with( experiment.id) self.mock_tasks_set_is_paused_value.delay.assert_not_called() self.mock_tasks_add_start_date_comment.delay.assert_not_called() # No email was sent self.assertEqual(len(mail.outbox), 0)
def test_accepted_experiment_becomes_live_if_normandy_enabled(self): experiment = ExperimentFactory.create( normandy_id=1234, proposed_start_date=date.today(), proposed_duration=30, proposed_enrollment=1, ) experiment.status = Experiment.STATUS_LIVE experiment.save() tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].recipients(), [experiment.owner.email, experiment.analysis_owner], )
def test_live_experiment_doesnt_update_population_percent_with_namespace( self): experiment = ExperimentFactory.create( status=Experiment.STATUS_LIVE, normandy_id=1234, population_percent=decimal.Decimal("25.000"), ) mock_response_data = { "approved_revision": { "enabled": True, "filter_object": [{ "count": 2500, "namespace": "first-run", "start": 9700, "total": 10000, "type": "namespaceSample", }], } } mock_response = mock.Mock() mock_response.json = mock.Mock() mock_response.json.return_value = mock_response_data mock_response.raise_for_status = mock.Mock() mock_response.raise_for_status.side_effect = None mock_response.status_code = 200 self.mock_normandy_requests_get.return_value = mock_response tasks.update_launched_experiments() experiment = Experiment.objects.get(normandy_id=1234) self.assertEqual(experiment.population_percent, decimal.Decimal("25.000")) self.assertFalse( experiment.changes.filter( message="Updated Population Percent").exists())
def test_experiment_without_normandy_ids(self): ExperimentFactory.create_with_status( target_status=Experiment.STATUS_LIVE, normandy_id=None) tasks.update_launched_experiments() self.mock_normandy_requests_get.assert_not_called()