Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated merlin server unit testing #372

Merged
merged 30 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
57d44b9
Added additional tests for merlin server
ryannova Aug 1, 2022
24f32a4
Updated merlin server test to check other flags
ryannova Aug 1, 2022
f26fba5
Updated start/stop step in merlin config test
ryannova Aug 1, 2022
841875b
Fixed directory change to create a new directory if one doesn't exist
ryannova Aug 2, 2022
b0ee8f7
Lint changes
ryannova Aug 2, 2022
815da2c
Added quotation marks for appendfilename
ryannova Aug 2, 2022
61ef1b8
Checking FileExists condition
ryannova Aug 2, 2022
4ea54e4
Remove FileExist conditions for start/stop step
ryannova Aug 2, 2022
09cfc6e
Updated test definitions for merlin server
ryannova Aug 2, 2022
4ef2452
Remove unused variable
ryannova Aug 2, 2022
7da3c58
Removed lines for removing necessary files for condition check
ryannova Aug 2, 2022
afa4ee2
Changed condition to exist
ryannova Aug 2, 2022
c4e288c
Check directory with ls command
ryannova Aug 2, 2022
0966a04
Check directory with ls command
ryannova Aug 3, 2022
0c9a480
Updated conditions and command for config test
ryannova Aug 3, 2022
fa98e01
Removed appendfile condition
ryannova Aug 3, 2022
2a72b24
Added condition for checking directory
ryannova Aug 3, 2022
27a1651
Combined FileExist and DirExist
ryannova Aug 3, 2022
296785f
Added end command for clean up of tests
ryannova Aug 4, 2022
9b9c6d4
Added test case for adding user to merlin server
ryannova Aug 5, 2022
ef90ec3
Removed container check for users and implemented users file for user…
ryannova Aug 5, 2022
adeb255
Added comments for new conditions and lint changes
ryannova Aug 5, 2022
f198e72
Removed unused redis import
ryannova Aug 5, 2022
ca26fd2
Updated CHANGELOG with the necessary changes.
ryannova Aug 8, 2022
2f0b6c1
Added __str__ to new conditions for error reporting
ryannova Aug 11, 2022
628c41f
Command for cleaning merlin server moved toa variable
ryannova Aug 11, 2022
c0e660c
Added an additional comment regarding local variable in test_id and t…
ryannova Aug 12, 2022
0b3fa2e
Added channels to redis users
ryannova Aug 30, 2022
c4de691
Lint changes
ryannova Aug 31, 2022
a62e500
Updated changelog
ryannova Sep 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added lgtm.com Badge for README.md
- More fixes for lgtm checks.
- Added merlin server command as a container option for broker and results_backend servers.
- Added merlin server unit tests to test exisiting merlin server commands.
- Added the flux_exec batch argument to allow for flux exec arguments,
e.g. flux_exec: flux exec -r "0-1" to run celery workers only on
ranks 0 and 1 of a multi-rank allocation
Expand Down
7 changes: 5 additions & 2 deletions merlin/server/server_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,17 @@ def get_password(self) -> str:
def set_directory(self, directory: str) -> bool:
if directory is None:
return False
if not os.path.exists(directory):
os.mkdir(directory)
LOG.info(f"Created directory {directory}")
# Validate the directory input
if os.path.exists(directory):
# Set the save directory to the redis config
if not self.set_config_value("dir", directory):
LOG.error("Unable to set directory for redis config")
return False
else:
LOG.error("Directory given does not exist.")
LOG.error(f"Directory {directory} given does not exist and could not be created.")
return False
LOG.info(f"Directory is set to {directory}")
return True
Expand Down Expand Up @@ -413,7 +416,7 @@ def set_append_file(self, file: str) -> bool:
if file is None:
return False
# Set the append file in the redis config
if not self.set_config_value("appendfilename", file):
if not self.set_config_value("appendfilename", f'"{file}"'):
LOG.error("Unable to set append filename.")
return False
LOG.info(f"Append file is set to {file}")
Expand Down
53 changes: 53 additions & 0 deletions tests/integration/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,56 @@ def passes(self):
if self.negate:
return not self.is_within()
return self.is_within()


class PathExists(Condition):
"""
A condition for checking if a path to a file or directory exists
"""

def __init__(self, pathname) -> None:
self.pathname = pathname

def path_exists(self) -> bool:
return os.path.exists(self.pathname)

@property
def passes(self):
return self.path_exists()


class FileHasRegex(Condition):
"""
A condition that some body of text within a file
MUST match a given regular expression.
"""

def __init__(self, filename, regex) -> None:
self.filename = filename
self.regex = regex

def contains(self) -> bool:
try:
with open(self.filename, "r") as f:
filetext = f.read()
return self.is_within(filetext)
except Exception:
return False

def is_within(self, text):
return search(self.regex, text) is not None

@property
def passes(self):
return self.contains()


class FileHasNoRegex(FileHasRegex):
"""
A condition that some body of text within a file
MUST NOT match a given regular expression.
"""

@property
def passes(self):
return not self.contains()
8 changes: 7 additions & 1 deletion tests/integration/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ def run_single_test(name, test, test_label="", buffer_length=50):
info["violated_condition"] = (condition, i, len(conditions))
break

if len(test) == 4:
end_process = Popen(test[3], stdout=PIPE, stderr=PIPE, shell=True)
end_stdout, end_stderr = end_process.communicate()
info["end_stdout"] = end_stdout
info["end_stderr"] = end_stderr

return passed, info


Expand Down Expand Up @@ -139,7 +145,7 @@ def run_tests(args, tests):
n_to_run = 0
selective = True
for test_id, test in enumerate(tests.values()):
if len(test) == 3 and test[2] == "local":
if len(test) >= 3 and test[2] == "local":
args.ids.append(test_id + 1)
n_to_run += 1

Expand Down
84 changes: 78 additions & 6 deletions tests/integration/test_definitions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
from conditions import HasRegex, HasReturnCode, ProvenanceYAMLFileHasRegex, StepFileExists, StepFileHasRegex
from conditions import (
FileHasNoRegex,
FileHasRegex,
HasRegex,
HasReturnCode,
PathExists,
ProvenanceYAMLFileHasRegex,
StepFileExists,
StepFileHasRegex,
)

from merlin.utils import get_flux_cmd

Expand Down Expand Up @@ -45,18 +54,80 @@ def define_tests():
"local",
),
}
server_tests = {
"merlin server init": ("merlin server init", HasRegex(".*successful"), "local"),
server_basic_tests = {
"merlin server init": (
"merlin server init",
HasRegex(".*successful"),
"local",
"rm -rf appendonly.aof dump.rdb merlin_server/",
),
"merlin server start/stop": (
"merlin server start; merlin server status; merlin server stop",
"""merlin server init;
merlin server start;
merlin server status;
merlin server stop;""",
[
HasRegex("Server started with PID [0-9]*"),
HasRegex("Merlin server is running"),
HasRegex("Merlin server terminated"),
],
"local",
"rm -rf appendonly.aof dump.rdb merlin_server/",
),
"merlin server restart": (
"""merlin server init;
merlin server start;
merlin server restart;
merlin server status;
merlin server stop;""",
[
HasRegex("Server started with PID [0-9]*"),
HasRegex("Merlin server is running"),
HasRegex("Merlin server terminated"),
],
"local",
"rm -rf appendonly.aof dump.rdb merlin_server/",
),
}
server_config_tests = {
"merlin server change config": (
"""merlin server init;
merlin server config -p 8888 -pwd new_password -d ./config_dir -ss 80 -sc 8 -sf new_sf -am always -af new_af.aof;
merlin server start;
merlin server stop;""",
[
FileHasRegex("merlin_server/redis.conf", "port 8888"),
FileHasRegex("merlin_server/redis.conf", "requirepass new_password"),
FileHasRegex("merlin_server/redis.conf", "dir ./config_dir"),
FileHasRegex("merlin_server/redis.conf", "save 80 8"),
FileHasRegex("merlin_server/redis.conf", "dbfilename new_sf"),
FileHasRegex("merlin_server/redis.conf", "appendfsync always"),
FileHasRegex("merlin_server/redis.conf", 'appendfilename "new_af.aof"'),
PathExists("./config_dir/new_sf"),
PathExists("./config_dir/appendonlydir"),
HasRegex("Server started with PID [0-9]*"),
HasRegex("Merlin server terminated"),
],
"local",
"rm -rf appendonly.aof dump.rdb merlin_server/ config_dir/",
),
"merlin server config add/remove user": (
"""merlin server init;
merlin server start;
merlin server config --add-user new_user new_password;
merlin server stop;
scp ./merlin_server/redis.users ./merlin_server/redis.users_new
merlin server start;
merlin server config --remove-user new_user;
merlin server stop;
""",
[
FileHasRegex("./merlin_server/redis.users_new", "new_user"),
FileHasNoRegex("./merlin_server/redis.users", "new_user"),
],
"local",
"""rm -rf appendonly.aof dump.rdb merlin_server/""",
),
"clean merlin server": ("rm -rf appendonly.aof dump.rdb merlin_server/"),
}
examples_check = {
"example list": (
Expand Down Expand Up @@ -384,7 +455,8 @@ def define_tests():
all_tests = {}
for test_dict in [
basic_checks,
server_tests,
server_basic_tests,
server_config_tests,
examples_check,
run_workers_echo_tests,
wf_format_tests,
Expand Down