Add plugin meta tests

This commit is contained in:
Rikko 2022-08-31 04:34:22 +05:30
parent 40b70fe4a7
commit 66edc78896
10 changed files with 248 additions and 95 deletions

View file

@ -22,4 +22,4 @@ jobs:
pip install -r test/pip_reqs.txt pip install -r test/pip_reqs.txt
- name: Execute Tests - name: Execute Tests
run: | run: |
python -m unittest discover python -m unittest discover -v

View file

@ -66,7 +66,7 @@ $ pip install -r test/pip_reqs.txt
and then executing the following in the project's root directory: and then executing the following in the project's root directory:
```bash ```bash
$ python -m unittest discover $ python -m unittest discover -v
``` ```
## License ## License

View file

@ -16,7 +16,7 @@
"versions": { "versions": {
"1.1.0": { "1.1.0": {
"api_version": 7, "api_version": 7,
"commit_sha": "cbdb3ead", "commit_sha": "40b70fe",
"released_on": "08-08-2022", "released_on": "08-08-2022",
"md5sum": "f4f0bb91f5d10cf8f591ecf7d2848182" "md5sum": "f4f0bb91f5d10cf8f591ecf7d2848182"
} }

View file

@ -30,12 +30,6 @@
"commit_sha": "963a17379", "commit_sha": "963a17379",
"released_on": "12-08-2022", "released_on": "12-08-2022",
"md5sum": "41084bfec41119ca9df8e6d899cd3cc0" "md5sum": "41084bfec41119ca9df8e6d899cd3cc0"
},
"1.1.0": {
"api_version": 7,
"commit_sha": "13a9d128",
"released_on": "03-06-2022",
"md5sum": "4b6bbb99037ebda4664da7c510b3717c"
}, },
"1.0.0": { "1.0.0": {
"api_version": 6, "api_version": 6,
@ -58,7 +52,7 @@
"versions": { "versions": {
"1.0.0": { "1.0.0": {
"api_version": 7, "api_version": 7,
"commit_sha": "2aa6df31", "commit_sha": "63d674cf",
"released_on": "06-08-2022", "released_on": "06-08-2022",
"md5sum": "233dfaa7f0e9394d21454f4ffa7d0205" "md5sum": "233dfaa7f0e9394d21454f4ffa7d0205"
} }

View file

View file

@ -0,0 +1,52 @@
import hashlib
import json
import re
import asyncio
import aiohttp
import unittest
from test import helpers
class TestMetadata(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
with open("plugins/minigames.json", "rb") as fin:
self.content = json.load(fin)
async def asyncTearDown(self):
# This helps suppress aiohttp warnings. See:
# https://github.com/aio-libs/aiohttp/issues/1115
await asyncio.sleep(0.2)
def test_keys(self):
self.assertEqual(self.content["name"], "Minigames")
self.assertTrue(isinstance(self.content["description"], str))
self.assertTrue(self.content["plugins_base_url"].startswith("http"))
self.assertTrue(isinstance(self.content["plugins"], dict))
async def test_plugins_metadata(self):
asserts_for_versions_metadata = []
async with aiohttp.ClientSession() as session:
for plugin in self.content["plugins"].items():
metadata = helpers.AssertPluginMetadata(*plugin)
metadata.assert_keys()
asserts_for_versions_metadata.append(
metadata.assert_for_versions_metadata(
self.content["plugins_base_url"],
session,
)
)
await asyncio.gather(
*asserts_for_versions_metadata
)
def test_versions_order(self):
for plugin_metadata in self.content["plugins"].values():
versions = list(plugin_metadata["versions"].items())
sorted_versions = sorted(
versions,
key=lambda version: version[0],
reverse=True,
)
self.assertEqual(sorted_versions, versions)

View file

@ -0,0 +1,52 @@
import hashlib
import json
import re
import asyncio
import aiohttp
import unittest
from test import helpers
class TestMetadata(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
with open("plugins/utilities.json", "rb") as fin:
self.content = json.load(fin)
async def asyncTearDown(self):
# This helps suppress aiohttp warnings. See:
# https://github.com/aio-libs/aiohttp/issues/1115
await asyncio.sleep(0.2)
def test_keys(self):
self.assertEqual(self.content["name"], "Utilities")
self.assertTrue(isinstance(self.content["description"], str))
self.assertTrue(self.content["plugins_base_url"].startswith("http"))
self.assertTrue(isinstance(self.content["plugins"], dict))
async def test_plugins_metadata(self):
asserts_for_versions_metadata = []
async with aiohttp.ClientSession() as session:
for plugin in self.content["plugins"].items():
metadata = helpers.AssertPluginMetadata(*plugin)
metadata.assert_keys()
asserts_for_versions_metadata.append(
metadata.assert_for_versions_metadata(
self.content["plugins_base_url"],
session,
)
)
await asyncio.gather(
*asserts_for_versions_metadata
)
def test_versions_order(self):
for plugin_metadata in self.content["plugins"].values():
versions = list(plugin_metadata["versions"].items())
sorted_versions = sorted(
versions,
key=lambda version: version[0],
reverse=True,
)
self.assertEqual(sorted_versions, versions)

85
test/helpers.py Normal file
View file

@ -0,0 +1,85 @@
import hashlib
import os
import re
import asyncio
async def assert_for_network_file(url, md5sum, aiohttp_session, regexp=None, regexp_result=None):
async with aiohttp_session.get(url) as response:
expected_response_status = 200
assert response.status == expected_response_status, (
f'Request to "{url}" returned status code {response.status} '
f'(expected {expected_response_status}).'
)
content = await response.read()
caclulated_md5sum = hashlib.md5(content).hexdigest()
assert caclulated_md5sum == md5sum, (
f'"{url}" failed MD5 checksum:\nGot {caclulated_md5sum} '
f'(expected {md5sum}).'
)
if regexp and regexp_result:
result = regexp.search(content).group().decode("utf-8")
assert result == regexp_result, (
f'Regexp failed: Got ({result}) (expected {regexp_result}).'
)
async def assert_for_network_files_from_versions(base_url, versions, aiohttp_session, regexp=None):
tasks = tuple(
assert_for_network_file(
base_url.format(
content_type="raw",
tag=version["commit_sha"],
),
version["md5sum"],
aiohttp_session,
regexp=regexp,
regexp_result=str(version["api_version"]),
) for number, version in versions.items()
)
await asyncio.gather(*tasks)
class AssertPluginMetadata:
def __init__(self, name, metadata):
self.name = name
self.metadata = metadata
self.filename = f"{name}.py"
self.api_number_regexp = re.compile(b"(?<=ba_meta require api )(.*)")
def assert_keys(self):
assert isinstance(self.metadata["description"], str)
assert isinstance(self.metadata["external_url"], str)
assert isinstance(self.metadata["authors"], list)
assert len(self.metadata["authors"]) > 0
for author in self.metadata["authors"]:
assert isinstance(author["name"], str)
assert isinstance(author["email"], str)
assert isinstance(author["discord"], str)
assert isinstance(self.metadata["versions"], dict)
assert len(self.metadata["versions"]) > 0
async def assert_for_versions_metadata(self, base_url, aiohttp_session):
versions = tuple(self.metadata["versions"].items())
latest_number, latest_version = versions[0]
await asyncio.gather(
assert_for_network_files_from_versions(
f"{base_url}/{self.filename}",
self.metadata["versions"],
aiohttp_session,
regexp=self.api_number_regexp
),
# Additionally assert for the latest version with tag as "main".
assert_for_network_file(
f"{base_url}/{self.filename}".format(
content_type="raw",
tag="main",
),
latest_version["md5sum"],
aiohttp_session,
regexp=self.api_number_regexp,
regexp_result=str(latest_version["api_version"]),
)
)
# TODO: Regex stuff to get api number from plugin file.

View file

@ -1,85 +0,0 @@
import hashlib
import os
import json
import re
import asyncio
import aiohttp
import unittest
async def assert_for_md5sum(url, md5sum, aiohttp_session):
async with aiohttp_session.get(url) as response:
expected_response_status = 200
assert response.status == expected_response_status, (
f'Request to "{url}" returned status code {response.status} '
f'(expected {expected_response_status}).'
)
content = await response.read()
caclulated_md5sum = hashlib.md5(content).hexdigest()
assert caclulated_md5sum == md5sum, (
f'"{url}" failed MD5 checksum:\nGot {caclulated_md5sum} '
f'(expected {md5sum}).'
)
async def assert_for_commit_sha_and_md5sum_from_versions(base_url, versions, aiohttp_session):
tasks = tuple(
assert_for_md5sum(
base_url.format(
content_type="raw",
tag=version["commit_sha"],
),
version["md5sum"],
aiohttp_session,
) for number, version in versions.items()
)
await asyncio.gather(*tasks)
class TestPluginManagerMetadata(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
with open("index.json", "rb") as fin:
self.content = json.load(fin)
self.version_regexp = re.compile(b"PLUGIN_MANAGER_VERSION = .+")
async def asyncTearDown(self):
pass
def test_keys(self):
assert isinstance(self.content["plugin_manager_url"], str)
assert isinstance(self.content["versions"], dict)
assert isinstance(self.content["categories"], list)
assert isinstance(self.content["external_source_url"], str)
def test_versions_order(self):
versions = list(self.content["versions"].items())
sorted_versions = sorted(versions, key=lambda version: version[0])
assert sorted_versions == versions
async def test_versions_metadata(self):
versions = tuple(self.content["versions"].items())
latest_number, latest_version = versions[0]
async with aiohttp.ClientSession() as session:
await asyncio.gather(
assert_for_commit_sha_and_md5sum_from_versions(
self.content["plugin_manager_url"],
self.content["versions"],
session,
),
# Additionally assert for the latest version with tag as "main".
assert_for_md5sum(
self.content["plugin_manager_url"].format(
content_type="raw",
tag="main",
),
latest_version["md5sum"],
session,
),
)
# class TestPluginsMetadata(unittest.IsolatedAsyncioTestCase):
# class TestExternalSourceMetadata(unittest.IsolatedAsyncioTestCase):

View file

@ -0,0 +1,55 @@
import json
import re
import asyncio
import aiohttp
import unittest
from test import helpers
class TestPluginManagerMetadata(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
with open("index.json", "rb") as fin:
self.content = json.load(fin)
async def asyncTearDown(self):
pass
def test_keys(self):
self.assertTrue(self.content["plugin_manager_url"].startswith("http"))
self.assertTrue(isinstance(self.content["versions"], dict))
self.assertTrue(isinstance(self.content["categories"], list))
for category in self.content["categories"]:
self.assertTrue(category.startswith("http"))
self.assertTrue(self.content["external_source_url"].startswith("http"))
def test_versions_order(self):
versions = list(self.content["versions"].items())
sorted_versions = sorted(
versions,
key=lambda version: version[0],
reverse=True,
)
self.assertEqual(sorted_versions, versions)
async def test_versions_metadata(self):
versions = tuple(self.content["versions"].items())
latest_number, latest_version = versions[0]
async with aiohttp.ClientSession() as session:
await asyncio.gather(
helpers.assert_for_network_files_from_versions(
self.content["plugin_manager_url"],
self.content["versions"],
session,
),
# Additionally assert for the latest version with tag as "main".
helpers.assert_for_network_file(
self.content["plugin_manager_url"].format(
content_type="raw",
tag="main",
),
latest_version["md5sum"],
session,
),
)