コード例 #1
0
def test_operator_validator(setup_database):
    dbsession = setup_database

    # Test passing SQLObserver with empty SQL result
    alert1 = create_alert(dbsession,
                          "SELECT first FROM test_table WHERE first = -1")
    observe(alert1.id, dbsession)
    assert (operator_validator(alert1.sql_observer[0],
                               '{"op": ">=", "threshold": 60}') is False)

    # Test passing SQLObserver with result that doesn't pass a greater than threshold
    alert2 = create_alert(dbsession, "SELECT 55")
    observe(alert2.id, dbsession)
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": ">=", "threshold": 60}') is False)

    # Test passing SQLObserver with result that passes a greater than threshold
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": ">=", "threshold": 40}') is True)

    # Test passing SQLObserver with result that doesn't pass a less than threshold
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": "<=", "threshold": 40}') is False)

    # Test passing SQLObserver with result that passes threshold
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": "<=", "threshold": 60}') is True)

    # Test passing SQLObserver with result that doesn't equal threshold
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": "==", "threshold": 60}') is False)

    # Test passing SQLObserver with result that equals threshold
    assert (operator_validator(alert2.sql_observer[0],
                               '{"op": "==", "threshold": 55}') is True)
コード例 #2
0
def test_deliver_alert_screenshot(screenshot_mock, url_mock, email_mock,
                                  file_upload_mock, setup_database):
    dbsession = setup_database
    alert = create_alert(dbsession, "SELECT 55", "not null", "{}")
    observe(alert.id, dbsession)

    screenshot = read_fixture("sample.png")
    screenshot_mock.return_value = screenshot

    # TODO: fix AlertModelView.show url call from test
    url_mock.side_effect = [
        f"http://0.0.0.0:8080/alert/show/{alert.id}",
        f"http://0.0.0.0:8080/superset/slice/{alert.slice_id}/",
    ]

    deliver_alert(alert.id, dbsession)
    assert email_mock.call_args[1]["images"]["screenshot"] == screenshot
    assert file_upload_mock.call_args[1] == {
        "channels":
        alert.slack_channel,
        "file":
        screenshot,
        "initial_comment":
        f"\n*Triggered Alert: {alert.label} :redalert:*\n"
        f"*Query*:```{alert.sql_observer[0].sql}```\n"
        f"*Result*: {alert.observations[-1].value}\n"
        f"*Reason*: {alert.observations[-1].value} {alert.validators[0].pretty_print()}\n"
        f"<http://0.0.0.0:8080/alert/show/{alert.id}"
        f"|View Alert Details>\n<http://0.0.0.0:8080/superset/slice/{alert.slice_id}/"
        "|*Explore in Superset*>",
        "title":
        f"[Alert] {alert.label}",
    }
コード例 #3
0
def test_operator_validator(setup_database):
    dbsession = setup_database

    # Test passing with empty SQL result
    alert1 = create_alert(dbsession,
                          "SELECT first FROM test_table WHERE first = -1")
    observe(alert1.id, dbsession)
    assert operator_validator(alert1, '{"op": ">=", "threshold": 60}') is False
    # ensure that 0 threshold works
    assert operator_validator(alert1, '{"op": ">=", "threshold": 0}') is False

    # Test passing with result that doesn't pass a greater than threshold
    alert2 = create_alert(dbsession, "SELECT 55")
    observe(alert2.id, dbsession)
    assert operator_validator(alert2, '{"op": ">=", "threshold": 60}') is False

    # Test passing with result that passes a greater than threshold
    assert operator_validator(alert2, '{"op": ">=", "threshold": 40}') is True

    # Test passing with result that doesn't pass a less than threshold
    assert operator_validator(alert2, '{"op": "<=", "threshold": 40}') is False

    # Test passing with result that passes threshold
    assert operator_validator(alert2, '{"op": "<=", "threshold": 60}') is True

    # Test passing with result that doesn't equal threshold
    assert operator_validator(alert2, '{"op": "==", "threshold": 60}') is False

    # Test passing with result that equals threshold
    assert operator_validator(alert2, '{"op": "==", "threshold": 55}') is True

    # Test passing with result that equals decimal threshold
    assert operator_validator(alert2,
                              '{"op": ">", "threshold": 54.999}') is True
コード例 #4
0
def test_alert_observer_error_msg(setup_database, description, query):
    logger.info(description)
    db_session = setup_database
    alert = create_alert(db_session, query)
    observe(alert.id, db_session)
    assert alert.observations[-1].value is None
    assert alert.observations[-1].error_msg is not None
コード例 #5
0
def test_validate_observations_with_observe(setup_database, description, query,
                                            validator_type, config, expected):
    db_session = setup_database
    logger.info(description)

    alert = create_alert(db_session, query, validator_type, config)
    observe(alert.id, db_session)
    assert validate_observations(alert.id, alert.label, db_session) is expected
コード例 #6
0
def test_validate_observations(setup_database):
    db_session = setup_database

    # Test False on alert that shouldnt be triggered
    alert3 = create_alert(db_session, "SELECT 0", "not null", "{}")
    observe(alert3.id, db_session)
    assert validate_observations(alert3.id, alert3.label, db_session) is False

    # Test True on alert that should be triggered
    alert4 = create_alert(db_session, "SELECT 55", "operator",
                          '{"op": "<=", "threshold": 60}')
    observe(alert4.id, db_session)
    assert validate_observations(alert4.id, alert4.label, db_session) is True
コード例 #7
0
def evaluate_alert(
    alert_id: int,
    label: str,
    session: Session,
    recipients: Optional[str] = None,
    slack_channel: Optional[str] = None,
) -> None:
    """Processes an alert to see if it should be triggered"""

    logger.info("Processing alert ID: %i", alert_id)

    state = None
    dttm_start = datetime.utcnow()

    try:
        logger.info("Querying observers for alert <%s:%s>", alert_id, label)
        error_msg = observe(alert_id, session)
        if error_msg:
            state = AlertState.ERROR
            logging.error(error_msg)
    except Exception as exc:  # pylint: disable=broad-except
        state = AlertState.ERROR
        logging.exception(exc)
        logging.error("Failed at query observers for alert: %s (%s)", label,
                      alert_id)

    dttm_end = datetime.utcnow()

    if state != AlertState.ERROR:
        # Don't validate alert on test runs since it may not be triggered
        if recipients or slack_channel:
            deliver_alert(alert_id, session, recipients, slack_channel)
            state = AlertState.TRIGGER
        # Validate during regular workflow and deliver only if triggered
        elif validate_observations(alert_id, label, session):
            deliver_alert(alert_id, session, recipients, slack_channel)
            state = AlertState.TRIGGER
        else:
            state = AlertState.PASS

    session.commit()
    alert = session.query(Alert).get(alert_id)
    if state != AlertState.ERROR:
        alert.last_eval_dttm = dttm_end
    alert.last_state = state
    alert.logs.append(
        AlertLog(
            scheduled_dttm=dttm_start,
            dttm_start=dttm_start,
            dttm_end=dttm_end,
            state=state,
        ))
    session.commit()
コード例 #8
0
def test_not_null_validator(setup_database):
    dbsession = setup_database

    # Test passing SQLObserver with 'null' SQL result
    alert1 = create_alert(dbsession, "SELECT 0")
    observe(alert1.id, dbsession)
    assert not_null_validator(alert1.sql_observer[0], "{}") is False

    # Test passing SQLObserver with empty SQL result
    alert2 = create_alert(dbsession, "SELECT first FROM test_table WHERE first = -1")
    observe(alert2.id, dbsession)
    assert not_null_validator(alert2.sql_observer[0], "{}") is False

    # Test triggering alert with non-null SQL result
    alert3 = create_alert(dbsession, "SELECT 55")
    observe(alert3.id, dbsession)
    assert not_null_validator(alert3.sql_observer[0], "{}") is True
コード例 #9
0
def test_alert_observer(setup_database):
    dbsession = setup_database

    # Test SQLObserver with int SQL return
    alert1 = create_alert(dbsession, "SELECT 55")
    observe(alert1.id, dbsession)
    assert alert1.sql_observer[0].observations[-1].value == 55.0
    assert alert1.sql_observer[0].observations[-1].error_msg is None

    # Test SQLObserver with double SQL return
    alert2 = create_alert(dbsession, "SELECT 30.0 as wage")
    observe(alert2.id, dbsession)
    assert alert2.sql_observer[0].observations[-1].value == 30.0
    assert alert2.sql_observer[0].observations[-1].error_msg is None

    # Test SQLObserver with NULL result
    alert3 = create_alert(dbsession, "SELECT null as null_result")
    observe(alert3.id, dbsession)
    assert alert3.sql_observer[0].observations[-1].value is None
    assert alert3.sql_observer[0].observations[-1].error_msg is None

    # Test SQLObserver with empty SQL return
    alert4 = create_alert(dbsession,
                          "SELECT first FROM test_table WHERE first = -1")
    observe(alert4.id, dbsession)
    assert alert4.sql_observer[0].observations[-1].value is None
    assert alert4.sql_observer[0].observations[-1].error_msg is not None

    # Test SQLObserver with str result
    alert5 = create_alert(dbsession, "SELECT 'test_string' as string_value")
    observe(alert5.id, dbsession)
    assert alert5.sql_observer[0].observations[-1].value is None
    assert alert5.sql_observer[0].observations[-1].error_msg is not None

    # Test SQLObserver with two row result
    alert6 = create_alert(dbsession, "SELECT first FROM test_table")
    observe(alert6.id, dbsession)
    assert alert6.sql_observer[0].observations[-1].value is None
    assert alert6.sql_observer[0].observations[-1].error_msg is not None

    # Test SQLObserver with two column result
    alert7 = create_alert(
        dbsession, "SELECT first, second FROM test_table WHERE first = 1")
    observe(alert7.id, dbsession)
    assert alert7.sql_observer[0].observations[-1].value is None
    assert alert7.sql_observer[0].observations[-1].error_msg is not None
コード例 #10
0
def test_not_null_validator(setup_database, description, query, value):
    logger.info(description)
    db_session = setup_database
    alert = create_alert(db_session, query)
    observe(alert.id, db_session)
    assert not_null_validator(alert, "{}") is value
コード例 #11
0
def test_alert_observer(setup_database):
    db_session = setup_database

    # Test int SQL return
    alert1 = create_alert(db_session, "SELECT 55")
    observe(alert1.id, db_session)
    assert alert1.observations[-1].value == 55.0
    assert alert1.observations[-1].error_msg is None

    # Test double SQL return
    alert2 = create_alert(db_session, "SELECT 30.0 as wage")
    observe(alert2.id, db_session)
    assert alert2.observations[-1].value == 30.0
    assert alert2.observations[-1].error_msg is None

    # Test NULL result
    alert3 = create_alert(db_session, "SELECT null as null_result")
    observe(alert3.id, db_session)
    assert alert3.observations[-1].value is None
    assert alert3.observations[-1].error_msg is None

    # Test empty SQL return, expected
    alert4 = create_alert(db_session,
                          "SELECT first FROM test_table WHERE first = -1")
    observe(alert4.id, db_session)
    assert alert4.observations[-1].value is None
    assert alert4.observations[-1].error_msg is None

    # Test str result
    alert5 = create_alert(db_session, "SELECT 'test_string' as string_value")
    observe(alert5.id, db_session)
    assert alert5.observations[-1].value is None
    assert alert5.observations[-1].error_msg is not None

    # Test two row result
    alert6 = create_alert(db_session, "SELECT first FROM test_table")
    observe(alert6.id, db_session)
    assert alert6.observations[-1].value is None
    assert alert6.observations[-1].error_msg is not None

    # Test two column result
    alert7 = create_alert(
        db_session, "SELECT first, second FROM test_table WHERE first = 1")
    observe(alert7.id, db_session)
    assert alert7.observations[-1].value is None
    assert alert7.observations[-1].error_msg is not None

    # Test multiline sql
    alert8 = create_alert(
        db_session,
        """
        -- comment
        SELECT
            1 -- comment
        FROM test_table
            WHERE first = 1
        """,
    )
    observe(alert8.id, db_session)
    assert alert8.observations[-1].value == 1.0
    assert alert8.observations[-1].error_msg is None

    # Test jinja
    alert9 = create_alert(db_session, "SELECT {{ 2 }}")
    observe(alert9.id, db_session)
    assert alert9.observations[-1].value == 2.0
    assert alert9.observations[-1].error_msg is None