Compare commits

...

33 Commits

Author SHA1 Message Date
Anna Schumaker 2022b22180 xfstests.zsh: Various Updates
* Use $COLORS from common.zsh
* Add a --options option to pass generic NFS mount options
* Add the --no-scratch option to run tests without a scratch mount
* Add the --no-server-access option for testing against somebody else's
  server
* Remove the --nconnect and --rwsize options
* Run tcp and rdma tests sequentially instead of in parallel
* Add xfstestsdb support
* Clean up colors/xfstests.py to fix flake8 style errors
* Colorize xfstestsdb xunit output

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-20 14:04:50 -04:00
Anna Schumaker b07b1c2a52 unlock-sqlite-db.zsh: Add script for fixing locked database files
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 15:09:37 -04:00
Anna Schumaker 03255bc333 pull-request.sh: Various Updates
* We are on Linux v6.* now
* Add a subject line template
* Fix the $new tag variable

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 14:56:04 -04:00
Anna Schumaker b2432c671e submit-patches.zsh: Various updates
* Add an option to send to Linus
* Remove extra TO= lines

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 14:54:17 -04:00
Anna Schumaker 8cc4c23e71 read_plus.zsh: Various Updates
* Clean up colors/read_plus.py to match flake8 style guidelines
* Add --dmesg, --srvdmesg, and --no-server-vmtouch options
* Use $COLORS from common.zsh
* Accept a specific filename to test as a command line argument
* Add tests for 3, 5, 6, and 7 page segments

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 14:44:10 -04:00
Anna Schumaker 3e0f52b4e4 install-scripts.zsh: Various Updates
* Use $BIN from common.zsh
* Fixes for colorful output
* Install scripts to .local/bin on the remote machine
* Point setup.zsh at .local/bin instead of .bin
* Run setup/testdirs.zsh with the -e flag

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 13:50:02 -04:00
Anna Schumaker c7aad8e77c syncmusic.sh: Fix source path for the new synology device
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 13:25:23 -04:00
Anna Schumaker 0b9af1b0ff backup.sh: Fix backup path for the new synology device
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 13:24:45 -04:00
Anna Schumaker 078d6e126e vm.zsh: Various Updates
* Improve the exit trap to make sure child processes are stopped
* wait $(jobs -pr) is the same thing as wait with no options

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 13:17:40 -04:00
Anna Schumaker fef564a570 rping.zsh: Various Updates
* Use $COLORS from common.zsh
* Fix colorful output when run from a different script

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 12:02:47 -04:00
Anna Schumaker e4434babcb rdma.zsh: Various Updates
* Use $COLORS from common.zsh
* Fix colored output when run from another script

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 12:01:58 -04:00
Anna Schumaker c843549aa5 deploykernel.zsh: Various Updates
* Add options for cross compiling
* Put the resulting package in a subdirectory to keep the toplevel clean
* Fix color output
* Use $COLORS from common.zsh

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 11:53:10 -04:00
Anna Schumaker 2e9699a52e deploypkg.zsh: Various Updates
* Clean up colors/pacman.py for colorful output
* Fixes for the .local/bin move
* Use the $COLORS and $BIN variables from common.zsh

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 11:45:58 -04:00
Anna Schumaker 70dfceccef makekconfig.py: Various Updates
* Python flake8 style fixes
* Update for the .local/bin change

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-19 11:42:34 -04:00
Anna Schumaker 941308e246 makelinux.zsh: Various Updates
* Fixes to color output
* Added an option to cross compile for i686
* Use the new $COLORS variable for the location of the colors script

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-18 16:18:32 -04:00
Anna Schumaker 2373f06ea7 cthon.zsh: Various Updates
* Point $BIN to $HOME/.local/bin
* Create $COLORS pointing to $BIN/colors
* Use the zsh built-in _libvirt function for completion
* Add a --no-server-access option for testing against somebody else's
  server
* Add a generic --options option, replacing --nconnect and --rwsize but
  allowing for any NFS mount option to be passed instead
* Run RDMA tests after TCP instead of in parallel

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-07-18 16:04:37 -04:00
Anna Schumaker d29b73180f reporter: updates for xfstests xunit generation changes
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-04-17 13:12:51 -04:00
Anna Schumaker d080c04a5d makelinux.zsh: Add compiler selection options
I add an easy way to select between gcc and clang. Additionally, I add
an option to cross-compile for arm64 architectures.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2023-04-04 11:14:50 -04:00
Anna Schumaker 87d2a308c3 xfstests.zsh: Make -g GROUP an option to the script
So we can add tab completion and set a default group when one isn't
passed in.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-25 15:07:04 -04:00
Anna Schumaker 4025aaa0bd colors/xfstests.py: Fix splitting kernel PREEMPT line
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-25 15:05:55 -04:00
Anna Schumaker 061d076ee9 xfstests.zsh: Add a --rwsize option
For setting the rsize and wsize used by the tests

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-24 13:14:13 -04:00
Anna Schumaker d770421063 cthon.zsh: Add an --rwsize option
For setting rsize and wsize for the mount to test

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-24 13:13:41 -04:00
Anna Schumaker 1c3372e3a5 cthon.zsh: Don't return 0 if one of the tests fails
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-23 12:29:51 -04:00
Anna Schumaker 0fed27b109 submit-patches.zsh: Greatly improve the script
Take a command line option for who to send to, rather than relying on
having the proper variable set or commented out. Also, add some tab
completion.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-16 17:02:29 -04:00
Anna Schumaker 5e1664d88a cthon.zsh: Rewrite test
The runcthon script isn't the most straightforward for passing arbitrary
options or running with a specific NFS version. Deal with this by
writing our own version that does what we need it to do.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-05-16 16:53:21 -04:00
Anna Schumaker 600fd846dc common.zsh: Add automatic version verification
And expand "-v 4" to run all NFS v4 minorversions

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-26 10:56:09 -04:00
Anna Schumaker 3428879918 Move setup-* and run-* scripts into subdirectories
The common prefixes in these scripts indicate that they should really be
in directories and not the toplevel. I also provide a helper script in
$BIN to assist in calling them on the target VMs

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-26 10:33:01 -04:00
Anna Schumaker a2453af9cc common.zsh: Move some common test functions into common.zsh
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-25 15:27:36 -04:00
Anna Schumaker f757dec0ab common.zsh: Pull out common test config into a shared file
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-25 15:27:15 -04:00
Anna Schumaker 59d2891198 Add test script for nfstest read plus
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-22 12:30:44 -04:00
Anna Schumaker dd97c7079b read_plus: Add script for testing the READ_PLUS operation
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-18 11:27:52 -04:00
Anna Schumaker a6d46ff0e1 cthon: Add arguments for printing client and server dmesg log
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-18 11:24:50 -04:00
Anna Schumaker cbcc5ba269 cthon: Have colors script exit with the proper exit code
Otherwise, the script will always return success and pipelines using
cthon.zsh won't work properly

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2022-04-18 11:23:48 -04:00
41 changed files with 1006 additions and 250 deletions

View File

@ -24,7 +24,7 @@ SERVER=cheesecake
# Path where the backup will be placed
# Note that this is on the client, using autofs
BACKUP_DIRECTORY=/net/cheesecake/srv/Backups/`hostname -f`
BACKUP_DIRECTORY=/net/cheesecake/backups/`hostname -f`
# Path on this machine where output should be written
LOG=/tmp/backup.log
@ -48,5 +48,5 @@ if [ $? != 0 ]; then
fi
rsync -axvh --inplace --delete --delete-excluded --exclude-from=$EXCLUDE $BACKUP $BACKUP_DIRECTORY >> $LOG
rsync -axvhz --inplace --delete-delay --delete-excluded --exclude-from=$EXCLUDE $BACKUP $BACKUP_DIRECTORY >> $LOG
notify-send "Backup finished!"

View File

@ -5,6 +5,7 @@ import termcolor
colors = { "b" : "blue", "g" : "green", "s" : "cyan", "l" : "yellow" }
last = "white"
newline = False
status=0
text = ""
def print_text(color, attr=None):
@ -20,16 +21,19 @@ while c := sys.stdin.read(1):
text = "\n" + text if newline else text
newline = False
print_text("red", "bold")
status=1
elif match := re.match("^./server -([bgsl]) .*?\n$", text):
print_text(colors[match.group(1)], None)
elif match := re.match("^Waiting for '([bgsl])' to finish...", text):
elif match := re.match("^Waiting for '\-([bgsl])' to finish ... ", text):
last = colors[match.group(1)]
newline = True
print_text(last, "bold")
elif match := re.match("^ Done: .*?\n$", text):
elif match := re.match("^Done: .*?\n$", text):
print_text(last, "bold")
newline = False
elif c == "\n":
if len(text) > 1:
print_text("white", "bold")
text = ""
sys.exit(status)

View File

@ -21,15 +21,19 @@ add_color_attr("DESCEND", "white", "dark")
add_color_attr("objtool", "yellow", "dark", "bold")
add_color_attr("LD", "yellow")
for line in sys.stdin:
if line[0] == "#":
termcolor.cprint(line, "blue", attrs=["dark", "bold"], end="")
else:
for part in re.split(r'(\s+)', line):
if "/" in part or "(#" in part or os.path.exists(part):
color = "magenta" if re.match("module", part, re.I) else "white"
attrs = ["bold"]
else:
color = make_colors.get(part, "green")
attrs = make_attrs.get(part, [])
termcolor.cprint(part, color, attrs=attrs, end="")
text = ""
while c := sys.stdin.read(1):
text += c
if text[0] == "#":
if re.match("^#(.*?)\n", text):
termcolor.cprint(text, "blue", attrs=["dark", "bold"], end="")
text = ""
elif c in (" ", "\n"):
if "/" in text or "(#" in text or os.path.exists(text):
color = "magenta" if re.match("module", text, re.I) else "white"
attrs = ["bold"]
else:
color = make_colors.get(text.strip(), "green")
attrs = make_attrs.get(text.strip(), [])
termcolor.cprint(text, color, attrs=attrs, end="")
text = ""

View File

@ -1,17 +1,12 @@
#!/usr/bin/python
"""Add color and machine tags to remote pacman output."""
import termcolor
import re
import sys
prefix = sys.argv[1] if len(sys.argv) > 1 else None
pacman_colors = dict()
pacman_attrs = dict()
pacman_colors = {"==>": "green", "->": "blue"}
def add_color_attr(field, color, *attrs):
pacman_colors[field] = color
pacman_attrs[field] = attrs
add_color_attr("==>", "green", "bold")
add_color_attr("->", "blue", "bold")
for line in sys.stdin:
if prefix:
@ -19,8 +14,7 @@ for line in sys.stdin:
if "==>" in line or "->" in line:
for part in re.split(r'(\s+)', line):
color = pacman_colors.get(part, "white")
attrs = pacman_attrs.get(part, ["bold"])
termcolor.cprint(part, color, attrs=attrs, end="")
termcolor.cprint(part, color, attrs=["bold"], end="")
else:
print(line, end="")

107
colors/read_plus.py Normal file
View File

@ -0,0 +1,107 @@
"""Colorize read_plus.zsh output."""
import sys
import re
import termcolor
SIZE = sys.argv[1]
FILE = open(sys.argv[2], 'a') if len(sys.argv) >= 3 else None
COLORS = {"data": "red", "hole": "green", "d": "cyan", "h": "yellow"}
def write_log(text: str, color: str = None,
attrs: list = [], end: str = "") -> None:
"""Print a single formatted string to the screen and possibly a file."""
if FILE:
FILE.write(text + end)
termcolor.cprint(text, color=color, attrs=attrs, end=end)
def print_allocation(prefix: str, name: str,
filetype: str, extra: str) -> None:
"""Format and print file allocation information."""
write_log(prefix, color="white", attrs=["dark"])
write_log(name, color=COLORS[filetype], attrs=["bold"])
write_log(extra, color="white", attrs=["dark"])
def print_allocation_done(done: str, time: str, end: str) -> None:
"""Format and print the time to complete file allocation."""
write_log(done, color="white", attrs=["dark"])
write_log(time, color="blue", attrs=["bold"])
write_log(end, color="white", attrs=["dark"])
def print_reading(prefix: str, name: str,
precache: str, cached: str, postcache: str) -> None:
"""Format and print which file we are currently reading."""
match cached:
case "uncached": ccolor = "yellow"
case "cached": ccolor = "green"
case "unknown": ccolor = "grey"
case _: ccolor = "white"
write_log(prefix, color="white", attrs=["dark"])
write_log(name, color=COLORS[filetype], attrs=["bold"])
write_log(precache, color="white", attrs=["dark"])
write_log(cached, color=ccolor, attrs=["bold"])
write_log(postcache, color="white", attrs=["dark"])
write_log(" ...", color="white", attrs=["dark"])
def print_stats_1(walltime: str, speed: str) -> None:
"""Format and print the transfer time and rate information."""
write_log(" ")
write_log(walltime, color="blue", attrs=["bold"])
write_log(", ", color="white", attrs=["dark"])
write_log(speed, color="green", attrs=["bold"])
write_log(", ", color="white", attrs=["dark"])
def print_stats_2(kerntime: str, kernunits: str, cpu: str) -> None:
"""Format and print time spent in the kernel and cpu usage."""
write_log(kerntime, color="cyan", attrs=["bold"], end=" ")
write_log(kernunits, color="cyan", attrs=["bold"])
write_log(", ", color="white", attrs=["dark"])
write_log(cpu, color="red", attrs=["bold"])
def print_iteration(prefix: str, cur: str, sep: str, total: str) -> None:
"""Format and print the current iteration header."""
write_log(prefix, color="magenta", attrs=["bold", "underline"])
write_log(cur, color="green", attrs=["bold", "underline"])
write_log(sep, color="magenta", attrs=["bold", "underline"])
write_log(total, color="blue", attrs=["bold", "underline"], end="\n")
text = ""
while c := sys.stdin.read(1):
text += c
line = text
text = ""
if match := re.match(r"(Allocating file: )"
rf"({SIZE}M-(data|hole|mixed-\d+(d|h)))( ...)", line):
filetype = match.group(3) if match.group(4) is None else match.group(4)
print_allocation(match.group(1), match.group(2),
filetype, match.group(5))
elif match := re.match(r"( \[Done: )(\d+\.\d+s)(\]\n)", line):
print_allocation_done(match.group(1), match.group(2), match.group(3))
elif match := re.match(rf"(Reading: )({SIZE}M-(data|hole|mixed-\d+(d|h)))"
r"( \()((un)?(cached|known))( on [\w-]*\))\n",
line):
filetype = match.group(3) if match.group(4) is None else match.group(4)
print_reading(match.group(1), match.group(2), match.group(5),
match.group(6), match.group(9))
elif match := re.match(r"\d+ bytes \([\w,\. ]*\) copied, (\d+\.\d+ s), "
r"(\d+\.?\d+ [MG]B/s)\n", line):
print_stats_1(match.group(1), match.group(2))
elif match := re.match(r"(\d+\.\d+)(s kern), (\d+% cpu)", line):
print_stats_2(match.group(1), match.group(2), match.group(3))
elif match := re.match(r"\d+\+\d+ records (in|out)\n", line):
pass
elif match := re.match(r"(Iteration )(\d+)( / )(\d+)\n", line):
print_iteration(match.group(1), match.group(2),
match.group(3), match.group(4))
elif c == "\n":
write_log(line)
else:
text = line

View File

@ -1,86 +1,181 @@
"""Colorize xfstests.zsh output."""
import sys
import re
import termcolor
PROTO_COLORS = { "tcp":"white", "rdma":"yellow" }
PROTO = sys.argv[1]
VERS_COLORS = { "v3":"red", "v4.0":"green", "v4.1":"blue", "v4.2":"yellow" }
PROTO_COLORS = {"tcp": "white", "rdma": "yellow"}
STATUS_COLORS = {"Ran": "cyan", "Not run": "magenta", "Failures": "red"}
VERS_COLORS = {"v3": "red", "v4.0": "green", "v4.1": "blue", "v4.2": "yellow"}
PROTO = sys.argv[1]
VERS = f"v{sys.argv[2]}"
COLOR = VERS_COLORS[VERS]
PROTO_COLOR = PROTO_COLORS[PROTO]
CONFIG = []
prefix = termcolor.colored("[", "white", attrs=["bold"])
prefix += termcolor.colored(PROTO.rjust(4), PROTO_COLORS[PROTO], attrs=["dark"])
prefix += termcolor.colored(",", "white", attrs=["bold"])
prefix += termcolor.colored(VERS.ljust(4), COLOR, attrs=["bold"])
prefix += termcolor.colored("] ", "white", attrs=["bold"])
PREFIX = termcolor.colored("[", "white", attrs=["bold"])
PREFIX += termcolor.colored(PROTO.rjust(4), PROTO_COLOR, attrs=["dark"])
PREFIX += termcolor.colored(",", "white", attrs=["bold"])
PREFIX += termcolor.colored(VERS.ljust(4), COLOR, attrs=["bold"])
PREFIX += termcolor.colored("] ", "white", attrs=["bold"])
CONFIG = [ ]
def add_config(line):
[ key, val ] = [ s.strip() for s in re.split("--", line) ]
def add_config(line: str) -> None:
"""Format a configuration entry and add it to the CONFIG list."""
[key, val] = [s.strip() for s in re.split("--", line)]
if key == "MKFS_OPTIONS":
return
elif key == "MOUNT_OPTIONS" and val[:2] != "-o":
return
parts = [ prefix ]
parts = [PREFIX]
parts.append(termcolor.colored(key.ljust(14), COLOR, attrs=["bold"]))
parts.append(termcolor.colored("-- ", "white", attrs=["dark"]))
parts.append(termcolor.colored(val, "white", attrs=["bold"]))
CONFIG.append("".join(parts))
def print_config():
def print_config() -> None:
"""Print out the collected configuration entries and clear the list."""
if len(CONFIG) > 0:
print("\n".join(CONFIG), end="\n\n")
CONFIG.clear()
def print_test(match):
parts = [ prefix ]
def print_test(match: re.Match) -> None:
"""Format and print a single testcase."""
parts = [PREFIX]
parts.append(termcolor.colored(match.group(1), COLOR, attrs=["bold"]))
if m := re.match("(\[not run\])(.*?\n)", match.group(2)):
if m := re.match(r"(\[not run\])(.*?\n)", match.group(2)):
return
parts.append(termcolor.colored(m.group(1), "yellow"))
parts.append(termcolor.colored(m.group(2), "white", attrs=["bold"]))
elif m := re.match("(\d+s)( ... +)(\d+s\n)", match.group(2)):
elif m := re.match(r"(\d+s)( ... +)(\d+s\n)", match.group(2)):
parts.append(termcolor.colored(m.group(1), "green"))
parts.append(termcolor.colored(m.group(2), "white", attrs=["dark"]))
parts.append(termcolor.colored(m.group(3), "green"))
elif re.match("\d+s\n", match.group(2)):
elif re.match(r"\d+s\n", match.group(2)):
parts.append(termcolor.colored(match.group(2), "green"))
else: # Test failed
line = re.sub("\]-", "\] -", match.group(2))
else: # Test failed
line = re.sub(r"\]-", r"\] -", match.group(2))
parts.append(termcolor.colored(line, "magenta", attrs=["bold"]))
print("".join(parts), end="")
def print_diff(line):
print(prefix, end="")
if re.match(" +@@.*?@@\n", line):
def print_diff(line: str) -> None:
"""Format and print out a single line of a failing test diff."""
print(PREFIX, end="")
if re.match(r" +@@.*?@@\n", line):
termcolor.cprint(line, color="yellow", attrs=["dark"], end="")
elif re.match(" +-", line):
elif re.match(r" +-", line):
termcolor.cprint(line, color="magenta", attrs=["dark"], end="")
elif re.match(" +\+", line):
elif re.match(r" +\+", line):
termcolor.cprint(line, color="cyan", attrs=["dark"], end="")
elif re.match(" +\(Run", line):
elif re.match(r" +\(Run", line):
termcolor.cprint(line, color="magenta", attrs=["bold"], end="")
else:
termcolor.cprint(line, color="white", attrs=["dark"], end="")
def print_test_list(status: str, line: str) -> None:
"""Format and print the list of tests that ran, failed, or were skipped."""
tests = dict()
_tmp = [t.split("/") for t in line[len(status)+1:].split()]
[tests.setdefault(t[0], []).append(t[1]) for t in _tmp]
for key in sorted(tests.keys()):
parts = [PREFIX]
parts.append(termcolor.colored(status, STATUS_COLORS[status],
attrs=["bold"]))
parts.append(termcolor.colored(": ", "white", attrs=["bold"]))
parts.append(termcolor.colored(key, color=COLOR, attrs=["bold"]))
parts.append(termcolor.colored(": [", "white", attrs=["bold"]))
for i, test_num in enumerate(sorted(tests[key])):
sep = termcolor.colored(", ", attrs=["bold"] if i > 0 else "")
if i != 0:
parts.append(sep)
attr = ["bold", "dark"] if i % 2 else ["bold"]
parts.append(termcolor.colored(test_num, STATUS_COLORS[status],
attrs=attr))
parts.append(termcolor.colored("]", "white", attrs=["bold"]))
print("".join(parts))
def print_failed(match: re.Match) -> None:
"""Format and print the number of failing tests."""
parts = [PREFIX]
parts.append(termcolor.colored("Failed ", "red", attrs=["bold"]))
parts.append(termcolor.colored(match.group(1), COLOR, attrs=["bold"]))
parts.append(termcolor.colored(" of ", "red", attrs=["bold"]))
parts.append(termcolor.colored(match.group(2), COLOR, attrs=["bold"]))
parts.append(termcolor.colored(" tests", "red", attrs=["bold"]))
print("".join(parts))
def print_all_passed(match: re.Match) -> None:
"""Format and print a status line if all tests pass."""
parts = [PREFIX]
parts.append(termcolor.colored("Passed all ", "green", attrs=["bold"]))
parts.append(termcolor.colored(match.group(1), COLOR, attrs=["bold"]))
parts.append(termcolor.colored(" tests", "green", attrs=["bold"]))
print("".join(parts))
def print_xunit(match: re.Match) -> None:
"""Format and print the xunit file location."""
parts = [PREFIX]
parts.append(termcolor.colored(match.group(1), PROTO_COLOR,
attrs=["dark", "bold"]))
parts.append(termcolor.colored(": ", "white", attrs=["bold"]))
parts.append(termcolor.colored(match.group(2), COLOR, attrs=["bold"]))
print("".join(parts))
def print_xfstestsdb(match: re.Match) -> None:
"""Format and print the xfstestsdb xunit-add line."""
parts = [PREFIX]
parts.append(termcolor.colored(match.group(1).title(), PROTO_COLOR,
attrs=["dark", "bold"]))
parts.append(termcolor.colored(" '", "white", attrs=["bold"]))
parts.append(termcolor.colored(match.group(2), COLOR,
attrs=["bold"]))
parts.append(termcolor.colored("' ", "white", attrs=["bold"]))
parts.append(termcolor.colored(match.group(3), PROTO_COLOR,
attrs=["dark", "bold"]))
parts.append(termcolor.colored(match.group(4), COLOR, attrs=["bold"]))
parts.append(termcolor.colored(match.group(5), PROTO_COLOR,
attrs=["dark", "bold"]))
parts.append(termcolor.colored(" #", "white", attrs=["bold"]))
parts.append(termcolor.colored(match.group(6), COLOR,
attrs=["bold"]))
print("".join(parts))
for line in sys.stdin:
if line == "\n":
print_config()
elif re.match("^[A-Z_]+[ ]+-- .*?\n", line):
if match := re.match("(^PLATFORM(.*?)PREEMPT)(.*?\n)", line):
if match := re.match("(^PLATFORM(.*?)PREEMPT.*?) (.*?\n)", line):
add_config(match.group(1))
line = f"COMPILED -- {match.group(3)}"
add_config(line)
elif match := re.match("(^[a-z]+/[\d]+[ | ]+)(.*?\n)", line):
elif match := re.match(r"(^[a-z]+/\d+[ | ]+)(.*?\n)", line):
print_test(match)
elif match := re.match("^ (.*?)\n", line):
print_diff(line)
elif match := re.match(r"^(Ran|Not run|Failures):([ a-z]+/\d+)+\n", line):
print_test_list(match.group(1), line)
elif match := re.match(r"^Failed (\d+) of (\d+) tests\n", line):
print_failed(match)
elif match := re.match(r"^Passed all (\d+) tests\n", line):
print_all_passed(match)
elif match := re.match(r"(^Xunit report): (.*?.xml)\n", line):
print_xunit(match)
elif match := re.match(r"(^added) '(.*?)' (with )"
r"(\d+)( testcases to run) #(\d+)\n", line):
print_xfstestsdb(match)
else:
#pass
print(prefix, end="")
print(line, end="")
print(PREFIX + line, end="")

101
common.zsh Normal file
View File

@ -0,0 +1,101 @@
#!/bin/zsh
##############################
# #
# NFS client configuration #
# #
##############################
CLIENT=(client)
MOUNTPOINT=(/mnt/test)
SCRATCHMNT=(/mnt/scratch)
##############################
# #
# NFS server configuration #
# #
##############################
SERVER=(server)
EXPORT=(/srv/xfs/test)
SCRATCH=(/srv/xfs/scratch)
NO_SERVER_ACCESS=()
###########################
# #
# General configuration #
# #
###########################
BIN=$HOME/.local/bin
COLORS=$BIN/colors
DMESG=()
PROTO=(tcp)
SRVDMESG=()
USER=$(whoami)
VERSION=(3 4)
######################
# #
# Shared functions #
# #
######################
function client_run()
{
zparseopts -D -K t=TERMINAL
[[ ! -z $TERMINAL ]] && SSH_OPT="-t"
ssh $SSH_OPT ${CLIENT[-1]} sudo run.zsh $*
}
function client_setup()
{
ssh ${CLIENT[-1]} sudo setup.zsh $*
}
function setup_client_func()
{
client_setup testdirs.zsh ${SERVER[-1]} ${EXPORT[-1]} \
${MOUNTPOINT[-1]} $USER
}
function prepare_to_test()
{
$BIN/vm.zsh boot ${CLIENT[-1]} ${SERVER[-1]}
$BIN/install-scripts.zsh ${CLIENT[-1]}
if [ ${#DMESG} -gt 0 ]; then
ssh ${CLIENT[-1]} "sudo dmesg --clear"
fi
if [ ${#SRVDMESG} -gt 0 ]; then
ssh ${SERVER[-1]} "sudo dmesg --clear"
fi
if [ ${#RDMA} -gt 0 ]; then
PROTO+=(rdma)
if [ ${#NO_SERVER_ACCESS} -gt 0 ]; then
$BIN/rdma.zsh ${RDMA[-1]} ${CLIENT[-1]}
else
$BIN/rping.zsh ${RDMA[-1]} ${CLIENT[-1]} ${SERVER[-1]}
fi
fi
setup_client_func
check_versions
echo
}
function check_versions()
{
valid=(3 4.0 4.1 4.2)
if [[ ${VERSION[(ie)4]} -le ${#VERSION} ]]; then
VERSION+=(4.0 4.1 4.2)
fi
VERSION=(${(ou)VERSION})
VERSION=(${VERSION:*valid})
}
TRAPEXIT()
{
if [ ${#DMESG} -gt 0 ]; then
ssh ${CLIENT[-1]} "sudo dmesg --color=always"
fi
if [ ${#SRVDMESG} -gt 0 ]; then
ssh ${SERVER[-1]} "sudo dmesg --color=always"
fi
}

View File

@ -2,15 +2,24 @@
function _cthon.zsh() {
_arguments \
{-a,--all}'[run all tests]' \
{-b,--basic}'[run basic tests]' \
{-c,--client}'[the client to test]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
--nconnect'[number of connections]: :($(seq 1 32))' \
"domains\:domains\: _libvirt"' \
--dmesg'[print client dmesg log after running tests]' \
{-g,--general}'[run general tests]' \
{-l,--locking}'[run locking tests]' \
--no-server-access'[do not attempt to ssh into the server]' \
\*{-o,--options}'[mount options for all mounts]: :' \
--krb5'[run tests with sec=krb5]' \
--srvdmesg'[print server dmesg log after running tests]' \
{-p,--mountpoint}'[the directory to mount the server]: : _files -/' \
{-r,--rdma}'[test using rdma]: :(rxe siw)' \
{-s,--server}'[the server to test against]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
"domains\:domains\: _libvirt"' \
{-S,--special}'[run special tests]' \
\*{-v,--version}+'[the nfs version to test (default=all)]: :(3 4 4.0 4.1 4.2)' \
{-x,--export}'[the exported directory on the server]: : _files -/'
}

View File

@ -1,7 +1,11 @@
#compdef makelinux.zsh
function _makelinux.zsh() {
_arguments '*: :_make'
_arguments \
--clang'[compile using clang]' \
--gcc'[compile using gcc]' \
--arm64'[cross-compile for arm64]' \
'*: :_make'
}
_makelinux.zsh "$@"

View File

@ -0,0 +1,15 @@
#compdef nfstest_rplus.zsh
function _nfstest_rplus.zsh() {
_arguments \
{-c,--client}'[the client to test]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
--dmesg'[print client dmesg log after running tests]' \
--srvdmesg'[print server dmesg log after running tests]' \
{-p,--mountpoint}'[the directory to mount the server]: : _files -/' \
{-s,--server}'[the server to test against]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
{-x,--export}'[the exported directory on the server]: : _files -/'
}

View File

@ -0,0 +1,20 @@
#compdef read_plus.zsh
function _read_plus.zsh() {
_arguments \
{-c,--client}'[the client to test]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
{-d,--direct}'[call dd with iflag=direct]' \
--dmesg'[print client dmesg log after running tests]' \
{-f,--file}'[write output to file]: : _files' \
{-i,--iterations}'[number of times to repeat the test]: :($(seq 100))' \
{-p,--mountpoint}'[the directory to mount the server]: : _files -/' \
--no-server-vmtouch'[do not vmtouch the files on the server]' \
--srvdmesg'[print server dmesg log after running tests]' \
{-s,--server}'[the server to test against]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
{-x,--export}'[the exported directory on the server]: : _files -/' \
{-z,--size}'[the size of the test files]: :($(seq 5120))'
}

View File

@ -0,0 +1,10 @@
#compdef submit-patches.zsh
function _submit-patches.zsh() {
_arguments \
--linus'[submit to Linus Torvalds]' \
--nfs'[submit to nfs maintainers]' \
--nfsd'[submit to nfsd maintainers]' \
--nfsutils'[submit to nfs-utils maintainers]' \
{--xfstests,--fstests}'[submit to xfstests maintainers]'
}

View File

@ -5,14 +5,30 @@ function _xfstests.zsh() {
{-c,--client}'[the client to test]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
{-g,--group}'[the xfstests group to run]: :($(_list_xfstests_groups))' \
{-k,--scratch}'[the exported scratch directory on the server]: : _files -/' \
{-p,--mountpoint}'[the directory to mount the server]: : _files -/' \
--nconnect'[number of connections]: :($(seq 1 32))' \
--no-scratch'[do not use a scratch mount during testing]' \
--no-server-access'[do not attempt to ssh into the server]' \
\*{-o,--options}'[mount options for all mounts]: :' \
{-r,--rdma}'[test using rdma]: :(rxe siw)' \
{-q,--scratchmnt}'[the directory to mount the scratch export]: : _files -/' \
{-s,--server}'[the server to test against]: : _alternative
"hosts\:hosts\: _ssh_hosts"
"domains\:domains\:($(virsh list --all --name))"' \
\*{-v,--version}+'[the nfs version to test (default=all)]: :(3 4.0 4.1 4.2)' \
\*{-v,--version}+'[the nfs version to test (default=all)]: :(3 4 4.0 4.1 4.2)' \
{-x,--export}'[the exported directory on the server]: : _files -/'
}
function _list_xfstests_groups() {
if [ ! -f /tmp/xfstests.groups.completion ]; then
find $HOME/Programs/xfstests-dev -name group.list \
-exec grep -P '^\d+' '{}' \; | \
awk '{$1=""; print $0}' | \
awk -F\# '{print $1}' | \
grep -o -E '\w+' | \
sort | uniq > /tmp/xfstests.groups.completion
fi
cat /tmp/xfstests.groups.completion
}

View File

@ -1,43 +1,60 @@
#!/bin/zsh -e
CLIENT=(client)
SERVER=(server)
EXPORT=(/srv/test)
MOUNTPOINT=(/mnt/test)
source common.zsh
TESTS=(-a)
zparseopts -F -K \
a+=TESTS -all+=TESTS \
b+=TESTS -basic+=TESTS \
c:=CLIENT -client:=CLIENT \
-dmesg=DMESG -srvdmesg=SRVDMESG \
g+=TESTS -general+=TESTS \
l+=TESTS -locking+=TESTS \
o+:=MNTOPTS -options+:=MNTOPTS \
p:=MOUNTPOINT -mountpoint:=MOUNTPOINT \
-nconnect:=NCONNECT \
-no-server-access=NO_SERVER_ACCESS \
-krb5=KRB5 \
r:=RDMA -rdma:=RDMA \
S+=TESTS -special+=TESTS \
s:=SERVER -server:=SERVER \
x:=EXPORT -export:=EXPORT
x:=EXPORT -export:=EXPORT \
v+:=VERSION -version+:=VERSION
BIN=$HOME/bin
COLOR=$BIN/colors/cthon.py
RUN_CTHON="cd cthon04 && sudo ./runcthon"
USER=$(whoami)
SEC=(sys)
ARGS=($(echo $MNTOPTS | sed 's/-o /--mntopt /g'))
#
# Prepare to test
#
$BIN/vm.zsh boot ${CLIENT[-1]} ${SERVER[-1]}
$BIN/install-scripts.zsh ${CLIENT[-1]}
if [ ${#RDMA} -gt 0 ]; then
RUN_CTHON="$RUN_CTHON --rdma"
$BIN/rping.zsh ${RDMA[-1]} ${CLIENT[-1]} ${SERVER[-1]}
fi
if [ ${#NCONNECT} -gt 0 ]; then
RUN_CTHON="$RUN_CTHON --nconnect ${NCONNECT[-1]}"
prepare_to_test
if [[ ${TESTS[(ie)-a]} -le ${#TESTS} ]]; then
TESTS=(-b -g -s -l)
fi
if [ ${#KRB5} -gt 0 ]; then
RUN_CTHON="$RUN_CTHON --dokrb5"
SEC+=(krb5 krb5i krb5p)
fi
ssh ${CLIENT[-1]} "sudo setup-testdirs.zsh ${SERVER[-1]} ${EXPORT[-1]} ${MOUNTPOINT[-1]} $USER" | python $COLOR
echo
for vers in $VERSION; do
ARGS+=("--version $vers")
done
#
# Run tests
#
ssh ${CLIENT[-1]} "$RUN_CTHON --server ${SERVER[-1]} --serverdir ${EXPORT[-1]}/$USER 2>&1" | python -u $COLOR
function run_cthon_zsh()
{
client_run cthon.zsh --server ${SERVER[-1]} --export ${EXPORT[-1]} \
--mountpoint ${MOUNTPOINT[-1]} --user $USER \
--proto $2 --mntopt sec=$3 $1 $ARGS \
| python -u $COLORS/cthon.py
}
ret=0
set +e
date | python -u $COLORS/cthon.py
for test in $TESTS; do
for proto in $PROTO; do
for sec in $SEC; do
run_cthon_zsh $test $proto $sec
ret=$((ret+$?))
done
done
done
exit $ret

View File

@ -1,14 +1,31 @@
#!/bin/zsh -e
source common.zsh
autoload colors
colors
OPTS=(--clang)
zparseopts -D -K -clang+=OPTS -gcc+=OPTS -arm64+=OPTS -i686+=OPTS
if [ "$#" -lt 1 ]; then
echo "Usage: $0 {remote host, ...}"
exit 1
fi
makepkg -f
deploypkg.zsh $(makepkg --packagelist) $*
case ${OPTS[-1]} in
--clang) export CC=clang ;;
--gcc) export CC=gcc ;;
--arm64) export CC=gcc
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
;;
--i686) export CC=gcc
export ARCH=i386
;;
esac
PKGDEST=packages makepkg -f
PKGDEST=packages deploypkg.zsh $(makepkg --packagelist) $*
pkgname=$(grep ^pkgname PKGBUILD | awk -F= '{print $2}')
@ -22,7 +39,7 @@ echo
vm.zsh reboot $*
echo
tags=($(python /home/anna/bin/colors/vm.py $*))
tags=($(FORCE_COLOR=1 python $COLORS/vm.py $*))
for ((i=1; i<=$#; i++)); do
echo "${tags[i]} $fg_bold[default]$(ssh ${@[i]} uname -rsn)$reset_color"
done

View File

@ -1,5 +1,5 @@
#!/bin/zsh
colors="$HOME/bin/colors"
source common.zsh
if [ "$#" -lt 2 ]; then
echo "Usage: $0 /path/to/package {remote host, ...}"
@ -12,11 +12,12 @@ shift
function deploy_package() {
ssh $1 "mkdir -pv pkg" 2>&1 | sed -e "s/^/$2 /"
script -q -c "scp $pkg $1:pkg/ 2>&1" 2>&1 | sed -e "s/^/$2 /"
ssh $1 "sudo pacman --noconfirm -U pkg/$pkg" | python $colors/pacman.py $2
ssh $1 "sudo pacman --noconfirm -U pkg/$pkg" | python $COLORS/pacman.py $2
}
$HOME/bin/vm.zsh boot $*
tags=($(python $colors/vm.py $*))
$BIN/vm.zsh boot $*
tags=($(FORCE_COLOR=1 python $COLORS/vm.py $*))
for ((i=1; i<=$#; i++)); do
deploy_package ${@[i]} ${tags[i]} &
done

View File

@ -1,19 +1,19 @@
#!/bin/zsh
source common.zsh
BIN=$HOME/bin
SCRIPTS=(grub-list.zsh setup-testdirs.zsh \
setup-xfstests.zsh run-xfstests.zsh)
SCRIPTS=(grub-list.zsh setup.zsh setup/ run/)
function install_script() {
ssh $1 mkdir -p bin/
ssh $1 mkdir -p .local/bin/{setup,run}
echo -n "$2 Copying files ..."
for script in $SCRIPTS; do
scp -q $BIN/$script $1:bin/
scp -qr $BIN/$script $1:.local/bin/
done
ssh $1 cp .local/bin/setup.zsh .local/bin/run.zsh
echo " done"
}
tags=($(python $BIN/colors/vm.py $*))
tags=($(FORCE_COLOR=1 python $COLORS/vm.py $*))
for ((i=1; i<=${#@}; i++)); do
install_script ${@[i]} ${tags[i]}
done

View File

@ -1,117 +1,151 @@
#!/usr/bin/python
"""Iterate through KConfig options, enabling them one by one."""
import argparse
import pathlib
import re
import subprocess
import sys
import termcolor
import typing
parser = argparse.ArgumentParser()
parser.add_argument("-q", "--quick", action="store_true", dest="quick",
help="Only compile the subdirectory containing the Kconfig file")
parser.add_argument("kconfig", metavar="Kconfig", nargs=1, help="Path to Kconfig file")
parser.add_argument("makeargs", metavar="Make Arguments", nargs="*", help="Options to pass to make")
help="Only compile the subdirectory "
"containing the Kconfig file")
parser.add_argument("kconfig", metavar="Kconfig", nargs=1,
help="Path to Kconfig file")
parser.add_argument("makeargs", metavar="Make Arguments", nargs="*",
help="Options to pass to make")
Args = parser.parse_args()
Args = parser.parse_args()
Kconfig = pathlib.Path(Args.kconfig[0])
Config = pathlib.Path("scripts/config").absolute()
Make = pathlib.Path("~/bin/makelinux.zsh").expanduser()
MakeArg = Args.makeargs + ([ f"{str(Kconfig)}/" ] if Args.quick else [ ])
Config = pathlib.Path("scripts/config").absolute()
Make = pathlib.Path("~/.local/bin/makelinux.zsh").expanduser()
MakeArg = Args.makeargs + ([f"{str(Kconfig)}/"] if Args.quick else [])
Options = dict()
Colors = { "n" : "grey", "y" : "green", "m" : "cyan" }
Attrs = { "y" : [ "bold" ], "m" : [ "bold" ] }
Colors = {"n": "dark_grey", "y": "green", "m": "cyan"}
Attrs = {"y": ["bold"], "m": ["bold"]}
NameLen = 0
if Kconfig.is_dir():
Kconfig = Kconfig / "Kconfig"
def assert_exists(path):
for path in [Kconfig, Make, Config]:
if not path.exists():
print(f"Error: {path} does not exist!")
sys.exit(1)
assert_exists(Kconfig)
assert_exists(Make)
assert_exists(Config)
class Option:
def __init__(self, opt):
"""Represents a single CONFIG_* KConfig Option."""
def __init__(self, opt: str):
"""Initialize our Option class."""
lines = opt.splitlines()
self.name = lines[0].strip()
self.type = lines[1].strip().split()[0]
self.state = "y"
self.res = None
if search := re.search("\sdepends on (.*?)\n", opt):
if search := re.search(r"\sdepends on (.*?)\n", opt):
depends = search.group(1).strip()
depends = [ d.strip() for d in re.split("[&&|=m|=y|=n]", depends) ]
self.depends = set([ d for d in depends if len(d) > 0 ])
depends = [d.strip() for d in re.split("[&&|=m|=y|=n]", depends)]
self.depends = set([d for d in depends if len(d) > 0])
else:
self.depends = set()
def __repr__(self):
def __repr__(self) -> str:
"""Return a string representation of this Option."""
return f"{self.name}:{self.type}"
def __lt__(self, rhs):
if self.name.endswith("DEBUG"): return False
if rhs.name.endswith("DEBUG"): return True
def __lt__(self, rhs: typing.Self) -> bool:
"""Check if this option is less than the `rhs` option."""
if self.name.endswith("DEBUG"):
return False
if rhs.name.endswith("DEBUG"):
return True
return self.name in rhs.dependencies()
def dependencies(self):
def dependencies(self) -> set[typing.Self]:
"""Get a set of dependencies for this Option."""
ret = self.depends.copy()
for dep in self.depends:
if (opt := Options.get(dep)) is not None:
ret.update(opt.dependencies())
return ret
def disable(self):
subprocess.run([ Config ] + [ "--disable", self.name ]).check_returncode()
def disable(self) -> None:
"""Disable this Option."""
subprocess.run([Config] + ["--disable", self.name]).check_returncode()
self.state = "n"
def enable(self):
def enable(self) -> None:
"""Enable this Option."""
how = "--module" if self.type == "tristate" else "--enable"
subprocess.run([ Config ] + [ how, self.name ]).check_returncode()
subprocess.run([Config] + [how, self.name]).check_returncode()
self.state = "m" if self.type == "tristate" else "y"
def print(self):
def print(self) -> None:
"""Print out this option (in color!)."""
print(" ", end="")
termcolor.cprint(self.name, Colors.get(self.state), attrs=["bold", "dark"], end="")
termcolor.cprint(self.name, Colors.get(self.state),
attrs=["bold", "dark"], end="")
termcolor.cprint("=", "white", attrs=["bold"], end="")
termcolor.cprint(self.state, Colors.get(self.state), attrs=["bold", "dark"])
termcolor.cprint(self.state, Colors.get(self.state),
attrs=["bold", "dark"])
def print_result(self) -> None:
"""Print out this option and result."""
attrs = [] if self.res is None else ["bold"]
def print_result(self):
match self.res:
case True: result = ("Success", "green")
case False: result = ("Failed", "red")
case _: result = ("Not Run", "yellow")
termcolor.cprint(" " + self.name + " ", Colors.get(self.state), attrs=["bold", "dark"], end="")
termcolor.cprint(" " * (NameLen - len(self.name)), "grey", attrs=["underline"], end="")
termcolor.cprint(" " + result[0], result[1], attrs=["bold", "dark"])
termcolor.cprint(" " + self.name + " ", Colors.get(self.state),
attrs=attrs, end="")
termcolor.cprint(" " * (NameLen - len(self.name)), "grey",
attrs=["underline"], end="")
termcolor.cprint(" " + result[0], result[1], attrs=attrs)
with open(Kconfig) as f:
regex = re.compile("\nconfig")
opts = [ Option(opt) for opt in regex.split(f.read()) if opt[0] != "#" ]
Options = { opt.name:opt for opt in opts if opt.type in [ "bool", "tristate" ]}
opts = [Option(opt) for opt in regex.split(f.read()) if opt[0] != "#"]
Options = {opt.name: opt for opt in opts
if opt.type in ["bool", "tristate"]}
options = list(Options.values())
options.sort()
options = list(sorted(Options.values()))
def make_opt(option):
def make_opt(option: Option) -> None:
"""Enable and build a single option."""
option.enable()
print()
for o in options: o.print()
for o in options:
o.print()
option.res = False
subprocess.run([ Make ] + [ "olddefconfig" ]).check_returncode()
subprocess.run([ Make ] + MakeArg).check_returncode()
subprocess.run([Make] + ["olddefconfig"]).check_returncode()
subprocess.run([Make] + MakeArg).check_returncode()
option.res = True
try:
for opt in options: NameLen = max(NameLen, len(opt.name) + 2)
for opt in options: opt.disable()
for opt in options: make_opt(opt)
for opt in options:
NameLen = max(NameLen, len(opt.name) + 2)
opt.disable()
for opt in options:
make_opt(opt)
except Exception as e:
print(str(e))
finally:
termcolor.cprint(f"\nKconfig Results:", "yellow", attrs=["bold", "underline"])
for opt in options: opt.print_result()
if False in [ opt.res for opt in options ]: sys.exit(1)
print()
termcolor.cprint("Kconfig Results:", "yellow", attrs=["bold", "underline"])
for opt in options:
opt.print_result()
if False in [opt.res for opt in options]:
sys.exit(1)

View File

@ -1,11 +1,33 @@
#!/bin/zsh
source common.zsh
set -eo pipefail
let jobs=$(nproc)-2
OPTS=(--clang)
zparseopts -D -K -clang+=OPTS -gcc+=OPTS -arm64+=OPTS -i686+=OPTS -env+=OPTS
[[ -z "$ARCH" ]] && ARCH=$(uname -m)
case ${OPTS[-1]} in
--clang) CC=clang ;;
--gcc) CC=gcc ;;
--arm64) ARCH=arm64
CC=gcc
CROSS_COMPILE=aarch64-linux-gnu-
;;
--i686) ARCH=i386
CC=gcc
;;
esac
if [ -f .git/config ] && [ -f .git/HEAD ]; then
REV=$(git rev-parse --short HEAD)$(git diff --quiet || echo "-dirty")
scripts/config --set-str CONFIG_LOCALVERSION "-g$REV"
fi
make -j$jobs $* | python /home/anna/bin/colors/make.py
make -j$jobs CC=$CC ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE $* | python -u $COLORS/make.py
if [[ "$CC" == "clang" ]]; then
scripts/clang-tools/gen_compile_commands.py &
fi

15
nfstest_rplus.zsh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/zsh -e
source common.zsh
zparseopts -F -K \
c:=CLIENT -client:=CLIENT \
-dmesg=DMESG -srvdmesg=SRVDMESG \
p:=MOUNTPOINT -mountpoint:=MOUNTPOINT \
s:=SERVER -server:=SERVER \
x:=EXPORT -export:=EXPORT
prepare_to_test
client_run -t nfstest-rplus.zsh --server ${SERVER[-1]} \
--export ${EXPORT[-1]} \
--mountpoint ${MOUNTPOINT[-1]} \
--user $USER

View File

@ -2,10 +2,12 @@
url=git://git.linux-nfs.org/projects/anna/linux-nfs.git
[ -z "$1" ] && tag="v5.*-rc*" || tag="$1"
[ -z "$1" ] && tag="v6.*-rc*" || tag="$1"
old=$(git describe --tags --abbrev=0 --match $tag)
new=$(git describe)
echo "Subject: [GIT PULL] <INSERT SUBJECT HERE>"
echo
echo "Hi Linus,"
echo
git request-pull $old $url HEAD:$new
git request-pull $old $url $new

View File

@ -1,4 +1,5 @@
#!/bin/zsh
source common.zsh
if [ "$#" -lt 2 ]; then
echo "Usage: $0 {rxe,siw,info,start,status,stop,off} {remote host,...}"
@ -55,7 +56,7 @@ rdma_stop() {
}
IFS=$'\n'
tags=($(python /home/anna/bin/colors/vm.py ${@:2}))
tags=($(FORCE_COLOR=1 python $COLORS/vm.py ${@:2}))
for vm in "${@:2}"; do
index=${@[(ie)$vm]}
tag=${tags[index-1]}

86
read_plus.zsh Executable file
View File

@ -0,0 +1,86 @@
#!/bin/zsh -e
source common.zsh
SIZE=(2048)
ITERATIONS=(1)
zparseopts -D -F -K \
c:=CLIENT -client:=CLIENT \
d=DIRECT -direct=DIRECT \
-dmesg=DMESG -srvdmesg=SRVDMESG \
-no-server-vmtouch=NO_VMTOUCH \
f:=FILE -file:=FILE \
i:=ITERATIONS -iterations:=ITERATIONS \
p:=MOUNTPOINT -mountpoint:=MOUNTPOINT \
s:=SERVER -server:=SERVER \
x:=EXPORT -export:=EXPORT \
z:=SIZE -size:=SIZE
COLOR="python -u $COLORS/read_plus.py ${SIZE[-1]} ${FILE[-1]}"
IFLAG=
SRV_DIR=${EXPORT[-1]}/$USER/read_plus
TEST_DIR=${MOUNTPOINT[-1]}/read_plus
TEST_DEV=${SERVER[-1]}:$SRV_DIR
TEST_FILES=(${SIZE[-1]}M-{data,hole,mixed-{1,2,3,4,5,6,7,8,16}{d,h}})
CACHE_STATUS=(uncached cached)
TIME_CMD="sudo /usr/bin/time -f \"%Ss kern, %P cpu\""
if [ "$#" -gt 0 ]; then
TEST_FILES=($*)
fi
#
# Prepare to test
#
function setup_client_func()
{
client_setup read_plus.zsh ${SERVER[-1]} ${EXPORT[-1]} \
${MOUNTPOINT[-1]} $USER ${SIZE[-1]} \
1,2,3,4,5,6,7,8,16 | eval ${COLOR}
}
if [ ${#FILE} -gt 1 ]; then
mkdir -p $(dirname ${FILE[-1]})
[[ -f ${FILE[-1]} ]] && rm -fv ${FILE[-1]}
touch ${FILE[-1]}
fi
if [ ${#DIRECT} -gt 0 ]; then
IFLAG="iflag=direct"
fi
if [ ${#NO_VMTOUCH} -gt 0 ]; then
CACHE_STATUS=unknown
fi
prepare_to_test
function dd_file() {
echo "Reading: $1 ($2 on ${SERVER[-1]})"
case $2 in
"uncached") args="eq" ;;
"cached") args="tq" ;;
"unknown") args= ;;
esac
if [ ! -z $args ]; then
ssh ${SERVER[-1]} "sudo vmtouch -$args $SRV_DIR/$1"
fi
ssh ${CLIENT[-1]} "sudo vmtouch -eq $TEST_DIR/$1"
ssh ${CLIENT[-1]} "$TIME_CMD dd if=$TEST_DIR/$1 $IFLAG of=/dev/null bs=$3"
}
for i in $(seq ${ITERATIONS[-1]}); do
[[ $i -gt 1 ]] && echo
[[ ${#FILE} -gt 1 ]] && echo >> ${FILE[-1]}
ssh ${CLIENT[-1]} "sudo mount -o sec=sys,v4.2 $TEST_DEV $TEST_DIR"
bsize=$(ssh ${CLIENT[-1]} "mount | grep $TEST_DEV" | awk -F rsize= '{print $2}' | awk -F, '{print $1}')
if [[ ${ITERATIONS[-1]} -gt 1 ]]; then
echo "Iteration $i / ${ITERATIONS[-1]}" | eval ${COLOR}
fi
for f in $TEST_FILES; do
for cache in $CACHE_STATUS; do
dd_file $f $cache $bsize 2>&1 | eval ${COLOR}
done
done
ssh ${CLIENT[-1]} "sudo umount $TEST_DIR"
done

View File

@ -38,7 +38,7 @@ class Results(Property):
class Model(GObject.GObject, Gio.ListModel):
def __init__(self, properties):
GObject.GObject.__init__(self)
self.properties = [ Property(p, properties[p]) for p in PROPERTIES ]
self.properties = [ Property(p, properties.get(p)) for p in PROPERTIES ]
self.properties.append(Results(properties))
def do_get_item_type(self): return GObject.TYPE_PYOBJECT
@ -73,7 +73,9 @@ class Factory(Gtk.SignalListItemFactory):
label = listitem.get_child()
match self.column:
case "Property": label.set_text(listitem.get_item().key)
case "Value": label.set_text(listitem.get_item().value)
case "Value":
value = listitem.get_item().value
label.set_text(value if value else "")
case _: label.set_text("=")
def on_unbind(self, factory, listitem):

View File

@ -3,6 +3,7 @@ from gi.repository import GObject
from gi.repository import Gtk
import html
import pathlib
import re
import tarfile
import xml.etree.ElementTree
@ -23,20 +24,24 @@ class SkippedTest:
self.message = elm[0].attrib["message"]
self.message = self.message.replace(test_dev, "$TEST_DEV")
self.message = self.message.replace(test_dir, "$TEST_DIR")
self.message = self.message.replace(scratch_dev, "$SCRATCH_DEV")
self.message = self.message.replace(scratch_mnt, "$SCRATCH_MNT")
if scratch_dev:
self.message = self.message.replace(scratch_dev, "$SCRATCH_DEV")
if scratch_mnt:
self.message = self.message.replace(scratch_mnt, "$SCRATCH_MNT")
class FailedTest:
def __init__(self, elm):
def __init__(self, ns, elm):
self.time = elm.attrib["time"]
self.system_out = Gtk.TextBuffer()
self.system_err = Gtk.TextBuffer()
for e in elm:
match e.tag:
case "failure": self.message = e.attrib["message"]
case "system-out": self.system_out.set_text(html.unescape(e.text))
case "system-err": self.system_err.set_text(html.unescape(e.text))
if e.tag == f"{ns}failure":
self.message = e.attrib["message"]
elif e.tag == f"{ns}system-out":
self.system_out.set_text(html.unescape(e.text))
elif e.tag == f"{ns}system-err":
self.system_err.set_text(html.unescape(e.text))
class TestCase(GObject.GObject):
@ -66,26 +71,29 @@ class TestResults:
self.versions.append(pathlib.Path(name).stem)
passed = 0
match = re.match(r"{.*?}", root.tag)
ns = match.group(0) if match else ""
for prop in root.attrib.keys():
self.set_property(prop, root.attrib[prop])
for elm in root:
if elm.tag == "properties":
if elm.tag == f"{ns}properties":
for prop in elm:
self.set_property(prop.attrib["name"], prop.attrib["value"])
elif elm.tag == "testcase":
elif elm.tag == f"{ns}testcase":
if len(elm) == 0:
result = PassingTest(elm)
passed += 1
elif elm[0].tag == "skipped":
elif elm[0].tag == f"{ns}skipped":
result = SkippedTest(elm,
self.properties[self.versions[-1]]["TEST_DEV"],
self.properties[self.versions[-1]]["TEST_DIR"],
self.properties[self.versions[-1]]["SCRATCH_DEV"],
self.properties[self.versions[-1]]["SCRATCH_MNT"])
self.properties[self.versions[-1]].get("SCRATCH_DEV"),
self.properties[self.versions[-1]].get("SCRATCH_MNT"))
self.skipped.add(result.message)
elif elm[0].tag == "failure":
result = FailedTest(elm)
elif elm[0].tag == f"{ns}failure":
result = FailedTest(ns, elm)
self.add_testcase(elm.attrib["name"], result)
self.set_property("passed", str(passed))

View File

@ -124,6 +124,7 @@ class Filter(Gtk.Filter):
match type(testcase[key]):
case testresults.PassingTest:
res = [ "passing", "passed" ]
search.append(f"time={testcase[key].time}")
case testresults.SkippedTest:
res = [ "skipped" ]
search.append(f"message={testcase[key].message}")
@ -171,7 +172,7 @@ class Viewer(Gtk.ScrolledWindow):
self.columnview = Gtk.ColumnView.new(model=self.selection)
self.columnview.add_css_class("data-table")
self.provider.load_from_data(CSS.encode())
self.provider.load_from_data(CSS, -1)
self.get_style_context().add_provider_for_display(self.get_display(), self.provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
self.set_child(self.columnview)

View File

@ -1,4 +1,5 @@
#!/bin/zsh -e
source common.zsh
if [ "$#" -ne 3 ]; then
echo "Usage: $0 {rxe,siw} {client} {server}"
@ -10,8 +11,7 @@ CLIENT=$2
SERVER=$3
IFS=$'\n'
BIN=$HOME/bin
tags=($(python $BIN/colors/vm.py $CLIENT $SERVER))
tags=($(FORCE_COLOR=1 python $COLORS/vm.py $CLIENT $SERVER))
$BIN/rdma.zsh $RDMA $CLIENT $SERVER

43
run/cthon.zsh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/zsh
zparseopts -D -K -server:=SERVER -export:=EXPORT -mountpoint:=MOUNTPOINT \
-user:=USER -proto:=PROTO -version+:=VERSION -mntopt+:=MOUNTOPTS \
b=TEST g=TEST s=TEST l=TEST
exclude=(--mntopt)
MOUNTOPTS=(${(ou)MOUNTOPTS:|exclude})
function runtest
{
./server ${TEST[-1]} -o $1 -m $2 -p $3 ${SERVER[-1]} > $4 2>&1
if [ $? -ne 0 ]; then
echo ""
echo "The '${TEST[-1]}' test using '$1' options to ${SERVER[-1]}: Failed!!"
mv $4 $4-`date +"%H:%M:%S"`.error
fi
if [ $(grep -c $2 /proc/mounts) -gt 0 ]; then
sudo umount $2
fi
}
cd cthon04
for vers in $VERSION; do
[[ "$vers" == "--version" ]] && continue
dir=$(echo "nfsv${vers}${PROTO[-1]}" | sed 's/\.//' | sed 's/v40/v4/')
mnt=${MOUNTPOINT[-1]}/$dir
xprt=${EXPORT[-1]}/${USER[-1]}/$dir
opts="v$vers,proto=${PROTO[-1]}"
for o in $MOUNTOPTS; do
opts="$opts,$o"
done
echo "./server ${TEST[-1]} -o $opts -m $mnt -p $xprt ${SERVER[-1]}"
runtest $opts $mnt $xprt /tmp/nfsv${vers}${PROTO[-1]} &
done
echo -n "Waiting for '${TEST[-1]}' to finish ... "
wait
echo -n "Done: "
date +"%X"

11
run/nfstest-rplus.zsh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/zsh
zparseopts -D -K -server:=SERVER -export:=EXPORT \
-mountpoint:=MOUNTPOINT -user:=USER
NFSTEST_DIR=/home/anna/nfstest
export PYTHONPATH=$NFSTEST_DIR
$NFSTEST_DIR/test/nfstest_rplus --server ${SERVER[-1]} \
--export ${EXPORT[-1]}/${USER[-1]}/nfsv42tcp \
--mtpoint ${MOUNTPOINT[-1]}/test/nfsv42tcp

View File

@ -8,23 +8,31 @@ zparseopts -D -K -server:=SERVER -opts:=OPTS -user:=USER \
xdir=$(echo "nfsv${VERSION[-1]}${PROTO[-1]}" | sed 's/\.//' | sed 's/v40/v4/')
cd /home/${USER[-1]}/xfstests-dev
export TEST_DEV=${SERVER[-1]}:${EXPORT[-1]}/${USER[-1]}/$xdir
export TEST_DEV=$(echo ${SERVER[-1]}:${EXPORT[-1]}/${USER[-1]}/$xdir | sed 's|//|/|')
export TEST_DIR=${MOUNTPOINT[-1]}/$xdir
export SCRATCH_DEV=${SERVER[-1]}:${SCRATCH[-1]}/${USER[-1]}/$xdir
export SCRATCH_MNT=${SCRATCHMNT[-1]}/$xdir
if [ "${SCRATCH[-1]}" != "NONE" ]; then
export SCRATCH_DEV=${SERVER[-1]}:${SCRATCH[-1]}/${USER[-1]}/$xdir
export SCRATCH_MNT=${SCRATCHMNT[-1]}/$xdir
fi
export NFS_MOUNT_OPTIONS="-o proto=${PROTO[-1]},v${VERSION[-1]},${OPTS[-1]}"
export RESULT_BASE=/home/${USER[-1]}/xfstests-dev/results/${PROTO[-1]}/${VERSION[-1]}
mkdir -p $TEST_DIR
mkdir -p $SCRATCH_MNT
if [ "${SCRATCH[-1]}" != "NONE" ]; then
mkdir -p $SCRATCH_MNT
fi
[ -e local.config ] && rm -f local.config
[ -e $RESULT_BASE/result.xml ] && rm -f $RESULT_BASE/result.xml
echo "TIME -- $(date)"
echo "TEST_DEV -- $TEST_DEV"
echo "TEST_DIR -- $TEST_DIR"
echo "SCRATCH_DEV -- $SCRATCH_DEV"
echo "SCRATCH_MNT -- $SCRATCH_MNT"
if [ "${SCRATCH[-1]}" != "NONE" ]; then
echo "SCRATCH_DEV -- $SCRATCH_DEV"
echo "SCRATCH_MNT -- $SCRATCH_MNT"
else
echo "SCRATCH_DEV -- NONE"
fi
echo "MOUNT_OPTIONS -- $NFS_MOUNT_OPTIONS"
if [ ! -z "$*" ]; then
@ -32,4 +40,3 @@ if [ ! -z "$*" ]; then
fi
./check -nfs -r -R xunit $*
#./check -nfs -R xunit $*

9
setup.zsh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/zsh
BIN=.local/bin
[[ "$(basename $0)" == "run.zsh" ]] && TARGET=$BIN/run || TARGET=$BIN/setup
TARGET=$TARGET/$1
shift
[[ -x $TARGET ]] && $TARGET $*

50
setup/read_plus-files.py Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/python -u
"""Create sparse files for testing with various patterns."""
import datetime
import pathlib
import os
import string
import sys
PAGE_SIZE = 4096
PAGE_HEADER = "<<<Start Of Page>>>\n"
PAGE_FOOTER = "\n<<<End Of Page>>>\n"
line = string.ascii_letters + string.digits + "\n"
data_len = PAGE_SIZE - len(PAGE_HEADER + PAGE_FOOTER)
(n_lines, n_chars) = divmod(data_len, len(line))
page_data = PAGE_HEADER + (line * n_lines) + line[:n_chars] + PAGE_FOOTER
PAGE_DATA = page_data.encode()
FILE_BASE = pathlib.Path(sys.argv[1])
FILE_SIZE = int(sys.argv[2])
FILE_SIZE_BYTES = FILE_SIZE * 1024 * 1024
FILE_N_PAGES = FILE_SIZE_BYTES // PAGE_SIZE
def allocate_testfile(name: str, n_pages: int, hole: bool) -> None:
"""Allocate a single test file."""
file = FILE_BASE / f"{FILE_SIZE}M-{name}"
if file.exists():
return
print(f"Allocating file: {file.stem} ...", end="")
start = datetime.datetime.now()
with open(file, 'wb') as f:
f.truncate(FILE_SIZE_BYTES)
for chunk in range(FILE_N_PAGES // n_pages):
if hole:
f.seek(PAGE_SIZE * n_pages, os.SEEK_CUR)
else:
f.write(PAGE_DATA * n_pages)
hole = not hole
os.fsync(f)
tdelta = datetime.datetime.now() - start
time = float(f"{tdelta.seconds}.{tdelta.microseconds}")
print(f" [Done: {round(time, 2):.2f}s]")
allocate_testfile("data", FILE_N_PAGES, False)
allocate_testfile("hole", FILE_N_PAGES, True)
for chunk in [int(c) for c in sys.argv[3].split(",")]:
allocate_testfile(f"mixed-{chunk}d", chunk, False)
allocate_testfile(f"mixed-{chunk}h", chunk, True)

22
setup/read_plus.zsh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/zsh
SERVER=$1
EXPORT=$2
MOUNTPOINT=$3/read_plus
USER=$4
SIZE=$5
CHUNKS=$6
if [ "$#" -ne 6 ]; then
echo "Usage: $0 {server} {export} {mountpoint} {user} {size} {chunks}"
exit 1
fi
mkdir -p $MOUNTPOINT
mount -o sec=sys $SERVER:$EXPORT $MOUNTPOINT
TRAPEXIT() {
sudo umount -f $MOUNTPOINT
}
mkdir -p -m 777 $MOUNTPOINT/$USER/read_plus
setup.zsh read_plus-files.py $MOUNTPOINT/$USER/read_plus $SIZE $CHUNKS
sync

View File

@ -1,4 +1,4 @@
#!/bin/zsh
#!/bin/zsh -e
SERVER=$1
EXPORT=$2
MOUNTPOINT=$3

View File

@ -16,5 +16,7 @@ groupadd fsgqa 2>/dev/null
useradd --badnames 123456-fsgqa 2>/dev/null
useradd fsgqa2 2>/dev/null
setup-testdirs.zsh $SERVER $EXPORT $MOUNTPOINT $USER
setup-testdirs.zsh $SERVER $SCRATCH $SCRATCHMNT $USER
setup.zsh testdirs.zsh $SERVER $EXPORT $MOUNTPOINT $USER
if [ "$SCRATCH" != "NONE" ]; then
setup.zsh testdirs.zsh $SERVER $SCRATCH $SCRATCHMNT $USER
fi

View File

@ -1,13 +0,0 @@
#!/bin/bash
FROM="--from=Anna.Schumaker@Netapp.com"
TO="--to=Trond.Myklebust@hammerspace.com"
#TO="--to=bfields@redhat.com --to=chuck.lever@oracle.com"
#TO="--to=fstests@vger.kernel.org"
#TO="--to=steved@redhat.com"
TO="$TO --to=linux-nfs@vger.kernel.org"
CC="--cc=Anna.Schumaker@Netapp.com"
git send-email $FROM $TO $CC $*

25
submit-patches.zsh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/zsh
zparseopts -D -K \
-nfs+=WHO -nfsd+=WHO -nfsutils+=WHO -xfstests+=WHO -fstests+=WHO \
-linus+=WHO
if [[ ${#WHO} -eq 0 ]]; then
echo "Who to submit to?"
exit 1
fi
TO=(--to=linux-nfs@vger.kernel.org)
for who in $WHO; do
case $who in
--nfs) TO+=(--to=trond.myklebust@hammerspace.com) ;;
--nfsd) TO+=(--to=chuck.lever@oracle.com) ;;
--nfsutils) TO+=(--to=steved@redhat.com) ;;
--linus) TO+=(--to=torvalds@linux-foundation.org) ;;
--xfstests | --fstests) TO+=(--to=fstests@vger.kernel.org) ;;
esac
done
TO+=(--cc=anna@kernel.org)
git send-email $TO $*

View File

@ -4,7 +4,7 @@
SERVER=cheesecake
# Music source
SOURCE=/net/cheesecake/srv/Media/Music/vorbis/
SOURCE=/net/cheesecake/media/Music/vorbis/
# Music directory / destination
MUSIC=/home/anna/Music

12
unlock-sqlite-db.zsh Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/zsh
if [[ $# != 1 ]]; then
echo "Usage: $0 [FILE]"
exit 1
fi
backup="$(mktemp)"
mv $1 $backup
cp $backup $1
rm $backup

10
vm.zsh
View File

@ -33,12 +33,8 @@ function vm_reboot() {
vm_boot $1
}
TRAPEXIT() {
if [[ ! -z "$(jobs -pr)" ]]; then
for job in ($(jobs -pr)); do
kill -9 $job
done
fi
TRAPINT() {
kill -9 0
}
for vm in "${@:2}"; do
@ -59,4 +55,4 @@ for vm in "${@:2}"; do
esac
done
wait $(jobs -pr)
wait

View File

@ -1,17 +1,16 @@
#!/bin/zsh -e
CLIENT=(client)
SERVER=(server)
EXPORT=(/srv/test)
SCRATCH=(/srv/scratch)
MOUNTPOINT=(/mnt/test)
SCRATCHMNT=(/mnt/scratch)
source common.zsh
VERSION=(3 4.0 4.1 4.2)
PROTO=(tcp)
GROUP=(-g quick)
zparseopts -D -K \
c:=CLIENT -client:=CLIENT \
g:=GROUP -group:=GROUP \
k:=SCRATCH -scratch:=SCRATCH \
-nconnect:=NCONNECT \
-no-scratch=NO_SCRATCH \
-no-server-access=NO_SERVER_ACCESS \
o+:=MNTOPTS -options+:=MNTOPTS \
p:=MOUNTPOINT -mountpoint:=MOUNTPOINT \
q:=SCRATCHMNT -scratchmnt:=SCRATCHMNT \
r:=RDMA -rdma:=RDMA \
@ -19,11 +18,8 @@ zparseopts -D -K \
x:=EXPORT -export:=EXPORT \
v+:=VERSION -version+:=VERSION
BIN=$HOME/bin
COLOR=$BIN/colors/xfstests.py
RUN_XFSTESTS="sudo run-xfstests.zsh"
OPTIONS="sec=sys"
USER=$(whoami)
COLOR=$COLORS/xfstests.py
OPTIONS="sec=sys$(echo $MNTOPTS | sed -E 's/ ?-o /,/g')"
RESULT_BASE=$HOME/.local/share/xfstests/
DATE=$(date +%Y-%m-%d-%H:%M:%S%z)
TODAY=$(date +%Y/%m/%d)
@ -39,52 +35,56 @@ fi
#
# Prepare to test
#
$BIN/vm.zsh boot ${CLIENT[-1]} ${SERVER[-1]}
$BIN/install-scripts.zsh ${CLIENT[-1]}
if [ ${#RDMA} -gt 0 ]; then
PROTO+=(rdma)
$BIN/rping.zsh ${RDMA[-1]} ${CLIENT[-1]} ${SERVER[-1]}
fi
if [ ${#NCONNECT} -gt 0 ]; then
OPTIONS="$OPTIONS,nconnect=${NCONNECT[-1]}"
fi
function setup_client_func()
{
client_setup xfstests.zsh ${SERVER[-1]} ${EXPORT[-1]} \
${MOUNTPOINT[-1]} ${SCRATCH[-1]} \
${SCRATCHMNT[-1]} $USER
}
ssh ${CLIENT[-1]} "sudo setup-xfstests.zsh ${SERVER[-1]} ${EXPORT[-1]} ${MOUNTPOINT[-1]} \
${SCRATCH[-1]} ${SCRATCHMNT[-1]} $USER"
echo
prepare_to_test
if [ ${#NO_SCRATCH} -gt 0 ]; then
SCRATCH+=("NONE")
fi
testargs=()
for arg in $*; do
testargs+=($(printf '%q' "$arg"))
GROUP=()
done
run_xfs_tests() {
ssh ${CLIENT[-1]} "$RUN_XFSTESTS --server ${SERVER[-1]} \
--export ${EXPORT[-1]} \
--mountpoint ${MOUNTPOINT[-1]} \
--scratch ${SCRATCH[-1]} \
--scratchmnt ${SCRATCHMNT[-1]} \
--proto $1 \
--version $2 \
--opts $OPTIONS \
--user $USER $testargs" | python $COLOR $1 $2
scp -q ${CLIENT[-1]}:$REMOTE_RESULTS/$1/$2/result.xml $TMP_RESULTS/$1-$2.xml
for proto in $PROTO; do
client_run xfstests.zsh --server ${SERVER[-1]} \
--export ${EXPORT[-1]} \
--mountpoint ${MOUNTPOINT[-1]} \
--scratch ${SCRATCH[-1]} \
--scratchmnt ${SCRATCHMNT[-1]} \
--proto $proto --version $1 \
--opts $OPTIONS \
--user $USER $GROUP $testargs | python $COLOR $proto $1
if [[ "$proto" == "rdma" ]]; then
xunit="$TMP_RESULTS/${RDMA[-1]}-$1.xml"
else
xunit="$TMP_RESULTS/$proto-$1.xml"
fi
scp -q ${CLIENT[-1]}:$REMOTE_RESULTS/$proto/$1/result.xml $xunit
xfstestsdb xunit read $RUNID $xunit | python $COLOR $proto $1
done
}
#
# Run tests
#
mkdir -p $TMP_RESULTS
for proto in $PROTO; do
for vers in $VERSION; do
case $vers in
"-v" | "--version") continue ;;
esac
run_xfs_tests $proto $vers &
done
RUNID=$(xfstestsdb new ${SERVER[-1]}:${EXPORT[-1]} | awk -F" | #" '{print $3}')
for vers in $VERSION; do
run_xfs_tests $vers &
done
wait
mkdir -p $RESULTS
@ -92,5 +92,12 @@ tar -cJf $RESULTS/$NOW.tar.xz -C $(dirname $TMP_RESULTS) $NOW/
if [ ! -z "$TAG" ]; then
mkdir -p $TAGRES
ln $RESULTS/$NOW.tar.xz $TAGRES/$DATE.tar.xz
xfstestsdb tag $RUNID $TAG
fi
optirun report-xfstests.py $RESULTS/$NOW.tar.xz & disown
echo
xfstestsdb xunit list --results --runid $RUNID
echo
xfstestsdb show --failure $RUNID
echo
report-xfstests.py $RESULTS/$NOW.tar.xz & disown