Commit 6298e582 authored by Łukasz Nowak's avatar Łukasz Nowak

promise: Implement total_seconds in check_surykatka_json

It is only checked when maximum-elapsed-time is passed and surykatka is
recent enough to report total_seconds.

Also improve reporting even more to provide readable information for those
massive promises with ERROR/OK mixed states.
parent 24b0d926
...@@ -138,7 +138,7 @@ class RunPromise(GenericPromise): ...@@ -138,7 +138,7 @@ class RunPromise(GenericPromise):
def senseHttpQuery(self): def senseHttpQuery(self):
key = 'http_query' key = 'http_query'
error_list = [] error = False
def appendError(msg, *args): def appendError(msg, *args):
self.appendErrorMessage(key + ': ERROR ' + msg % args) self.appendErrorMessage(key + ': ERROR ' + msg % args)
...@@ -155,7 +155,6 @@ class RunPromise(GenericPromise): ...@@ -155,7 +155,6 @@ class RunPromise(GenericPromise):
if len(entry_list) == 0: if len(entry_list) == 0:
appendError('No data for %s', url) appendError('No data for %s', url)
return return
error_list = []
for entry in entry_list: for entry in entry_list:
entry_status_code = str(entry['status_code']) entry_status_code = str(entry['status_code'])
if entry_status_code != status_code: if entry_status_code != status_code:
...@@ -166,17 +165,18 @@ class RunPromise(GenericPromise): ...@@ -166,17 +165,18 @@ class RunPromise(GenericPromise):
entry_status_code, status_code_explanation) entry_status_code, status_code_explanation)
else: else:
status_code_explanation = entry_status_code status_code_explanation = entry_status_code
error_list.append( appendError(
'IP %s got status code %s instead of %s' % ( '%s : IP %s got status code %s instead of %s' % (
entry['ip'], status_code_explanation, status_code)) url, entry['ip'], status_code_explanation, status_code))
error = True
db_ip_list = [q['ip'] for q in entry_list] db_ip_list = [q['ip'] for q in entry_list]
if len(ip_list): if len(ip_list):
if set(ip_list) != set(db_ip_list): if set(ip_list) != set(db_ip_list):
error_list.append( appendError(
'expected IPs %s differes from got %s' % ( '%s : expected IPs %s differes from got %s' % (
' '.join(ip_list), ' '.join(db_ip_list))) url, ' '.join(ip_list), ' '.join(db_ip_list)))
if len(error_list): error = True
appendError('%s : ' % (url,) + ', '.join(error_list)) if error:
return return
if len(ip_list) > 0: if len(ip_list) > 0:
self.appendInfoMessage( self.appendInfoMessage(
...@@ -187,6 +187,40 @@ class RunPromise(GenericPromise): ...@@ -187,6 +187,40 @@ class RunPromise(GenericPromise):
'%s: OK %s replied correctly with status code %s' % '%s: OK %s replied correctly with status code %s' %
(key, url, status_code)) (key, url, status_code))
def senseElapsedTime(self):
key = 'elapsed_time'
surykatka_key = 'http_query'
def appendError(msg, *args):
self.appendErrorMessage(key + ': ERROR ' + msg % args)
if surykatka_key not in self.surykatka_json:
appendError("%r not in %r", surykatka_key, self.json_file)
return
url = self.getConfig('url')
maximum_elapsed_time = self.getConfig('maximum-elapsed-time')
entry_list = [
q for q in self.surykatka_json[surykatka_key] if q['url'] == url]
if len(entry_list) == 0:
appendError('No data for %s', url)
return
for entry in entry_list:
if maximum_elapsed_time:
if 'total_seconds' in entry:
maximum_elapsed_time = float(maximum_elapsed_time)
if entry['total_seconds'] > maximum_elapsed_time:
appendError(
'%s : IP %s replied in %.2fs which is longer than '
'maximum %.2fs' %
(url, entry['ip'], entry['total_seconds'], maximum_elapsed_time))
else:
self.appendInfoMessage(
'%s: OK %s : IP %s replied in %.2fs which is shorter than '
'maximum %.2fs' % (key, url, entry['ip'],
entry['total_seconds'], maximum_elapsed_time))
def sense(self): def sense(self):
""" """
Check if frontend URL is available Check if frontend URL is available
...@@ -218,6 +252,7 @@ class RunPromise(GenericPromise): ...@@ -218,6 +252,7 @@ class RunPromise(GenericPromise):
elif report == 'http_query': elif report == 'http_query':
self.senseHttpQuery() self.senseHttpQuery()
self.senseSslCertificate() self.senseSslCertificate()
self.senseElapsedTime()
else: else:
self.appendErrorMessage( self.appendErrorMessage(
"ERROR Report %r is not supported" % report) "ERROR Report %r is not supported" % report)
......
...@@ -266,6 +266,199 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -266,6 +266,199 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
"Fri, 27 Dec 2019 15:11:12 -0000" "Fri, 27 Dec 2019 15:11:12 -0000"
) )
def test_maximum_elapsed_time(self):
self.writeSurykatkaPromise(
{
'report': 'http_query',
'json-file': self.json_file,
'url': 'https://www.erp5.com/',
'status-code': '302',
'ip-list': '127.0.0.1 127.0.0.2',
'maximum-elapsed-time': '5',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
}
)
self.writeSurykatkaJson("""{
"http_query": [
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.1",
"status_code": 302,
"url": "https://www.erp5.com/",
"total_seconds": 4
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.2",
"status_code": 302,
"url": "https://www.erp5.com/",
"total_seconds": 4
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "176.31.129.213",
"status_code": 200,
"url": "https://www.erp5.org/",
"total_seconds": 4
}
],
"ssl_certificate": [
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.1",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
},
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.2",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
}
]
}
""")
self.configureLauncher()
self.launcher.run()
self.assertPassedMessage(
self.getPromiseResult(self.promise_name),
"http_query: OK https://www.erp5.com/ replied correctly with status "
"code 302 on ip list 127.0.0.1 127.0.0.2 ssl_certificate: OK "
"Certificate for https://www.erp5.com/ will expire on Mon, 13 Jul 2020 "
"12:00:00 -0000, which is more than 15 days, UTC now is Fri, 27 Dec "
"2019 15:11:12 -0000 elapsed_time: OK https://www.erp5.com/ : IP "
"127.0.0.1 replied in 4.00s which is shorter than maximum 5.00s "
"elapsed_time: OK https://www.erp5.com/ : IP 127.0.0.2 replied in "
"4.00s which is shorter than maximum 5.00s"
)
def test_maximum_elapsed_time_too_long(self):
self.writeSurykatkaPromise(
{
'report': 'http_query',
'json-file': self.json_file,
'url': 'https://www.erp5.com/',
'status-code': '302',
'ip-list': '127.0.0.1 127.0.0.2',
'maximum-elapsed-time': '5',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
}
)
self.writeSurykatkaJson("""{
"http_query": [
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.1",
"status_code": 302,
"url": "https://www.erp5.com/",
"total_seconds": 6
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.2",
"status_code": 302,
"url": "https://www.erp5.com/",
"total_seconds": 4
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "176.31.129.213",
"status_code": 200,
"url": "https://www.erp5.org/",
"total_seconds": 4
}
],
"ssl_certificate": [
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.1",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
},
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.2",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
}
]
}
""")
self.configureLauncher()
with self.assertRaises(PromiseError):
self.launcher.run()
self.assertFailedMessage(
self.getPromiseResult(self.promise_name),
"elapsed_time: ERROR https://www.erp5.com/ : IP 127.0.0.1 replied in "
"6.00s which is longer than maximum 5.00s http_query: OK "
"https://www.erp5.com/ replied correctly with status code 302 on ip "
"list 127.0.0.1 127.0.0.2 ssl_certificate: OK Certificate for "
"https://www.erp5.com/ will expire on Mon, 13 Jul 2020 12:00:00 -0000, "
"which is more than 15 days, UTC now is Fri, 27 Dec 2019 15:11:12 "
"-0000 elapsed_time: OK https://www.erp5.com/ : IP 127.0.0.2 replied "
"in 4.00s which is shorter than maximum 5.00s"
)
def test_maximum_elapsed_time_no_total_seconds(self):
self.writeSurykatkaPromise(
{
'report': 'http_query',
'json-file': self.json_file,
'url': 'https://www.erp5.com/',
'status-code': '302',
'ip-list': '127.0.0.1 127.0.0.2',
'maximum-elapsed-time': '5',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
}
)
self.writeSurykatkaJson("""{
"http_query": [
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.1",
"status_code": 302,
"url": "https://www.erp5.com/"
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "127.0.0.2",
"status_code": 302,
"url": "https://www.erp5.com/"
},
{
"date": "Wed, 11 Dec 2019 09:35:28 -0000",
"ip": "176.31.129.213",
"status_code": 200,
"url": "https://www.erp5.org/"
}
],
"ssl_certificate": [
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.1",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
},
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.2",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
}
]
}
""")
self.configureLauncher()
self.launcher.run()
self.assertPassedMessage(
self.getPromiseResult(self.promise_name),
"http_query: OK https://www.erp5.com/ replied correctly with status "
"code 302 on ip list 127.0.0.1 127.0.0.2 ssl_certificate: OK "
"Certificate for https://www.erp5.com/ will expire on Mon, 13 Jul "
"2020 12:00:00 -0000, which is more than 15 days, UTC now is Fri, 27 "
"Dec 2019 15:11:12 -0000"
)
def test_http(self): def test_http(self):
self.writeSurykatkaPromise( self.writeSurykatkaPromise(
{ {
...@@ -402,10 +595,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -402,10 +595,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
self.assertFailedMessage( self.assertFailedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: ERROR No data for https://www.erp5.com/ ssl_certificate: " "http_query: ERROR No data for https://www.erp5.com/ elapsed_time: "
"OK Certificate for https://www.erp5.com/ will expire on Mon, 13 Jul " "ERROR No data for https://www.erp5.com/ ssl_certificate: OK "
"2020 12:00:00 -0000, which is more than 15 days, UTC now is " "Certificate for https://www.erp5.com/ will expire on Mon, 13 Jul 2020 "
"Fri, 27 Dec 2019 15:11:12 -0000" "12:00:00 -0000, which is more than 15 days, UTC now is Fri, 27 Dec "
"2019 15:11:12 -0000"
) )
def test_no_ssl_certificate_data(self): def test_no_ssl_certificate_data(self):
...@@ -730,10 +924,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -730,10 +924,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
self.assertFailedMessage( self.assertFailedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: ERROR https://www.erp5.com/ : IP 127.0.0.1 got " "http_query: ERROR https://www.erp5.com/ : IP 127.0.0.1 got status "
"status code 302 instead of 301, expected IPs 127.0.0.1 127.0.0.2 " "code 302 instead of 301 http_query: ERROR https://www.erp5.com/ : "
"differes from got 127.0.0.1 127.0.0.4 ssl_certificate: OK Certificate " "expected IPs 127.0.0.1 127.0.0.2 differes from got 127.0.0.1 "
"for https://www.erp5.com/ will expire on Mon, 13 Jul 2020 12:00:00 " "127.0.0.4 ssl_certificate: OK Certificate for https://www.erp5.com/ "
"-0000, which is more than 15 days, UTC now is Fri, 27 Dec 2019 " "will expire on Mon, 13 Jul 2020 12:00:00 -0000, which is more than 15 "
"15:11:12 -0000" "days, UTC now is Fri, 27 Dec 2019 15:11:12 -0000"
) )
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment