Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve test coverage of tencentsms.py #479

Merged
merged 7 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- Add missing show_ssl_warn and silence_qk_value params to docs - [#469](https://github.com/jertel/elastalert2/pull/469) - @jertel
- [OpsGenie] Clarify documentation for URL endpoint to use in European region - [#475](https://github.com/jertel/elastalert2/pull/475) - @nsano-rururu
- [Docs] The documentation has been updated as the name of Amazon Elasticsearch Service has changed to Amazon OpenSearch Service. - [#478](https://github.com/jertel/elastalert2/pull/478) - @nsano-rururu
- [Tests] Improve test coverage of tencentsms.py - [#479](https://github.com/jertel/elastalert2/pull/479) - @liuxingjun

# 2.2.1

Expand Down
63 changes: 34 additions & 29 deletions elastalert/alerters/tencentsms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models
from tencentcloud.sms.v20210111 import models
from tencentcloud.sms.v20210111.sms_client import SmsClient
from jsonpointer import resolve_pointer


Expand Down Expand Up @@ -41,33 +42,7 @@ def __init__(self, *args):
def alert(self, matches):
try:
elastalert_logger.debug("matches:%s", json.dumps(matches))
# Required steps:
# Instantiate an authentication object. The Tencent Cloud account key pair `secretId` and `secretKey` need to be passed in as the input parameters.
# The example here uses the way to read from the environment variable, so you need to set these two values in the environment variable first.
# You can also write the key pair directly into the code, but be careful not to copy, upload, or share the code to others;
# otherwise, the key pair may be leaked, causing damage to your properties.
# Query the CAM key: https://console.cloud.tencent.com/cam/capi
cred = credential.Credential(self.tencent_sms_secret_id, self.tencent_sms_secret_key)
# cred = credential.Credential(
# os.environ.get(""),
# os.environ.get("")
# )
# (Optional) Instantiate an HTTP option
httpProfile = HttpProfile()
# If you need to specify the proxy for API access, you can initialize HttpProfile as follows
# httpProfile = HttpProfile(proxy="http://username:password@proxy IP:proxy port")
httpProfile.reqMethod = "POST" # POST request (POST request by default)
httpProfile.reqTimeout = 30 # Request timeout period in seconds (60 seconds by default)
httpProfile.endpoint = "sms.tencentcloudapi.com" # Specify the access region domain name (nearby access by default)
# Optional steps:
# Instantiate a client configuration object. You can specify the timeout period and other configuration items
clientProfile = ClientProfile()
clientProfile.signMethod = "TC3-HMAC-SHA256" # Specify the signature algorithm
clientProfile.language = "en-US"
clientProfile.httpProfile = httpProfile
# Instantiate the client object of the requested product (with SMS as an example)
# The second parameter is the region information. You can directly enter the string `ap-guangzhou` or import the preset constant
client = sms_client.SmsClient(cred, self.tencent_sms_region, clientProfile)
client = self.get_client()
# Instantiate a request object. You can further set the request parameters according to the API called and actual conditions
# You can directly check the SDK source code to determine which attributes of `SendSmsRequest` can be set
# An attribute may be of a basic type or import another data structure
Expand Down Expand Up @@ -121,11 +96,41 @@ def alert(self, matches):
elastalert_logger.debug("SendSms response :%s", resp.to_json_string())
for item in resp.SendStatusSet:
if item.Code != "Ok":
raise EAException(json.dumps(item.__dict__))
raise TencentCloudSDKException(item.Code, item.Message, resp.RequestId)
except TencentCloudSDKException as e:
raise EAException("Error posting to TencentSMS: %s" % e)
elastalert_logger.info("Alert sent to TencentSMS")

def get_client(self):
# Required steps:
# Instantiate an authentication object. The Tencent Cloud account key pair `secretId` and `secretKey` need to be passed in as the input parameters.
# The example here uses the way to read from the environment variable, so you need to set these two values in the environment variable first.
# You can also write the key pair directly into the code, but be careful not to copy, upload, or share the code to others;
# otherwise, the key pair may be leaked, causing damage to your properties.
# Query the CAM key: https://console.cloud.tencent.com/cam/capi
cred = credential.Credential(self.tencent_sms_secret_id, self.tencent_sms_secret_key)
# cred = credential.Credential(
# os.environ.get(""),
# os.environ.get("")
# )
# (Optional) Instantiate an HTTP option
httpProfile = HttpProfile()
# If you need to specify the proxy for API access, you can initialize HttpProfile as follows
# httpProfile = HttpProfile(proxy="http://username:password@proxy IP:proxy port")
httpProfile.reqMethod = "POST" # POST request (POST request by default)
httpProfile.reqTimeout = 30 # Request timeout period in seconds (60 seconds by default)
httpProfile.endpoint = "sms.tencentcloudapi.com" # Specify the access region domain name (nearby access by default)
# Optional steps:
# Instantiate a client configuration object. You can specify the timeout period and other configuration items
clientProfile = ClientProfile()
clientProfile.signMethod = "TC3-HMAC-SHA256" # Specify the signature algorithm
clientProfile.language = "en-US"
clientProfile.httpProfile = httpProfile
# Instantiate the client object of the requested product (with SMS as an example)
# The second parameter is the region information. You can directly enter the string `ap-guangzhou` or import the preset constant
client = SmsClient(cred, self.tencent_sms_region, clientProfile)
return client

def create_template_parm(self, matches):
esData = matches[0]
templateParam = []
Expand Down
156 changes: 120 additions & 36 deletions tests/alerters/tencentsms_test.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
import logging
import pytest
from unittest import mock
from elastalert.alerters.tencentsms import TencentSMSAlerter
from elastalert.loaders import FileRulesLoader
from elastalert.util import EAException


def test_tencentsms_alert(caplog):
caplog.set_level(logging.DEBUG)
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",
"tencent_sms_template_parm": [
"/kubernetes/pod_name"
]
}

match = {
"kubernetes": {
"namespace_name": "nginx",
"pod_name": "ngin.nginx-6bd96d6f74-2ts4x"
},
'@timestamp': '2014-01-01T00:00:00',
"message": "2021-09-03T14:34:08+0000|INFO|vector eps : 192.168.0.2:10000,",
}

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

with pytest.raises(EAException) as ea:
alert = TencentSMSAlerter(rule)
alert.alert([match])
assert 'The SecretId is not found' in str(ea)
from tencentcloud.sms.v20210111 import models


def test_tencentsms_get_info():
Expand Down Expand Up @@ -152,3 +118,121 @@ def test_tencentsms_required_error(key, val, expected_data):
assert expected_data == actual_data
except Exception as ea:
assert expected_data in str(ea)


@pytest.mark.parametrize('tencent_sms_to_number, send_status_code', [
('+8613711112222', 'Ok')
])
def test_tencentsms_alert(tencent_sms_to_number, send_status_code):
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": [
tencent_sms_to_number
],
"tencent_sms_template_id": "1123835"
}
match = {
'@timestamp': '2014-01-01T00:00:00',
"message": "2021-09-03T14:34:08+0000|INFO|vector eps : 192.168.0.2:10000,",
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
with mock.patch('elastalert.alerters.tencentsms.SmsClient.SendSms') as mock_client:
model = models.SendSmsResponse()
model._deserialize({
"SendStatusSet": [
{
"SerialNo": "5000:1045710669157053657849499619",
"PhoneNumber": tencent_sms_to_number,
"Fee": 1,
"SessionContext": "test",
"Code": send_status_code,
"Message": "send success",
"IsoCode": "CN"
}
],
"RequestId": "a0aabda6-cf91-4f3e-a81f-9198114a2279"
})

mock_client.return_value = model
alert = TencentSMSAlerter(rule)
alert.alert([match])
assert mock_client.return_value == model


@pytest.mark.parametrize('tencent_sms_to_number, send_status_code', [
('+8613711112222', 'FailedOperation.PhoneNumberInBlacklist')
])
def test_tencentsms_alert_status(tencent_sms_to_number, send_status_code):
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": [
tencent_sms_to_number
],
"tencent_sms_template_id": "1123835"
}

match = {
'@timestamp': '2014-01-01T00:00:00',
"message": "2021-09-03T14:34:08+0000|INFO|vector eps : 192.168.0.2:10000,",
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
model = models.SendSmsResponse()
model._deserialize({
"SendStatusSet": [
{
"SerialNo": "5000:1045710669157053657849499619",
"PhoneNumber": tencent_sms_to_number,
"Fee": 1,
"SessionContext": "test",
"Code": send_status_code,
"Message": "send success",
"IsoCode": "CN"
}
],
"RequestId": "a0aabda6-cf91-4f3e-a81f-9198114a2279"
})
with pytest.raises(EAException) as ea:
with mock.patch('elastalert.alerters.tencentsms.SmsClient.SendSms') as mock_client:
mock_client.return_value = model
alert = TencentSMSAlerter(rule)
alert.alert([match])
assert mock_client.return_value == model
assert 'Error posting to TencentSMS:' in str(ea)


def test_tencentsms_alert_secret_id_error(caplog):
caplog.set_level(logging.DEBUG)
with pytest.raises(EAException) as ea:
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",
}
match = {
'@timestamp': '2014-01-01T00:00:00',
"message": "2021-09-03T14:34:08+0000|INFO|vector eps : 192.168.0.2:10000,",
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = TencentSMSAlerter(rule)
alert.alert([match])
assert 'The SecretId is not found' in str(ea)