diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-03 19:59:42 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-03 19:59:42 -0500 |
| commit | deff663d480afb23e47f0d0fd834d2c0959d0b00 (patch) | |
| tree | 0d6ca6f4c429e3623ae6b69d19ff1716852856f2 /tests/test-testutil-general.el | |
| parent | 3e9499f62c4fb621ec234a0cf5cee51eb2cf32c0 (diff) | |
| download | dotemacs-deff663d480afb23e47f0d0fd834d2c0959d0b00.tar.gz dotemacs-deff663d480afb23e47f0d0fd834d2c0959d0b00.zip | |
fix: make test scratch paths sandbox-friendly
`tests/testutil-general.el` hard-coded `~/.temp-emacs-tests/` as the test root. That worked locally but blew up under sandboxed `make` runs and CI environments that can't write outside the repo or `/tmp`. A clean sandbox `make test` run reported 32 failing test files purely from the home-directory write attempt, even though the same suite passed when run with normal write permission.
I rewrote `cj/test-base-dir` to honor `CJ_EMACS_TEST_DIR` if set, otherwise create a unique directory under `temporary-file-directory` via `make-temp-file`. So sandbox and CI paths just work, and a stable local debug root is still one env-var away.
I also tightened the path-containment checks. The old `(string-prefix-p base fullpath)` was a textual hack. Relative paths and weird trailing slashes could fool it. I extracted `cj/test--assert-inside-base` using `file-in-directory-p`, which is the proper API. While I was there, I added `cj/test--safe-base-dir-p` so `cj/delete-test-base-dir` refuses to recursively wipe `/`, `~/`, `temporary-file-directory`, `user-emacs-directory`, `default-directory`, or any path of length under six characters. That guards against an env-var typo or a misaligned `let` binding accidentally deleting something important.
I updated the Makefile's `clean-tests` target to nuke the new `$TMPDIR/cj-emacs-tests-*` pattern plus an explicit `CJ_EMACS_TEST_DIR` (if set) and the legacy `~/.temp-emacs-tests` directory.
I added `tests/test-testutil-general.el` with five tests: default base lives under `temporary-file-directory`, env override resolves correctly, parent-escape paths are rejected, broad roots are refused for deletion, and a specific selected root is cleaned cleanly.
Diffstat (limited to 'tests/test-testutil-general.el')
| -rw-r--r-- | tests/test-testutil-general.el | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/test-testutil-general.el b/tests/test-testutil-general.el new file mode 100644 index 00000000..55cafe00 --- /dev/null +++ b/tests/test-testutil-general.el @@ -0,0 +1,48 @@ +;;; test-testutil-general.el --- Tests for shared test utilities -*- lexical-binding: t; -*- + +;;; Commentary: +;; Verifies shared test scratch paths are sandbox-friendly and guarded. + +;;; Code: + +(require 'ert) +(add-to-list 'load-path (expand-file-name "tests" user-emacs-directory)) +(require 'testutil-general) + +(ert-deftest test-testutil-general-default-base-dir-is-under-temp () + "The default test root should not require home-directory write access." + (skip-unless (not (getenv "CJ_EMACS_TEST_DIR"))) + (should (file-in-directory-p cj/test-base-dir temporary-file-directory))) + +(ert-deftest test-testutil-general-env-override-shape () + "A stable local test root can still be supplied via environment variable." + (let ((process-environment + (cons "CJ_EMACS_TEST_DIR=/tmp/cj-custom-test-root" process-environment))) + (should (equal + (file-name-as-directory + (expand-file-name + (or (getenv "CJ_EMACS_TEST_DIR") + (expand-file-name "cj-emacs-tests/" temporary-file-directory)))) + "/tmp/cj-custom-test-root/")))) + +(ert-deftest test-testutil-general-create-file-rejects-parent-escape () + "Relative paths must not escape the selected test root." + (let ((cj/test-base-dir (make-temp-file "testutil-base-" t))) + (should-error + (cj/create-directory-or-file-ensuring-parents "../escape.txt" "bad")))) + +(ert-deftest test-testutil-general-delete-refuses-temp-root () + "Cleanup must refuse broad roots such as `temporary-file-directory'." + (let ((cj/test-base-dir temporary-file-directory)) + (should-error (cj/delete-test-base-dir)))) + +(ert-deftest test-testutil-general-delete-removes-selected-root () + "Cleanup should remove a specific selected test root." + (let ((cj/test-base-dir (make-temp-file "testutil-delete-" t))) + (cj/create-directory-or-file-ensuring-parents "nested/file.txt" "ok") + (should (file-directory-p cj/test-base-dir)) + (cj/delete-test-base-dir) + (should-not (file-exists-p cj/test-base-dir)))) + +(provide 'test-testutil-general) +;;; test-testutil-general.el ends here |
