def test_none_returned_on_variant_call_with_no_times_with_cfg_data(self):
     cfg_data = {
         "test": {
             "id": 1,
             "name": "test",
             "owner": "test_owner",
             "type": "r2",
             "version": "1",
             "experiment": {
                 "id": 1,
                 "name": "test",
                 "variants": {
                     "active": 50,
                     "control_1": 25,
                     "control_2": 25
                 },
             },
         }
     }
     experiments = Experiments(
         config_watcher=self.mock_filewatcher,
         server_span=self.mock_span,
         context_name="test",
         cfg_data=cfg_data,
         global_cache={},
         event_logger=self.event_logger,
     )
     self.assertEqual(self.event_logger.log.call_count, 0)
     variant = experiments.variant("test", user=self.user)
     self.assertEqual(variant, None)
    def test_is_valid_experiment(self):
        self.mock_filewatcher.get_data.return_value = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    }
                },
            }
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            event_logger=self.event_logger,
        )
        with mock.patch(
                "reddit_experiments.providers.r2.R2Experiment.variant") as p:
            p.return_value = "active"
            is_valid = experiments.is_valid_experiment("test")
            self.assertEqual(is_valid, True)

            is_valid = experiments.is_valid_experiment("test2")
            self.assertEqual(is_valid, False)
 def test_does_not_log_bucketing_event_with_cfg_data(self):
     event_queue = mock.Mock(spec=EventQueue)
     span = mock.MagicMock(spec=ServerSpan)
     cfg_data = {
         "test": {
             "id": 1,
             "name": "test",
             "type": "feature_flag",
             "version": "1",
             "start_ts": time.time() - THIRTY_DAYS,
             "stop_ts": time.time() + THIRTY_DAYS,
             "experiment": {
                 "targeting": {"logged_in": [True, False]},
                 "variants": {"active": 100},
             },
         }
     }
     experiments = Experiments(
         config_watcher=mock.Mock(spec=FileWatcher),
         server_span=span,
         context_name="test",
         cfg_data=cfg_data,
         global_cache={},
     )
     self.assertEqual(event_queue.put.call_count, 0)
     variant = experiments.variant("test", user_id=self.user_id, logged_in=True)
     self.assertEqual(variant, "active")
     self.assertEqual(event_queue.put.call_count, 0)
     experiments.variant("test", user_id=self.user_id, logged_in=True)
     self.assertEqual(event_queue.put.call_count, 0)
    def test_exposure_event_fields_with_cfg_data(self):
        cfg_data = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test_owner",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "id": 1,
                    "name": "test",
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    },
                },
            }
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            cfg_data=cfg_data,
            global_cache={},
            event_logger=self.event_logger,
        )

        self.assertEqual(self.event_logger.log.call_count, 0)
        experiments.expose("test",
                           variant_name="control_1",
                           user=self.user,
                           app_name="r2")
        self.assertEqual(self.event_logger.log.call_count, 1)

        event_fields = self.event_logger.log.call_args[1]

        self.assertEqual(event_fields["variant"], "control_1")
        self.assertEqual(event_fields["user_id"], "t2_1")
        self.assertEqual(event_fields["logged_in"], True)
        self.assertEqual(event_fields["app_name"], "r2")
        self.assertEqual(event_fields["cookie_created_timestamp"], 10000)
        self.assertEqual(event_fields["event_type"], EventType.EXPOSE)
        self.assertNotEqual(event_fields["span"], None)

        self.assertEqual(getattr(event_fields["experiment"], "id"), 1)
        self.assertEqual(getattr(event_fields["experiment"], "name"), "test")
        self.assertEqual(getattr(event_fields["experiment"], "owner"),
                         "test_owner")
        self.assertEqual(getattr(event_fields["experiment"], "version"), "1")
    def test_bucketing_event_fields_without_baseplate_user_with_cfg_data(self):
        cfg_data = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test_owner",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "id": 1,
                    "name": "test",
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    },
                },
            }
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            cfg_data=cfg_data,
            global_cache={},
            event_logger=self.event_logger,
        )

        with mock.patch("reddit_experiments.providers.r2.R2Experiment.variant",
                        return_value="active"):
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test",
                                user_id="t2_2",
                                app_name="r2",
                                logged_in=True)
            self.assertEqual(self.event_logger.log.call_count, 1)
        event_fields = self.event_logger.log.call_args[1]

        self.assertEqual(event_fields["variant"], "active")
        self.assertEqual(event_fields["user_id"], "t2_2")
        self.assertEqual(event_fields["logged_in"], True)
        self.assertEqual(event_fields["app_name"], "r2")
        self.assertEqual(event_fields["event_type"], EventType.BUCKET)
        self.assertNotEqual(event_fields["span"], None)

        self.assertEqual(getattr(event_fields["experiment"], "id"), 1)
        self.assertEqual(getattr(event_fields["experiment"], "name"), "test")
        self.assertEqual(getattr(event_fields["experiment"], "owner"),
                         "test_owner")
        self.assertEqual(getattr(event_fields["experiment"], "version"), "1")
    def test_get_all_experiment_names_with_cfg_data(self):
        cfg_data = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    }
                },
            },
            "test2": {
                "id": 1,
                "name": "test",
                "owner": "test",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    }
                },
            },
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            cfg_data=cfg_data,
            global_cache={},
            event_logger=self.event_logger,
        )

        with mock.patch(
                "reddit_experiments.providers.r2.R2Experiment.variant") as p:
            p.return_value = "active"
            experiment_names = experiments.get_all_experiment_names()
            self.assertEqual(len(experiment_names), 2)
            self.assertEqual("test" in experiment_names, True)
            self.assertEqual("test2" in experiment_names, True)
 def test_that_bucketing_events_not_sent_if_cant_find_experiment_with_cfg_data(
         self):
     cfg_data = {
         "other_test": {
             "id": 1,
             "name": "test",
             "owner": "test",
             "type": "r2",
             "version": "1",
             "start_ts": time.time() - THIRTY_DAYS,
             "stop_ts": time.time() + THIRTY_DAYS,
             "experiment": {
                 "variants": {
                     "active": 10,
                     "control_1": 10,
                     "control_2": 10
                 }
             },
         }
     }
     experiments = Experiments(
         config_watcher=self.mock_filewatcher,
         server_span=self.mock_span,
         context_name="test",
         cfg_data=cfg_data,
         global_cache={},
         event_logger=self.event_logger,
     )
     self.assertEqual(self.event_logger.log.call_count, 0)
     experiments.variant("test", user=self.user)
     self.assertEqual(self.event_logger.log.call_count, 0)
     experiments.variant("test", user=self.user)
     self.assertEqual(self.event_logger.log.call_count, 0)
    def test_that_bucketing_events_are_not_sent_with_override_false_with_cfg_data(
            self):
        """Don't send events when override is False."""
        cfg_data = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    }
                },
            }
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            cfg_data=cfg_data,
            global_cache={},
            event_logger=self.event_logger,
        )

        with mock.patch(
                "reddit_experiments.providers.r2.R2Experiment.variant") as p:
            p.return_value = "active"
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test",
                                user=self.user,
                                bucketing_event_override=False)
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test",
                                user=self.user,
                                bucketing_event_override=False)
            self.assertEqual(self.event_logger.log.call_count, 0)
            p.return_value = None
            experiments.variant("test",
                                user=self.user,
                                bucketing_event_override=False)
            self.assertEqual(self.event_logger.log.call_count, 0)
 def test_none_returned_on_variant_call_with_no_experiment_with_cfg_data(
         self):
     cfg_data = {
         "test": {
             "id": 1,
             "name": "test",
             "owner": "test_owner",
             "type": "r2",
             "version": "1",
             "start_ts": time.time() - THIRTY_DAYS,
             "stop_ts": time.time() + THIRTY_DAYS,
         }
     }
     experiments = Experiments(
         config_watcher=self.mock_filewatcher,
         server_span=self.mock_span,
         context_name="test",
         cfg_data=cfg_data,
         global_cache={},
         event_logger=self.event_logger,
     )
     self.assertEqual(self.event_logger.log.call_count, 0)
     variant = experiments.variant("test", user=self.user)
     self.assertEqual(variant, None)
    def test_that_bucketing_events_not_sent_if_experiment_disables_with_cfg_data(
            self):
        cfg_data = {
            "test": {
                "id": 1,
                "name": "test",
                "owner": "test",
                "type": "r2",
                "version": "1",
                "start_ts": time.time() - THIRTY_DAYS,
                "stop_ts": time.time() + THIRTY_DAYS,
                "experiment": {
                    "variants": {
                        "active": 10,
                        "control_1": 10,
                        "control_2": 10
                    }
                },
            }
        }
        experiments = Experiments(
            config_watcher=self.mock_filewatcher,
            server_span=self.mock_span,
            context_name="test",
            cfg_data=cfg_data,
            global_cache={},
            event_logger=self.event_logger,
        )

        with mock.patch(
                "reddit_experiments.providers.r2.R2Experiment.variant",
                return_value="active"
        ), mock.patch(
                "reddit_experiments.providers.r2.R2Experiment.should_log_bucketing",
                return_value=False,
        ):
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test", user=self.user)
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test", user=self.user)
            self.assertEqual(self.event_logger.log.call_count, 0)
            experiments.variant("test",
                                user=self.user,
                                bucketing_event_override=True)
            self.assertEqual(self.event_logger.log.call_count, 0)
 def test_that_bucketing_events_not_sent_if_config_is_empty_with_cfg_data(
         self):
     experiments = Experiments(
         config_watcher=self.mock_filewatcher,
         server_span=self.mock_span,
         context_name="test",
         cfg_data={},
         global_cache={},
         event_logger=self.event_logger,
     )
     self.assertEqual(self.event_logger.log.call_count, 0)
     experiments.variant("test", user=self.user)
     self.assertEqual(self.event_logger.log.call_count, 0)
     experiments.variant("test", user=self.user)
     self.assertEqual(self.event_logger.log.call_count, 0)