Esempio n. 1
0
def test_victorops_getinfo():
    rule = {
        'name': 'Test VictorOps Rule',
        'type': 'any',
        'victorops_api_key': 'xxxx1',
        'victorops_routing_key': 'xxxx2',
        'victorops_message_type': 'INFO',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = VictorOpsAlerter(rule)

    expected_data = {'type': 'victorops', 'victorops_routing_key': 'xxxx2'}
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 2
0
def test_alertmanager_required_error(alertmanager_hosts, expected_data):
    try:
        rule = {'name': 'Test Alertmanager Rule', 'type': 'any', 'alert': []}

        if alertmanager_hosts:
            rule['alertmanager_hosts'] = alertmanager_hosts

        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = AlertmanagerAlerter(rule)

        actual_data = alert.get_info()
        assert expected_data == actual_data
    except Exception as ea:
        print('ea %s' % str(ea))
        assert expected_data in str(ea)
Esempio n. 3
0
def test_mattermost_author_icon():
    rule = {
        'name': 'Test Mattermost Rule',
        'type': 'any',
        'alert_text_type': 'alert_text_only',
        'mattermost_webhook_url': 'http://xxxxx',
        'mattermost_msg_pretext': 'aaaaa',
        'mattermost_msg_color': 'danger',
        'mattermost_author_icon': 'http://author.icon.url',
        'alert': [],
        'alert_subject': 'Test Mattermost'
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = MattermostAlerter(rule)
    match = {
        '@timestamp': '2021-01-01T00:00:00',
        'somefield': 'foobarbaz'
    }
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])

    expected_data = {
        'attachments': [
            {
                'fallback': 'Test Mattermost: aaaaa',
                'color': 'danger',
                'title': 'Test Mattermost',
                'pretext': 'aaaaa',
                'fields': [],
                'text': 'Test Mattermost Rule\n\n',
                'author_icon': 'http://author.icon.url'
            }
        ],
        'username': '******'
    }

    mock_post_request.assert_called_once_with(
        rule['mattermost_webhook_url'],
        data=mock.ANY,
        headers={'content-type': 'application/json'},
        verify=True,
        proxies=None
    )

    actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
    assert expected_data == actual_data
Esempio n. 4
0
def test_pagerduty_alerter_v2_payload_class_args():
    rule = {
        'name': 'Test PD Rule',
        'type': 'any',
        'pagerduty_service_key': 'magicalbadgers',
        'pagerduty_client_name': 'ponies inc.',
        'pagerduty_api_version': 'v2',
        'pagerduty_v2_payload_class': 'somefield',
        'pagerduty_v2_payload_class_args': ['@timestamp', 'somefield'],
        'pagerduty_v2_payload_component': 'mysql',
        'pagerduty_v2_payload_group': 'app-stack',
        'pagerduty_v2_payload_severity': 'error',
        'pagerduty_v2_payload_source': 'mysql.host.name',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = PagerDutyAlerter(rule)
    match = {'@timestamp': '2017-01-01T00:00:00', 'somefield': 'foobarbaz'}
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])
    expected_data = {
        'client': 'ponies inc.',
        'payload': {
            'class': 'somefield',
            'component': 'mysql',
            'group': 'app-stack',
            'severity': 'error',
            'source': 'mysql.host.name',
            'summary': 'Test PD Rule',
            'custom_details': {
                'information':
                'Test PD Rule\n\n@timestamp: 2017-01-01T00:00:00\nsomefield: foobarbaz\n'
            },
            'timestamp': '2017-01-01T00:00:00'
        },
        'event_action': 'trigger',
        'dedup_key': '',
        'routing_key': 'magicalbadgers',
    }
    mock_post_request.assert_called_once_with(
        'https://events.pagerduty.com/v2/enqueue',
        data=mock.ANY,
        headers={'content-type': 'application/json'},
        proxies=None)
    assert expected_data == json.loads(
        mock_post_request.call_args_list[0][1]['data'])
Esempio n. 5
0
def test_mattermost_kibana_discover_color():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'alert_text_type': 'alert_text_only',
        'mattermost_attach_kibana_discover_url': True,
        'mattermost_kibana_discover_color': 'blue',
        'mattermost_webhook_url': 'http://please.dontgohere.mattermost',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = MattermostAlerter(rule)
    match = {
        '@timestamp': '2021-01-01T00:00:00',
        'kibana_discover_url': 'http://localhost:5601/app/discover#/'
    }
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])

    expected_data = {
        'attachments': [
            {
                'fallback': 'Test Rule: ',
                'color': 'danger',
                'title': 'Test Rule',
                'pretext': '',
                'fields': [],
                'text': 'Test Rule\n\n'
            },
            {
                'color': 'blue',
                'title': 'Discover in Kibana',
                'title_link': 'http://localhost:5601/app/discover#/'
            }
        ], 'username': '******'
    }
    mock_post_request.assert_called_once_with(
        rule['mattermost_webhook_url'],
        data=mock.ANY,
        headers={'content-type': 'application/json'},
        verify=True,
        proxies=None
    )

    actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
    assert expected_data == actual_data
Esempio n. 6
0
def test_gitter_getinfo():
    rule = {
        'name': 'Test Gitter Rule',
        'type': 'any',
        'gitter_webhook_url': 'https://webhooks.gitter.im/e/xxxxx',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = GitterAlerter(rule)

    expected_data = {
        'type': 'gitter',
        'gitter_webhook_url': 'https://webhooks.gitter.im/e/xxxxx'
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 7
0
def test_alertmanager_ea_exception():
    with pytest.raises(EAException) as ea:
        rule = {
            'name': 'Test Alertmanager Rule',
            'type': 'any',
            'alertmanager_hosts': ['http://*****:*****@timestamp': '2021-01-01T00:00:00', 'somefield': 'foobarbaz'}
        mock_run = mock.MagicMock(side_effect=RequestException)
        with mock.patch('requests.post',
                        mock_run), pytest.raises(RequestException):
            alert.alert([match])
    assert 'Error posting to Alertmanager' in str(ea)
Esempio n. 8
0
def test_slack_title_link():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'slack_webhook_url': 'http://please.dontgohere.slack',
        'slack_username_override': 'elastalert',
        'slack_title_link': 'http://slack.title.link',
        'alert_subject': 'Cool subject',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = SlackAlerter(rule)
    match = {
        '@timestamp': '2016-01-01T00:00:00',
        'somefield': 'foobarbaz'
    }
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])

    expected_data = {
        'username': '******',
        'channel': '',
        'icon_emoji': ':ghost:',
        'attachments': [
            {
                'color': 'danger',
                'title': rule['alert_subject'],
                'text': BasicMatchString(rule, match).__str__(),
                'mrkdwn_in': ['text', 'pretext'],
                'fields': [],
                'title_link': 'http://slack.title.link'
            }
        ],
        'text': '',
        'parse': 'none'
    }
    mock_post_request.assert_called_once_with(
        rule['slack_webhook_url'],
        data=mock.ANY,
        headers={'content-type': 'application/json'},
        proxies=None,
        verify=True,
        timeout=10
    )
    assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])
Esempio n. 9
0
def test_rocket_chat_ca_certs(ca_certs, ignore_ssl_errors, excpet_verify):
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'rocket_chat_webhook_url': 'http://please.dontgohere.rocketchat',
        'alert_subject': 'Cool subject',
        'alert': []
    }
    if ca_certs:
        rule['rocket_chat_ca_certs'] = ca_certs

    if ignore_ssl_errors:
        rule['rocket_chat_ignore_ssl_errors'] = ignore_ssl_errors

    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = RocketChatAlerter(rule)
    match = {'@timestamp': '2017-01-01T00:00:00', 'somefield': 'foobarbaz'}
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])

    expected_data = {
        'username':
        '******',
        'channel':
        '',
        'emoji':
        ':ghost:',
        'attachments': [{
            'color': 'danger',
            'title': 'Cool subject',
            'text': BasicMatchString(rule, match).__str__(),
            'fields': []
        }],
        'text':
        ''
    }
    mock_post_request.assert_called_once_with(
        rule['rocket_chat_webhook_url'],
        data=mock.ANY,
        headers={'content-type': 'application/json'},
        proxies=None,
        verify=excpet_verify,
        timeout=10)
    assert expected_data == json.loads(
        mock_post_request.call_args_list[0][1]['data'])
Esempio n. 10
0
def test_discord(caplog):
    caplog.set_level(logging.INFO)
    rule = {
        'name': 'Test Discord Rule',
        'type': 'any',
        'discord_webhook_url': 'http://xxxxxxx',
        'discord_emoji_title': ':warning:',
        'discord_embed_color': 0xffffff,
        'discord_embed_footer': 'footer',
        'discord_embed_icon_url': 'http://xxxx/image.png',
        'alert': [],
        'alert_subject': 'Test Discord'
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = DiscordAlerter(rule)
    match = {'@timestamp': '2021-01-01T00:00:00', 'somefield': 'foobarbaz'}
    with mock.patch('requests.post') as mock_post_request:
        alert.alert([match])

    expected_data = {
        'content':
        ':warning: Test Discord :warning:',
        'embeds': [{
            'description':
            'Test Discord Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
            'color': 0xffffff,
            'footer': {
                'text': 'footer',
                'icon_url': 'http://xxxx/image.png'
            }
        }]
    }

    mock_post_request.assert_called_once_with(
        rule['discord_webhook_url'],
        data=mock.ANY,
        headers={'Content-Type': 'application/json'},
        proxies=None,
        auth=None)

    actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
    assert expected_data == actual_data
    assert (
        'elastalert', logging.INFO,
        'Alert sent to the webhook http://xxxxxxx') == caplog.record_tuples[0]
Esempio n. 11
0
def test_file_rules_loader_get_names_recursive():
    conf = {'scan_subdirectories': True, 'rules_folder': 'root'}
    rules_loader = FileRulesLoader(conf)
    walk_paths = (('root', ['folder_a', 'folder_b'], ('rule.yaml', )),
                  ('root/folder_a', [],
                   ('a.yaml', 'ab.yaml')), ('root/folder_b', [], ('b.yaml', )))
    with mock.patch('os.walk') as mock_walk:
        mock_walk.return_value = walk_paths
        paths = rules_loader.get_names(conf)

    paths = [p.replace(os.path.sep, '/') for p in paths]

    assert 'root/rule.yaml' in paths
    assert 'root/folder_a/a.yaml' in paths
    assert 'root/folder_a/ab.yaml' in paths
    assert 'root/folder_b/b.yaml' in paths
    assert len(paths) == 4
def test_file_rules_loader_get_names():
    # Check for no subdirectory
    conf = {'scan_subdirectories': False, 'rules_folder': 'root'}
    rules_loader = FileRulesLoader(conf)
    files = ['badfile', 'a.yaml', 'b.yaml']

    with mock.patch('os.listdir') as mock_list:
        with mock.patch('os.path.isfile') as mock_path:
            mock_path.return_value = True
            mock_list.return_value = files
            paths = rules_loader.get_names(conf)

    paths = [p.replace(os.path.sep, '/') for p in paths]

    assert 'root/a.yaml' in paths
    assert 'root/b.yaml' in paths
    assert len(paths) == 2
Esempio n. 13
0
def test_google_chat_getinfo():
    rule = {
        'name': 'Test GoogleChat Rule',
        'type': 'any',
        'googlechat_webhook_url': 'http://xxxxxxx',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = GoogleChatAlerter(rule)

    expected_data = {
        'type': 'googlechat',
        'googlechat_webhook_url': ['http://xxxxxxx']
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 14
0
def test_http_getinfo():
    rule = {
        'name': 'Test HTTP Post Alerter Without Payload',
        'type': 'any',
        'http_post_url': 'http://test.webhook.url',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = HTTPPostAlerter(rule)

    expected_data = {
        'type': 'http_post',
        'http_post_webhook_url': ['http://test.webhook.url']
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 15
0
def test_google_chat_ea_exception():
    with pytest.raises(EAException) as ea:
        rule = {
            'name': 'Test GoogleChat Rule',
            'type': 'any',
            'googlechat_webhook_url': 'http://xxxxxxx',
            'alert': []
        }
        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = GoogleChatAlerter(rule)
        match = {'@timestamp': '2021-01-01T00:00:00', 'somefield': 'foobarbaz'}
        mock_run = mock.MagicMock(side_effect=RequestException)
        with mock.patch('requests.post',
                        mock_run), pytest.raises(RequestException):
            alert.alert([match])
    assert 'Error posting to google chat: ' in str(ea)
Esempio n. 16
0
def test_thehive_getinfo(hive_host, expect):
    rule = {
        'alert': [],
        'alert_text': '',
        'alert_text_type': 'alert_text_only',
        'description': 'test',
        'hive_alert_config': {
            'customFields': [{
                'name': 'test',
                'type': 'string',
                'value': 'test.ip'
            }],
            'follow':
            True,
            'severity':
            2,
            'source':
            'elastalert',
            'status':
            'New',
            'tags': ['test.ip'],
            'tlp':
            3,
            'type':
            'external'
        },
        'hive_connection': {
            'hive_apikey': '',
            'hive_host': hive_host,
            'hive_port': 9000
        },
        'hive_observable_data_mapping': [{
            'ip': 'test.ip'
        }],
        'name': 'test-thehive',
        'tags': ['a', 'b'],
        'type': 'any'
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = HiveAlerter(rule)

    expected_data = expect
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 17
0
def test_stomp_getinfo():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'alert_subject': 'Cool subject',
        'stomp_hostname': 'localhost',
        'stomp_hostport': '61613',
        'stomp_login': '******',
        'stomp_password': '******',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = StompAlerter(rule)

    expected_data = {'type': 'stomp'}
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 18
0
def test_ses_getinfo():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'alert_subject': 'Cool subject',
        'ses_from_addr': '*****@*****.**',
        'ses_email': '*****@*****.**',
        'ses_aws_access_key_id': 'access key id',
        'ses_aws_secret_access_key': 'secret access key',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = SesAlerter(rule)

    expected_data = {'type': 'ses', 'recipients': ['*****@*****.**']}
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 19
0
def test_ses_required_error(ses_email, ses_from_addr, expected_data):
    try:
        rule = {'name': 'Test Telegram Rule', 'type': 'any', 'alert': []}

        if ses_email:
            rule['ses_email'] = ses_email

        if ses_from_addr:
            rule['ses_from_addr'] = ses_from_addr

        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = SesAlerter(rule)

        actual_data = alert.get_info()
        assert expected_data == actual_data
    except Exception as ea:
        assert expected_data in str(ea)
Esempio n. 20
0
def test_twilio_getinfo():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'alert_subject': 'Cool subject',
        'twilio_account_sid': 'xxxxx1',
        'twilio_auth_token': 'xxxxx2',
        'twilio_to_number': 'xxxxx3',
        'twilio_from_number': 'xxxxx4',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = TwilioAlerter(rule)

    expected_data = {'type': 'twilio', 'twilio_client_name': 'xxxxx4'}
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 21
0
def test_line_notify_ea_exception():
    with pytest.raises(EAException) as ea:
        rule = {
            'name': 'Test LineNotify Rule',
            'type': 'any',
            'linenotify_access_token': 'xxxxx',
            'alert': []
        }
        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = LineNotifyAlerter(rule)
        match = {'@timestamp': '2021-01-01T00:00:00', 'somefield': 'foobarbaz'}
        mock_run = mock.MagicMock(side_effect=RequestException)
        with mock.patch('requests.post',
                        mock_run), pytest.raises(RequestException):
            alert.alert([match])

    assert 'Error posting to Line Notify: ' in str(ea)
Esempio n. 22
0
def test_slack_getinfo():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'slack_webhook_url': 'http://please.dontgohere.slack',
        'alert_subject': 'Cool subject',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = SlackAlerter(rule)

    expected_data = {
        'type': 'slack',
        'slack_username_override': 'elastalert'
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 23
0
def test_telegram_ea_exception():
    with pytest.raises(EAException) as ea:
        rule = {
            'name': 'Test Telegram Rule',
            'type': 'any',
            'telegram_bot_token': 'xxxxx1',
            'telegram_room_id': 'xxxxx2',
            'alert': []
        }
        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = TelegramAlerter(rule)
        match = {'@timestamp': '2021-01-01T00:00:00', 'somefield': 'foobarbaz'}
        mock_run = mock.MagicMock(side_effect=RequestException)
        with mock.patch('requests.post',
                        mock_run), pytest.raises(RequestException):
            alert.alert([match])
    assert 'Error posting to Telegram: . Details: ' in str(ea)
Esempio n. 24
0
def test_http_alerter_post_ea_exception():
    with pytest.raises(EAException) as ea:
        rule = {
            'name': 'Test HTTP Post Alerter Without Payload',
            'type': 'any',
            'http_post2_url': 'http://test.webhook.url',
            'http_post2_ca_certs': False,
            'alert': []
        }
        rules_loader = FileRulesLoader({})
        rules_loader.load_modules(rule)
        alert = HTTPPost2Alerter(rule)
        match = {'@timestamp': '2017-01-01T00:00:00', 'somefield': 'foobarbaz'}
        mock_run = mock.MagicMock(side_effect=RequestException)
        with mock.patch('requests.post',
                        mock_run), pytest.raises(RequestException):
            alert.alert([match])
    assert 'Error posting HTTP Post 2 alert: ' in str(ea)
Esempio n. 25
0
def test_ms_teams_getinfo():
    rule = {
        'name': 'Test Rule',
        'type': 'any',
        'ms_teams_webhook_url': 'http://test.webhook.url',
        'alert_subject': 'Cool subject',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = MsTeamsAlerter(rule)

    expected_data = {
        'type': 'ms_teams',
        'ms_teams_webhook_url': ['http://test.webhook.url']
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 26
0
def test_discord_getinfo():
    rule = {
        'name': 'Test Discord Rule' + ('a' * 2069),
        'type': 'any',
        'discord_webhook_url': 'http://xxxxxxx',
        'alert': [],
        'alert_subject': 'Test Discord'
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = DiscordAlerter(rule)

    expected_data = {
        'type': 'discord',
        'discord_webhook_url': 'http://xxxxxxx'
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 27
0
def test_tencentsms_get_info():
    rule = {
        'name': 'Test tencentsms Template Parm',
        'type': 'any',
        'alert': ["tencent_sms"],
        "tencent_sms_secret_id": "secret_id",
        "tencent_sms_secret_key": "secret_key",
        "tencent_sms_sdk_appid": "1400006666",
        "tencent_sms_to_number": ["+8613711112222"],
        "tencent_sms_template_id": "1123835"
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = TencentSMSAlerter(rule)

    excepted = {'type': 'tencent sms', 'to_number': ["+8613711112222"]}
    actual = alert.get_info()
    assert excepted == actual
def test_import_filter():
    # Check that if a filter is specified the rules are merged:

    rules_loader = FileRulesLoader(test_config)
    import_rule = copy.deepcopy(test_rule)
    del(import_rule['es_host'])
    del(import_rule['es_port'])
    import_rule['import'] = 'importme.ymlt'
    import_me = {
        'es_host': 'imported_host',
        'es_port': 12349,
        'filter': [{'term': {'ratchet': 'clank'}}],
    }

    with mock.patch.object(rules_loader, 'get_yaml') as mock_open:
        mock_open.side_effect = [import_rule, import_me]
        rules = rules_loader.load_configuration('blah.yaml', test_config)
        assert rules['filter'] == [{'term': {'ratchet': 'clank'}}, {'term': {'key': 'value'}}]
Esempio n. 29
0
def test_pagerduty_getinfo():
    rule = {
        'name': 'Test PD Rule',
        'type': 'any',
        'pagerduty_service_key': 'magicalbadgers',
        'pagerduty_client_name': 'ponies inc.',
        'alert': []
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = PagerDutyAlerter(rule)

    expected_data = {
        'type': 'pagerduty',
        'pagerduty_client_name': 'ponies inc.'
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data
Esempio n. 30
0
def test_dingtalk_getinfo():
    rule = {
        'name': 'Test DingTalk Rule',
        'type': 'any',
        'dingtalk_access_token': 'xxxxxxx',
        'alert': [],
        'alert_subject': 'Test DingTalk'
    }
    rules_loader = FileRulesLoader({})
    rules_loader.load_modules(rule)
    alert = DingTalkAlerter(rule)

    expected_data = {
        'type': 'dingtalk',
        "dingtalk_webhook_url": 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxx'
    }
    actual_data = alert.get_info()
    assert expected_data == actual_data