mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 18:02:41 +02:00
🔀 Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
7c485a4ad9
4 changed files with 112 additions and 1 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
- ✨ — Add new check types: body-like, headers-like and json-like (#58)
|
||||||
|
|
||||||
## 0.3.0
|
## 0.3.0
|
||||||
|
|
||||||
Date: 2024-09-02
|
Date: 2024-09-02
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Define the available checks"""
|
"""Define the available checks"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from jsonpointer import resolve_pointer, JsonPointerException
|
from jsonpointer import resolve_pointer, JsonPointerException
|
||||||
|
@ -110,6 +111,36 @@ class HTTPHeadersHave(BaseCheck):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPHeadersLike(BaseCheck):
|
||||||
|
"""Checks that response headers contains the expected headers and that the values
|
||||||
|
matches the provided regexes"""
|
||||||
|
|
||||||
|
config = "headers-like"
|
||||||
|
expected_cls = ExpectedStringValue
|
||||||
|
|
||||||
|
async def run(self) -> dict:
|
||||||
|
# XXX Get the method from the task
|
||||||
|
task = self.task
|
||||||
|
response = await self.http_client.request(
|
||||||
|
method="get", url=task.url, timeout=60
|
||||||
|
)
|
||||||
|
|
||||||
|
status = True
|
||||||
|
for header, value in json.loads(self.expected).items():
|
||||||
|
if header not in response.headers:
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
if not re.search(rf"{value}", response.headers[header]):
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
|
||||||
|
return self.response(
|
||||||
|
status=status,
|
||||||
|
expected=self.expected,
|
||||||
|
retrieved=json.dumps(dict(response.headers)),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class HTTPBodyContains(BaseCheck):
|
class HTTPBodyContains(BaseCheck):
|
||||||
"""Checks that the HTTP body contains the expected string."""
|
"""Checks that the HTTP body contains the expected string."""
|
||||||
|
|
||||||
|
@ -123,6 +154,22 @@ class HTTPBodyContains(BaseCheck):
|
||||||
return self.response(status=self.expected in response.text)
|
return self.response(status=self.expected in response.text)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPBodyLike(BaseCheck):
|
||||||
|
"""Checks that the HTTP body matches the provided regex."""
|
||||||
|
|
||||||
|
config = "body-like"
|
||||||
|
expected_cls = ExpectedStringValue
|
||||||
|
|
||||||
|
async def run(self) -> dict:
|
||||||
|
response = await self.http_client.request(
|
||||||
|
method="get", url=self.task.url, timeout=60
|
||||||
|
)
|
||||||
|
if re.search(rf"{self.expected}", response.text):
|
||||||
|
return self.response(status=True)
|
||||||
|
|
||||||
|
return self.response(status=False)
|
||||||
|
|
||||||
|
|
||||||
class HTTPJsonContains(BaseCheck):
|
class HTTPJsonContains(BaseCheck):
|
||||||
"""Checks that JSON response contains the expected structure
|
"""Checks that JSON response contains the expected structure
|
||||||
(without checking the value)"""
|
(without checking the value)"""
|
||||||
|
@ -187,6 +234,40 @@ class HTTPJsonHas(BaseCheck):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPJsonLike(BaseCheck):
|
||||||
|
"""Checks that JSON response contains the expected structure and that the values
|
||||||
|
matches the provided regexes"""
|
||||||
|
|
||||||
|
config = "json-like"
|
||||||
|
expected_cls = ExpectedStringValue
|
||||||
|
|
||||||
|
async def run(self) -> dict:
|
||||||
|
# XXX Get the method from the task
|
||||||
|
task = self.task
|
||||||
|
response = await self.http_client.request(
|
||||||
|
method="get", url=task.url, timeout=60
|
||||||
|
)
|
||||||
|
|
||||||
|
obj = response.json()
|
||||||
|
|
||||||
|
status = True
|
||||||
|
for pointer, exp_value in json.loads(self.expected).items():
|
||||||
|
try:
|
||||||
|
value = resolve_pointer(obj, pointer)
|
||||||
|
if not re.search(rf"{exp_value:}", value):
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
except JsonPointerException:
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
|
||||||
|
return self.response(
|
||||||
|
status=status,
|
||||||
|
expected=self.expected,
|
||||||
|
retrieved=json.dumps(obj),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class HTTPJsonIs(BaseCheck):
|
class HTTPJsonIs(BaseCheck):
|
||||||
"""Checks that JSON response is the exact expected JSON object"""
|
"""Checks that JSON response is the exact expected JSON object"""
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ websites:
|
||||||
- status-is: 200
|
- status-is: 200
|
||||||
# Check that the response contains this string
|
# Check that the response contains this string
|
||||||
- body-contains: '<div id= "mypads"></div>'
|
- body-contains: '<div id= "mypads"></div>'
|
||||||
|
# Check that the response matches this regex
|
||||||
|
- body-like: MyPads .* accounts
|
||||||
# Check that the SSL certificate is no older than ssl.thresholds
|
# Check that the SSL certificate is no older than ssl.thresholds
|
||||||
- ssl-certificate-expiration: "on-check"
|
- ssl-certificate-expiration: "on-check"
|
||||||
# Check that the response contains this headers
|
# Check that the response contains this headers
|
||||||
|
@ -104,6 +106,12 @@ websites:
|
||||||
- headers-have:
|
- headers-have:
|
||||||
content-encoding: "gzip"
|
content-encoding: "gzip"
|
||||||
content-type: "text/html"
|
content-type: "text/html"
|
||||||
|
# Checks that response headers contains the expected headers and
|
||||||
|
# that the values matches the provided regexes
|
||||||
|
# You have to double the escape character \
|
||||||
|
- headers-like:
|
||||||
|
content-encoding: "gzip|utf"
|
||||||
|
content-type: "text/(html|css)"
|
||||||
- path: "/my-stats.json"
|
- path: "/my-stats.json"
|
||||||
checks:
|
checks:
|
||||||
# Check that JSON response contains the expected structure
|
# Check that JSON response contains the expected structure
|
||||||
|
@ -116,6 +124,12 @@ websites:
|
||||||
- json-has:
|
- json-has:
|
||||||
/maintenance: false
|
/maintenance: false
|
||||||
/productname: "Nextcloud"
|
/productname: "Nextcloud"
|
||||||
|
# Check that JSON response contains the expected structure and
|
||||||
|
# that the values matches the provided regexes
|
||||||
|
# You have to double the escape character \
|
||||||
|
- json-like:
|
||||||
|
/productname: ".*cloud"
|
||||||
|
/versionstring: "29\\..*"
|
||||||
# Check that JSON response is the exact expected JSON object
|
# Check that JSON response is the exact expected JSON object
|
||||||
# The order of the items in the object does not matter.
|
# The order of the items in the object does not matter.
|
||||||
- json-is: '{"foo": "bar", "baz": 42}'
|
- json-is: '{"foo": "bar", "baz": 42}'
|
||||||
|
|
|
@ -11,11 +11,14 @@ These checks are the most basic ones. They simply check that the response from t
|
||||||
| `status-is` | Check that the returned status code matches what you expect. | `status-is: "200"` |
|
| `status-is` | Check that the returned status code matches what you expect. | `status-is: "200"` |
|
||||||
| `status-in` | Check that the returned status code is in the list of codes you expect. | <pre><code>status-in:<br> - 200<br> - 302</code></pre> |
|
| `status-in` | Check that the returned status code is in the list of codes you expect. | <pre><code>status-in:<br> - 200<br> - 302</code></pre> |
|
||||||
| `body-contains` | Check that the returned body contains a given string. | `body-contains: "Hello world"` |
|
| `body-contains` | Check that the returned body contains a given string. | `body-contains: "Hello world"` |
|
||||||
|
| `body-like` | Check that the returned body matches a given regex. | `body-like: "Hel+o w.*"` |
|
||||||
| `headers-contain` | Check that the response contains the expected headers. | <pre><code>headers-contain:<br> - "content-encoding"<br> - "content-type"</code></pre> |
|
| `headers-contain` | Check that the response contains the expected headers. | <pre><code>headers-contain:<br> - "content-encoding"<br> - "content-type"</code></pre> |
|
||||||
| `headers-have` | Check that the response contains the expected headers with the expected value. | <pre><code>headers-have:<br> content-encoding: "gzip"<br> content-type: "text/html"</code></pre> |
|
| `headers-have` | Check that the response contains the expected headers with the expected value. | <pre><code>headers-have:<br> content-encoding: "gzip"<br> content-type: "text/html"</code></pre> |
|
||||||
|
| `headers-like` | Check that response headers contains the expected headers and that the values matches the provided regexes. | <pre><code>headers-like:<br> content-encoding: "gzip\|utf"<br> content-type: "text/(html\|css)"</code></pre> |
|
||||||
| `json-contains` | Check that JSON response contains the expected structure. | <pre><code>json-contains:<br> - /foo/bar/0<br> - /timestamp</code></pre> |
|
| `json-contains` | Check that JSON response contains the expected structure. | <pre><code>json-contains:<br> - /foo/bar/0<br> - /timestamp</code></pre> |
|
||||||
| `json-has` | Check that JSON response contains the expected structure and values. | <pre><code>json-has:<br> /maintenance: false<br> /productname: "Nextcloud"</code></pre> |
|
| `json-has` | Check that JSON response contains the expected structure and values. | <pre><code>json-has:<br> /maintenance: false<br> /productname: "Nextcloud"</code></pre> |
|
||||||
| `json-is` | Check that JSON response is the exact expected JSON object | `json-is: '{"foo": "bar", "baz": 42}'`|
|
| `json-like` | Check that JSON response contains the expected structure and that the values matches the provided regexes. | <pre><code>json-like:<br> /productname: ".\*cloud"<br> /versionstring: "29\\\\..\*"</code></pre> |
|
||||||
|
| `json-is` | Check that JSON response is the exact expected JSON object. | `json-is: '{"foo": "bar", "baz": 42}'`|
|
||||||
|
|
||||||
```{code-block} yaml
|
```{code-block} yaml
|
||||||
---
|
---
|
||||||
|
@ -27,6 +30,7 @@ caption: argos-config.yaml
|
||||||
checks:
|
checks:
|
||||||
- status-is: 200
|
- status-is: 200
|
||||||
- body-contains: "Hello world"
|
- body-contains: "Hello world"
|
||||||
|
- body-like: "Hel+o w.*"
|
||||||
- headers-contain:
|
- headers-contain:
|
||||||
- "content-encoding"
|
- "content-encoding"
|
||||||
- "content-type"
|
- "content-type"
|
||||||
|
@ -39,6 +43,11 @@ caption: argos-config.yaml
|
||||||
- headers-have:
|
- headers-have:
|
||||||
content-encoding: "gzip"
|
content-encoding: "gzip"
|
||||||
content-type: "text/html"
|
content-type: "text/html"
|
||||||
|
# It’s VERY important to respect the 4 spaces indentation here!
|
||||||
|
# You have to double the escape character \
|
||||||
|
- headers-like:
|
||||||
|
content-encoding: "gzip|utf"
|
||||||
|
content-type: "text/(html|css)"
|
||||||
- json-contains:
|
- json-contains:
|
||||||
- /foo/bar/0
|
- /foo/bar/0
|
||||||
- /timestamp
|
- /timestamp
|
||||||
|
@ -46,6 +55,11 @@ caption: argos-config.yaml
|
||||||
- json-has:
|
- json-has:
|
||||||
/maintenance: false
|
/maintenance: false
|
||||||
/productname: "Nextcloud"
|
/productname: "Nextcloud"
|
||||||
|
# It’s VERY important to respect the 4 spaces indentation here!
|
||||||
|
# You have to double the escape character \
|
||||||
|
- json-like:
|
||||||
|
/productname: ".*cloud"
|
||||||
|
/versionstring: "29\\..*"
|
||||||
- json-is: '{"foo": "bar", "baz": 42}'
|
- json-is: '{"foo": "bar", "baz": 42}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue