Skip to content

Commit

Permalink
[cli-tests] Add --set-exact-output to update the expected output
Browse files Browse the repository at this point in the history
`./run.py --set-exact-output` will update `stdout.expect` and
`stderr.expect` to match the expected output. This doesn't apply to
outputs which use `.glob` or `.ignore`.
  • Loading branch information
terrelln committed Dec 22, 2022
1 parent b6e8112 commit 7df6e25
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
10 changes: 10 additions & 0 deletions tests/cli-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ Examples:
./run.py --preserve --verbose basic/help.sh
```

### Updating exact output

If a test is failing because a `.stderr.exact` or `.stdout.exact` no longer matches, you can re-run the tests with `--set-exact-output` and the correct output will be written.

Example:
```
./run.py --set-exact-output
./run.py basic/help.sh --set-exact-output
```

## Writing a test

Test cases are arbitrary executables, and can be written in any language, but are generally shell scripts.
Expand Down
18 changes: 15 additions & 3 deletions tests/cli-tests/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,15 @@ def __init__(
preserve: bool,
scratch_dir: str,
test_dir: str,
set_exact_output: bool,
) -> None:
self.env = env
self.timeout = timeout
self.verbose = verbose
self.preserve = preserve
self.scratch_dir = scratch_dir
self.test_dir = test_dir
self.set_exact_output = set_exact_output


class TestCase:
Expand Down Expand Up @@ -335,7 +337,7 @@ def _join_test(self) -> None:
self._test_stdin.close()
self._test_stdin = None

def _check_output_exact(self, out_name: str, expected: bytes) -> None:
def _check_output_exact(self, out_name: str, expected: bytes, exact_name: str) -> None:
"""
Check the output named :out_name: for an exact match against the :expected: content.
Saves the success and message.
Expand All @@ -349,6 +351,10 @@ def _check_output_exact(self, out_name: str, expected: bytes) -> None:
self._success[check_name] = False
self._message[check_name] = f"{out_name} does not match!\n> diff expected actual\n{diff(expected, actual)}"

if self._opts.set_exact_output:
with open(exact_name, "wb") as f:
f.write(actual)

def _check_output_glob(self, out_name: str, expected: bytes) -> None:
"""
Check the output named :out_name: for a glob match against the :expected: glob.
Expand Down Expand Up @@ -386,15 +392,15 @@ def _check_output(self, out_name: str) -> None:
ignore_name = f"{self._test_file}.{out_name}.ignore"

if os.path.exists(exact_name):
return self._check_output_exact(out_name, read_file(exact_name))
return self._check_output_exact(out_name, read_file(exact_name), exact_name)
elif os.path.exists(glob_name):
return self._check_output_glob(out_name, read_file(glob_name))
elif os.path.exists(ignore_name):
check_name = f"check_{out_name}"
self._success[check_name] = True
self._message[check_name] = f"{out_name} ignored!"
else:
return self._check_output_exact(out_name, bytes())
return self._check_output_exact(out_name, bytes(), exact_name)

def _check_stderr(self) -> None:
"""Checks the stderr output against the expectation."""
Expand Down Expand Up @@ -678,6 +684,11 @@ def setup_zstd_symlink_dir(zstd_symlink_dir: str, zstd: str) -> None:
"Scratch directory located in TEST_DIR/scratch/."
)
)
parser.add_argument(
"--set-exact-output",
action="store_true",
help="Set stderr.exact and stdout.exact for all failing tests, unless .ignore or .glob already exists"
)
parser.add_argument(
"tests",
nargs="*",
Expand Down Expand Up @@ -714,6 +725,7 @@ def setup_zstd_symlink_dir(zstd_symlink_dir: str, zstd: str) -> None:
preserve=args.preserve,
test_dir=args.test_dir,
scratch_dir=scratch_dir,
set_exact_output=args.set_exact_output,
)

if len(args.tests) == 0:
Expand Down

0 comments on commit 7df6e25

Please sign in to comment.