def test_1(settings):
    test_data1 = struct.wrap({
        "header": ("date", "count", "mean-std", "mean", "mean+std", "reject"),
        "rows": [
            ("2013-Apr-05 13:55:00", "23", "655.048136994614", "668.5652173913044", "682.0822977879948"),
            ("2013-Apr-05 13:59:00", "23", "657.8717192954238", "673.3478260869565", "688.8239328784892"),
            ("2013-Apr-05 14:05:00", "23", "658.3247270429598", "673", "687.6752729570402"),
            ("2013-Apr-05 14:08:00", "23", "658.5476631609771", "673.6521739130435", "688.7566846651099"),
            ("2013-Apr-05 14:16:00", "23", "653.2311994952266", "666.1739130434783", "679.1166265917299"),
            ("2013-Apr-05 14:26:00", "23", "659.5613845589426", "671.8260869565217", "684.0907893541009"),
            ("2013-Apr-05 14:42:00", "23", "662.3517791831357", "677.1739130434783", "691.9960469038208"),
            ("2013-Apr-05 15:26:00", "23", "659.8270045518033", "672", "684.1729954481967"),
            ("2013-Apr-05 15:30:00", "23", "659.4023663187861", "674", "688.5976336812139"),
            ("2013-Apr-05 15:32:00", "23", "652.8643631817508", "666.9565217391304", "681.0486802965099"),
            ("2013-Apr-05 15:35:00", "23", "661.6037178485499", "675.1739130434783", "688.7441082384066"),
            ("2013-Apr-05 15:39:00", "23", "658.0124378440726", "670.1304347826087", "682.2484317211449"),
            ("2013-Apr-05 16:20:00", "46", "655.9645219644624", "667.4782608695652", "678.9919997746681"),
            ("2013-Apr-05 16:30:00", "23", "660.2572506418051", "671.8695652173913", "683.4818797929775"),
            ("2013-Apr-05 16:31:00", "23", "661.011102554583", "673.4347826086956", "685.8584626628083"),
            ("2013-Apr-05 16:55:00", "23", "655.9407699325201", "671.304347826087", "686.6679257196539"),
            ("2013-Apr-05 17:07:00", "23", "657.6412277100247", "667.5217391304348", "677.4022505508448"),
            #        ("2013-Apr-05 17:12:00", "23", "598.3432138277318", "617.7391304347826", "637.1350470418334"),   # <--DIP IN DATA
            ("2013-Apr-05 17:23:00", "23", "801.0537973113723", "822.1739130434783", "843.2940287755843", 1)  # <--SPIKE IN DATA
        ]
    })
    test_data1 = [
        struct.wrap({
            "timestamp": CNV.datetime2unix(CNV.string2datetime(t.date, "%Y-%b-%d %H:%M:%S")),
            "datetime": CNV.string2datetime(t.date, "%Y-%b-%d %H:%M:%S"),
            "count": int(t.count),
            "mean": float(t.mean),
            "variance": pow(float(t["mean+std"]) - float(t.mean), 2),
            "reject": t.reject
        })
        for t in CNV.table2list(test_data1.header, test_data1.rows)
    ]

    with DB(settings.perftest) as db:
        tester = test_alert_exception(db)
        tester.test_alert_generated(settings, test_data1)
def not_test_2(settings):
    """
    THIS WAS TESTING FOR A DECREASE IN THE MEAN, BUT THE CURRENT CODE IGNORES THOSE
    """
    test_data2 = struct.wrap({
        "header": ("timestamp", "mean", "std", "h0_rejected", "count"),
        "rows": [
            (1366388389, 295.36, 32.89741631, 0, 25),
            (1366387915, 307.92, 32.86198412, 0, 25),
            (1366390777, 309, 41.22802445, 0, 25),
            (1366398771, 309.24, 34.18488945, 0, 25),
            (1366401499, 308.2, 30.36170834, 0, 25),
            (1366412504, 192.8, 46.27634385, 1, 25), # Should be an alert
            (1366421699, 298.04, 29.09249617, 0, 25),
            (1366433920, 324.52, 28.13378752, 0, 25),
            (1366445744, 302.2, 28.19131072, 0, 25),
            (1366455408, 369.96, 31.25363979, 0, 25),
            (1366474119, 313.12, 33.66541252, 0, 25),
            (1366483789, 369.96, 30.81460693, 0, 25),
            (1366498412, 311.76, 36.02462121, 0, 25),
            (1366507773, 291.08, 27.86562996, 0, 25)
        ]
    })
    test_data2 = [
        struct.wrap({
            "timestamp": t.timestamp,
            "datetime": CNV.unix2datetime(t.timestamp),
            "count": t.count,
            "mean": t.mean,
            "variance": pow(t.std, 2),
            "reject": t.h0_rejected
        })
        for t in CNV.table2list(test_data2.header, test_data2.rows)
    ]

    with DB(settings.perftest) as db:
        tester = test_alert_exception(db)
        tester.test_alert_generated(test_data2)
    def _setup(self):
        uid = self.db.query("SELECT util.newid() uid FROM DUAL")[0].uid

        ## VERFIY THE alert_reason EXISTS
        exists = self.db.query("""
            SELECT
                count(1) num
            FROM
                reasons
            WHERE
                code={{reason}}
            """,
                               {"reason": REASON}
        )[0].num
        if exists == 0:
            Log.error("Expecting the database to have an alert_reason={{reason}}", {"reason": REASON})

        ## MAKE A 'PAGE' TO TEST
        self.db.execute("DELETE FROM pages")
        self.db.insert("pages", {
            "test_id": 0,
            "url": self.url
        })
        self.page_id = self.db.query("SELECT id FROM pages")[0].id

        ## ADD A THRESHOLD TO TEST WITH
        self.db.execute("""
            INSERT INTO alert_page_thresholds (
                id,
                page,
                threshold,
                severity,
                reason,
                time_added,
                contact
            ) VALUES (
                {{uid}},
                {{page_id}},
                {{threshold}},
                {{severity}},
                concat("(", {{url}}, ") for test"),
                now(),
                "*****@*****.**"
            )
            """, {
            "uid": uid,
            "url": self.url,
            "page_id": self.page_id,
            "severity": self.severity,
            "threshold": 800
        })

        ## ENSURE THERE ARE NO ALERTS IN DB
        self.db.execute("DELETE FROM alerts WHERE reason={{reason}}", {"reason": REASON})

        ## diff_time IS REQUIRED TO TRANSLATE THE TEST DATE DATES TO SOMETHING MORE CURRENT
        now_time = CNV.datetime2unix(datetime.utcnow())
        max_time = max([CNV.datetime2unix(CNV.string2datetime(t.date, "%Y-%b-%d %H:%M:%S")) for t in CNV.table2list(self.test_data.header, self.test_data.rows)])
        diff_time = now_time - max_time

        ## INSERT THE TEST RESULTS
        for t in CNV.table2list(self.test_data.header, self.test_data.rows):
            time = CNV.datetime2unix(CNV.string2datetime(t.date, "%Y-%b-%d %H:%M:%S"))
            time += diff_time

            self.db.insert("test_data_all_dimensions", {
                "id": SQL("util.newid()"),
                "test_run_id": SQL("util.newid()"),
                "product_id": 0,
                "operating_system_id": 0,
                "test_id": 0,
                "page_id": self.page_id,
                "date_received": time,
                "revision": "ba928cbd5191",
                "product": "Firefox",
                "branch": "Mozilla-Inbound",
                "branch_version": "23.0a1",
                "operating_system_name": "mac",
                "operating_system_version": "OS X 10.8",
                "processor": "x86_64",
                "build_type": "opt",
                "machine_name": "talos-mtnlion-r5-049",
                "pushlog_id": 19998363,
                "push_date": time,
                "test_name": "tp5o",
                "page_url": self.url,
                "mean": float(t.mean),
                "std": float(t["mean+std"]) - float(t.mean),
                "h0_rejected": 0,
                "p": None,
                "n_replicates": t.count,
                "fdr": 0,
                "trend_mean": None,
                "trend_std": None,
                "test_evaluation": 0,
                "status": 1
            })
    def setup(self, to_list):
        self.uid = self.db.query("SELECT util.newid() uid FROM DUAL")[0].uid

        #CLEAR EMAILS
        self.db.execute("DELETE FROM mail.delivery")
        self.db.execute("DELETE FROM mail.attachment")
        self.db.execute("DELETE FROM mail.content")

        #TEST NUMBER OF LISTENERS IN listeners TABLE
        self.db.execute("DELETE FROM listeners")
        for l in to_list:
            self.db.insert("listeners", {"email": l})


        #MAKE A REASON FOR USE IN THIS TESTING
        self.db.execute("DELETE FROM alerts WHERE reason={{reason}}", {"reason": self.reason})
        self.db.execute("DELETE FROM reasons WHERE code={{reason}}", {"reason": self.reason})
        self.db.insert("reasons", {
            "code": self.reason,
            "description": ">>>>{{id}}<<<<", #SPECIAL PATTERN TO DISTINGUISH BETWEEN RESULTING MAILS
            "config": None,
            "last_run": self.now - timedelta(days=1)
        })


        #MAKE SOME TEST DATA (AND GET ID)
        all_dim = struct.wrap({
            "header":
                ("id", "test_run_id", "product_id", "operating_system_id", "test_id", "page_id", "date_received", "revision", "product", "branch", "branch_version", "operating_system_name",
                 "operating_system_version", "processor", "build_type", "machine_name", "pushlog_id", "push_date", "test_name", "page_url", "mean", "std", "h0_rejected", "p", "n_replicates", "fdr",
                 "trend_mean", "trend_std", "test_evaluation", "status"),
            "data": [
                (0, 117679, 65, 20, 64, 860, 1366261267, "d6b34be6fb4c", "Firefox", "Mozilla-Inbound", "23.0a1", "win", "6.2.9200", "x86_64", "opt", "t-w864-ix-022", "19801727", "1366245741", "tp5o",
                 "bbc.co.uk", 138.8, 40.5257120028, 0, 0.650194865224, 25, 0, 144.37333333365, 12.96130778322, 1, 1)
            ]})
        self.db.insert_list("test_data_all_dimensions", CNV.table2list(all_dim.header, all_dim.data))
        self.series = self.db.query("SELECT min(id) id FROM test_data_all_dimensions")[0].id


        # WE INJECT THE EXPECTED TEST RESULTS RIGHT INTO THE DETAILS, THAT WAY
        # WE CAN SEE THEM IN THE EMAIL DELIVERED
        test_data = struct.wrap({
            "header":
                ("id", "status", "create_time", "last_updated", "last_sent", "tdad_id", "reason", "details", "severity", "confidence", "solution"),
            "data": [
                #TEST last_sent IS NOT TOO YOUNG
                (self.uid + 0, "new", self.far_past, self.far_past, self.recent_past, self.series, self.reason, CNV.object2JSON({"id": 0, "expect": "fail"}), self.high_severity, self.high_confidence,
                 None),
                #TEST last_sent IS TOO OLD, SHOULD BE (RE)SENT
                (self.uid + 1, "new", self.far_past, self.now, None, self.series, self.reason, CNV.object2JSON({"id": 1, "expect": "pass"}), self.high_severity, self.high_confidence, None),
                (self.uid + 2, "new", self.far_past, self.now, self.far_past, self.series, self.reason, CNV.object2JSON({"id": 2, "expect": "pass"}), self.high_severity, self.high_confidence, None),
                (self.uid + 3, "new", self.now, self.now, self.recent_past, self.series, self.reason, CNV.object2JSON({"id": 3, "expect": "pass"}), self.high_severity, self.high_confidence, None),
                #TEST obsolete ARE NOT SENT
                (self.uid + 4, "obsolete", self.now, self.now, self.far_past, self.series, self.reason, CNV.object2JSON({"id": 4, "expect": "fail"}), self.high_severity, self.high_confidence, None),
                #TEST ONLY IMPORTANT ARE SENT
                (self.uid + 5, "new", self.now, self.now, None, self.series, self.reason, CNV.object2JSON({"id": 5, "expect": "pass"}), self.important, 0.5, None),
                (self.uid + 6, "new", self.now, self.now, None, self.series, self.reason, CNV.object2JSON({"id": 6, "expect": "fail"}), self.low_severity, self.high_confidence, None),
                (self.uid + 7, "new", self.now, self.now, None, self.series, self.reason, CNV.object2JSON({"id": 7, "expect": "fail"}), self.high_severity, self.low_confidence, None),
                #TEST ONES WITH SOLUTION ARE NOT SENT
                (self.uid + 8, "new", self.now, self.now, None, self.series, self.reason, CNV.object2JSON({"id": 8, "expect": "fail"}), self.high_severity, self.high_confidence, "a solution!")
            ]
        })

        self.test_data = CNV.table2list(test_data.header, test_data.data)
        self.db.insert_list("alerts", self.test_data)