aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--test/py/conftest.py8
-rw-r--r--test/py/lib/test_repo.py116
-rwxr-xr-xtest/py/lib/test_repo/ci.sh24
-rw-r--r--test/py/test_repo.py4
4 files changed, 108 insertions, 44 deletions
diff --git a/test/py/conftest.py b/test/py/conftest.py
index a92699d..e087dd1 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -11,7 +11,7 @@ from pytest import fixture
from lib.db import Database
from lib.net import random_unused_port
from lib.process import CmdLine
-from lib.test_repo import TestRepo
+from lib.test_repo import TestRepoOutputSimple, TestRepoOutputEmpty
class Param:
@@ -188,9 +188,9 @@ def client(client_cmd):
return client_cmd
-@fixture
-def test_repo(tmp_path):
- return TestRepo(tmp_path)
+@fixture(params=[TestRepoOutputSimple, TestRepoOutputEmpty])
+def test_repo(tmp_path, request):
+ return request.param(os.path.join(tmp_path, 'repo'))
class Env:
diff --git a/test/py/lib/test_repo.py b/test/py/lib/test_repo.py
index 3a4d847..94b6f93 100644
--- a/test/py/lib/test_repo.py
+++ b/test/py/lib/test_repo.py
@@ -3,8 +3,10 @@
# For details, see https://github.com/egor-tensin/cimple.
# Distributed under the MIT License.
+import abc
import logging
import os
+import shlex
import shutil
from .process import Process
@@ -24,28 +26,114 @@ class Repo:
Process.run(*args, cwd=self.path, **kwargs)
+CI_SCRIPT = R'''#!/usr/bin/env bash
+
+set -o errexit -o nounset -o pipefail
+shopt -s inherit_errexit lastpipe
+
+readonly runs_dir={runs_dir}
+
+readonly run_output_template=run_XXXXXX
+
+run_output_path="$( mktemp --tmpdir="$runs_dir" "$run_output_template" )"
+readonly run_output_path
+
+touch -- "$run_output_path"
+'''
+
+
class TestRepo(Repo):
# Prevent Pytest from discovering test cases in this class:
__test__ = False
- DATA_DIR = 'test_repo'
- CI_SCRIPT = 'ci.sh'
- OUTPUT_DIR = 'output'
+ def _format_ci_script(self):
+ runs_dir = shlex.quote(self.runs_dir)
+ return CI_SCRIPT.format(runs_dir=runs_dir)
+
+ def __init__(self, path, ci_script='ci.sh'):
+ super().__init__(path)
+
+ self.runs_dir = os.path.join(self.path, 'runs')
+ os.makedirs(self.runs_dir, exist_ok=True)
- @staticmethod
- def get_ci_script():
- return os.path.join(os.path.dirname(__file__), TestRepo.DATA_DIR, TestRepo.CI_SCRIPT)
+ self.ci_script_path = os.path.join(self.path, ci_script)
+ with open(self.ci_script_path, mode='x') as f:
+ f.write(self._format_ci_script())
+ os.chmod(self.ci_script_path, 0o755)
+
+ self.run('git', 'add', '--', ci_script)
+ self.run('git', 'commit', '-q', '-m', 'add CI script')
+
+ def count_run_files(self):
+ return len([name for name in os.listdir(self.runs_dir) if os.path.isfile(os.path.join(self.runs_dir, name))])
+
+
+class TestRepoOutput(TestRepo, abc.ABC):
+ __test__ = False
+
+ OUTPUT_SCRIPT_NAME = 'generate-output'
def __init__(self, path):
super().__init__(path)
- shutil.copy(self.get_ci_script(), self.path)
- self.run('git', 'add', '.')
- self.run('git', 'commit', '-q', '-m', 'add CI script')
- self.output_dir = os.path.join(self.path, TestRepo.OUTPUT_DIR)
- os.makedirs(self.output_dir, exist_ok=True)
- def count_ci_output_files(self):
- return len([name for name in os.listdir(self.output_dir) if os.path.isfile(os.path.join(self.output_dir, name))])
+ self.output_script_path = os.path.join(self.path, TestRepoOutput.OUTPUT_SCRIPT_NAME)
+ with open(self.output_script_path, mode='x') as f:
+ f.write(self._format_output_script())
+ os.chmod(self.output_script_path, 0o755)
+
+ with open(self.ci_script_path, mode='a') as f:
+ f.write(self._format_ci_script_addition())
+
+ self.run('git', 'add', '--', TestRepoOutput.OUTPUT_SCRIPT_NAME)
+ self.run('git', 'add', '-u')
+ self.run('git', 'commit', '-q', '-m', 'add output script')
- def output_matches(self, output):
+ @abc.abstractmethod
+ def _format_output_script(self):
+ pass
+
+ def _format_ci_script_addition(self):
+ return R'{output_script} | tee -a "$run_output_path"'.format(
+ output_script=shlex.quote(self.output_script_path))
+
+ @abc.abstractmethod
+ def run_output_matches(self, output):
+ pass
+
+
+OUTPUT_SCRIPT_SIMPLE = R'''#!/usr/bin/env bash
+
+set -o errexit -o nounset -o pipefail
+shopt -s inherit_errexit lastpipe
+
+timestamp="$( date --iso-8601=ns )"
+readonly timestamp
+
+echo "A CI run happened at $timestamp"
+'''
+
+
+class TestRepoOutputSimple(TestRepoOutput):
+ __test__ = False
+
+ def _format_output_script(self):
+ return OUTPUT_SCRIPT_SIMPLE
+
+ def run_output_matches(self, output):
return output.decode().startswith('A CI run happened at ')
+
+
+OUTPUT_SCRIPT_EMPTY = R'''#!/bin/sh
+
+true
+'''
+
+
+class TestRepoOutputEmpty(TestRepoOutput):
+ __test__ = False
+
+ def _format_output_script(self):
+ return OUTPUT_SCRIPT_EMPTY
+
+ def run_output_matches(self, output):
+ return len(output) == 0
diff --git a/test/py/lib/test_repo/ci.sh b/test/py/lib/test_repo/ci.sh
deleted file mode 100755
index 804cdb3..0000000
--- a/test/py/lib/test_repo/ci.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-set -o errexit -o nounset -o pipefail
-shopt -s inherit_errexit lastpipe
-
-script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
-script_dir="$( cd -- "$script_dir" && pwd )"
-readonly script_dir
-
-ci_output_dir="$( git remote get-url origin )"
-ci_output_dir="$ci_output_dir/output"
-readonly ci_output_dir
-
-mkdir -p -- "$ci_output_dir"
-
-readonly ci_output_template=ci_XXXXXX
-
-ci_output_path="$( mktemp --tmpdir="$ci_output_dir" "$ci_output_template" )"
-readonly ci_output_path
-
-timestamp="$( date --iso-8601=ns )"
-readonly timestamp
-
-echo "A CI run happened at $timestamp" | tee -- "$ci_output_path"
diff --git a/test/py/test_repo.py b/test/py/test_repo.py
index 3e507c3..76aeef3 100644
--- a/test/py/test_repo.py
+++ b/test/py/test_repo.py
@@ -47,14 +47,14 @@ def _test_repo_internal(env, repo, numof_processes, runs_per_process):
for proc in processes:
proc.join()
- assert numof_runs == repo.count_ci_output_files()
+ assert numof_runs == repo.count_run_files()
runs = env.db.get_all_runs()
assert numof_runs == len(runs)
for id, status, ec, output, url, rev in runs:
assert status == 'finished', f'Invalid status for run {id}: {status}'
- assert repo.output_matches(output), f"Output doesn't match: {output}"
+ assert repo.run_output_matches(output), f"Output doesn't match: {output}"
@pytest.mark.parametrize('numof_clients,runs_per_client',