2023-03-06 14:23:05 +01:00
|
|
|
|
from abc import ABC, abstractmethod
|
|
|
|
|
from sys import stderr
|
2022-07-11 12:17:33 +02:00
|
|
|
|
from time import time, sleep
|
|
|
|
|
from requests import get
|
|
|
|
|
from traceback import format_exc
|
2022-07-13 21:23:58 +02:00
|
|
|
|
from shutil import copytree
|
2022-07-11 12:17:33 +02:00
|
|
|
|
from os.path import isdir, join
|
2023-03-06 14:23:05 +01:00
|
|
|
|
from os import mkdir, makedirs, walk, chmod, rename
|
2022-07-13 21:43:04 +02:00
|
|
|
|
from re import sub, search, MULTILINE
|
2023-03-06 14:23:05 +01:00
|
|
|
|
from datetime import datetime
|
2022-07-13 21:23:58 +02:00
|
|
|
|
from subprocess import run
|
2023-03-05 21:51:04 +01:00
|
|
|
|
from logger import log
|
2022-07-11 12:17:33 +02:00
|
|
|
|
|
|
|
|
|
|
2023-03-09 10:04:59 +01:00
|
|
|
|
class Test(ABC):
|
|
|
|
|
def __init__(self, name, kind, timeout, tests, no_copy_container=False, delay=0):
|
2022-07-11 12:17:33 +02:00
|
|
|
|
self._name = name
|
|
|
|
|
self.__kind = kind
|
2022-07-27 13:56:05 +02:00
|
|
|
|
self._timeout = timeout
|
2022-07-11 12:17:33 +02:00
|
|
|
|
self.__tests = tests
|
2022-07-25 10:11:44 +02:00
|
|
|
|
self._no_copy_container = no_copy_container
|
2022-07-27 14:44:46 +02:00
|
|
|
|
self.__delay = delay
|
2023-03-09 10:04:59 +01:00
|
|
|
|
log(
|
|
|
|
|
"TEST",
|
|
|
|
|
"ℹ️",
|
|
|
|
|
"instiantiated with "
|
|
|
|
|
+ str(len(tests))
|
|
|
|
|
+ " tests and timeout of "
|
|
|
|
|
+ str(timeout)
|
|
|
|
|
+ "s for "
|
|
|
|
|
+ self._name,
|
|
|
|
|
)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
|
2023-03-06 14:23:05 +01:00
|
|
|
|
# Class method
|
2022-07-11 12:17:33 +02:00
|
|
|
|
# called once before running all the different tests for a given integration
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def init():
|
|
|
|
|
try:
|
|
|
|
|
if not isdir("/tmp/bw-data"):
|
2022-07-11 12:17:33 +02:00
|
|
|
|
mkdir("/tmp/bw-data")
|
2022-07-14 14:33:04 +02:00
|
|
|
|
run("sudo chmod 777 /tmp/bw-data", shell=True)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
rm_dirs = ["configs", "plugins", "www"]
|
2023-03-09 10:04:59 +01:00
|
|
|
|
for rm_dir in rm_dirs:
|
|
|
|
|
if isdir(rm_dir):
|
2023-03-06 14:23:05 +01:00
|
|
|
|
run("sudo rm -rf /tmp/bw-data/" + rm_dir, shell=True)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if not isdir("/tmp/tests"):
|
2022-07-11 16:23:50 +02:00
|
|
|
|
mkdir("/tmp/tests")
|
2023-03-09 10:04:59 +01:00
|
|
|
|
except:
|
2023-03-05 21:51:04 +01:00
|
|
|
|
log("TEST", "❌", "exception while running Test.init()\n" + format_exc())
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
2023-03-06 14:23:05 +01:00
|
|
|
|
# Class method
|
2022-07-13 22:57:36 +02:00
|
|
|
|
# called once all tests ended
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def end():
|
2022-07-14 14:58:48 +02:00
|
|
|
|
return True
|
2022-07-13 22:57:36 +02:00
|
|
|
|
|
2023-03-06 14:23:05 +01:00
|
|
|
|
# helper to check domains
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def _check_domains(self):
|
|
|
|
|
for k, v in self._domains.items():
|
|
|
|
|
if v is None:
|
2023-03-06 14:23:05 +01:00
|
|
|
|
log("TEST", "⚠️", "env " + k + " is None")
|
|
|
|
|
|
2022-07-11 12:17:33 +02:00
|
|
|
|
# called before starting the tests
|
|
|
|
|
# must be override if specific actions needs to be done
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def _setup_test(self):
|
|
|
|
|
try:
|
2022-07-11 16:23:50 +02:00
|
|
|
|
rm_dirs = ["configs", "plugins", "www"]
|
2023-03-09 10:04:59 +01:00
|
|
|
|
for rm_dir in rm_dirs:
|
|
|
|
|
if isdir("/tmp/bw-data/" + rm_dir):
|
|
|
|
|
run(
|
|
|
|
|
"sudo bash -c 'rm -rf /tmp/bw-data/" + rm_dir + "/*'",
|
|
|
|
|
shell=True,
|
|
|
|
|
)
|
|
|
|
|
if isdir("/tmp/tests/" + self._name):
|
2023-03-06 14:23:05 +01:00
|
|
|
|
run("sudo rm -rf /tmp/tests/" + self._name, shell=True)
|
|
|
|
|
copytree("./examples/" + self._name, "/tmp/tests/" + self._name)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
except:
|
|
|
|
|
log(
|
|
|
|
|
"TEST",
|
|
|
|
|
"❌",
|
|
|
|
|
"exception while running Test._setup_test()\n" + format_exc(),
|
|
|
|
|
)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
# called after running the tests
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def _cleanup_test(self):
|
|
|
|
|
try:
|
2023-03-06 14:23:05 +01:00
|
|
|
|
run("sudo rm -rf /tmp/tests/" + self._name, shell=True)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
except:
|
|
|
|
|
log(
|
|
|
|
|
"TEST",
|
|
|
|
|
"❌",
|
|
|
|
|
"exception while running Test._cleanup_test()\n" + format_exc(),
|
|
|
|
|
)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
# run all the tests
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def run_tests(self):
|
|
|
|
|
if not self._setup_test():
|
2022-08-16 14:32:09 +02:00
|
|
|
|
self._debug_fail()
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return False
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if self.__delay != 0:
|
2023-03-05 21:51:04 +01:00
|
|
|
|
log("TEST", "ℹ️", "delay is set, sleeping " + str(self.__delay) + "s")
|
2022-07-27 14:44:46 +02:00
|
|
|
|
sleep(self.__delay)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
start = time()
|
2023-03-09 10:04:59 +01:00
|
|
|
|
while time() < start + self._timeout:
|
2022-07-11 12:17:33 +02:00
|
|
|
|
all_ok = True
|
2023-03-09 10:04:59 +01:00
|
|
|
|
for test in self.__tests:
|
2022-07-11 12:17:33 +02:00
|
|
|
|
ok = self.__run_test(test)
|
2022-07-20 20:31:50 +02:00
|
|
|
|
sleep(1)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if not ok:
|
2022-07-11 12:17:33 +02:00
|
|
|
|
all_ok = False
|
|
|
|
|
break
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if all_ok:
|
2022-07-11 12:17:33 +02:00
|
|
|
|
elapsed = str(int(time() - start))
|
2023-03-09 10:04:59 +01:00
|
|
|
|
log(
|
|
|
|
|
"TEST",
|
|
|
|
|
"ℹ️",
|
|
|
|
|
"success (" + elapsed + "/" + str(self._timeout) + "s)",
|
|
|
|
|
)
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return self._cleanup_test()
|
2023-03-06 14:23:05 +01:00
|
|
|
|
log("TEST", "⚠️", "tests not ok, retrying in 1s ...")
|
2022-07-14 14:27:18 +02:00
|
|
|
|
self._debug_fail()
|
2022-07-14 19:44:05 +02:00
|
|
|
|
self._cleanup_test()
|
2023-03-05 21:51:04 +01:00
|
|
|
|
log("TEST", "❌", "failed (timeout = " + str(self._timeout) + "s)")
|
2022-07-11 12:17:33 +02:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# run a single test
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def __run_test(self, test):
|
|
|
|
|
try:
|
2022-07-23 11:29:18 +02:00
|
|
|
|
ex_url = test["url"]
|
2023-03-09 10:04:59 +01:00
|
|
|
|
for ex_domain, test_domain in self._domains.items():
|
|
|
|
|
if search(ex_domain, ex_url):
|
2022-07-23 11:29:18 +02:00
|
|
|
|
ex_url = sub(ex_domain, test_domain, ex_url)
|
|
|
|
|
break
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if test["type"] == "string":
|
2023-03-06 14:23:05 +01:00
|
|
|
|
r = get(ex_url, timeout=10, verify=False)
|
2022-07-13 21:56:59 +02:00
|
|
|
|
return test["string"].casefold() in r.text.casefold()
|
2023-03-09 10:04:59 +01:00
|
|
|
|
elif test["type"] == "status":
|
2023-03-06 14:23:05 +01:00
|
|
|
|
r = get(ex_url, timeout=10, verify=False)
|
2022-07-23 11:29:18 +02:00
|
|
|
|
return test["status"] == r.status_code
|
2023-03-09 10:04:59 +01:00
|
|
|
|
except:
|
|
|
|
|
# log("TEST", "❌", "exception while running test of type " + test["type"] + " on URL " + ex_url + "\n" + format_exc())
|
2022-07-13 21:43:04 +02:00
|
|
|
|
return False
|
2023-03-09 10:04:59 +01:00
|
|
|
|
raise (Exception("unknow test type " + test["type"]))
|
2022-07-11 12:17:33 +02:00
|
|
|
|
|
2022-07-14 14:27:18 +02:00
|
|
|
|
# called when tests fail : typical case is to show logs
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def _debug_fail(self):
|
2022-07-14 14:27:18 +02:00
|
|
|
|
pass
|
|
|
|
|
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def replace_in_file(path, old, new):
|
|
|
|
|
try:
|
|
|
|
|
with open(path, "r") as f:
|
2023-03-06 14:23:05 +01:00
|
|
|
|
content = f.read()
|
|
|
|
|
content = sub(old, new, content, flags=MULTILINE)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
with open(path, "w") as f:
|
2023-03-06 14:23:05 +01:00
|
|
|
|
f.write(content)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
except:
|
2023-03-05 21:51:04 +01:00
|
|
|
|
log("TEST", "⚠️", "can't replace file " + path + " : " + format_exc())
|
2022-07-11 12:17:33 +02:00
|
|
|
|
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def replace_in_files(path, old, new):
|
|
|
|
|
for root, dirs, files in walk(path):
|
|
|
|
|
for name in files:
|
2022-07-14 15:24:11 +02:00
|
|
|
|
Test.replace_in_file(join(root, name), old, new)
|
2022-07-11 16:23:50 +02:00
|
|
|
|
|
2023-03-09 10:04:59 +01:00
|
|
|
|
def rename(path, old, new):
|
|
|
|
|
for root, dirs, files in walk(path):
|
|
|
|
|
for name in dirs + files:
|
2022-07-11 12:17:33 +02:00
|
|
|
|
full_path = join(root, name)
|
2022-07-20 16:26:53 +02:00
|
|
|
|
new_path = sub(old, new, full_path)
|
2023-03-09 10:04:59 +01:00
|
|
|
|
if full_path != new_path:
|
2022-10-19 17:37:13 +02:00
|
|
|
|
rename(full_path, new_path)
|