diff options
Diffstat (limited to 'test/src/emacs-module-tests.el')
| -rw-r--r-- | test/src/emacs-module-tests.el | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index a4994b6223b..2aa85f0b247 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el | |||
| @@ -182,37 +182,66 @@ changes." | |||
| 182 | (should (equal (help-function-arglist #'mod-test-sum) | 182 | (should (equal (help-function-arglist #'mod-test-sum) |
| 183 | '(arg1 arg2)))) | 183 | '(arg1 arg2)))) |
| 184 | 184 | ||
| 185 | (ert-deftest module--test-assertions () | 185 | (defmacro module--with-temp-directory (name &rest body) |
| 186 | "Check that -module-assertions work." | 186 | "Bind NAME to the name of a temporary directory and evaluate BODY. |
| 187 | NAME must be a symbol. Delete the temporary directory after BODY | ||
| 188 | exits normally or non-locally. NAME will be bound to the | ||
| 189 | directory name (not the directory file name) of the temporary | ||
| 190 | directory." | ||
| 191 | (declare (indent 1)) | ||
| 192 | (cl-check-type name symbol) | ||
| 193 | `(let ((,name (file-name-as-directory | ||
| 194 | (make-temp-file "emacs-module-test" :directory)))) | ||
| 195 | (unwind-protect | ||
| 196 | (progn ,@body) | ||
| 197 | (delete-directory ,name :recursive)))) | ||
| 198 | |||
| 199 | (defmacro module--test-assertion (pattern &rest body) | ||
| 200 | "Test that PATTERN matches the assertion triggered by BODY. | ||
| 201 | Run Emacs as a subprocess, load the test module `mod-test-file', | ||
| 202 | and evaluate BODY. Verify that Emacs aborts and prints a module | ||
| 203 | assertion message that matches PATTERN. PATTERN is evaluated and | ||
| 204 | must evaluate to a regular expression string." | ||
| 205 | (declare (indent 1)) | ||
| 206 | ;; To contain any core dumps. | ||
| 207 | `(module--with-temp-directory tempdir | ||
| 208 | (with-temp-buffer | ||
| 209 | (let* ((default-directory tempdir) | ||
| 210 | (status (call-process mod-test-emacs nil t nil | ||
| 211 | "-batch" "-Q" "-module-assertions" "-eval" | ||
| 212 | ,(prin1-to-string | ||
| 213 | `(progn | ||
| 214 | (require 'mod-test ,mod-test-file) | ||
| 215 | ,@body))))) | ||
| 216 | (should (stringp status)) | ||
| 217 | ;; eg "Aborted" or "Abort trap: 6" | ||
| 218 | (should (string-prefix-p "Abort" status)) | ||
| 219 | (search-backward "Emacs module assertion: ") | ||
| 220 | (goto-char (match-end 0)) | ||
| 221 | (should (string-match-p ,pattern | ||
| 222 | (buffer-substring-no-properties | ||
| 223 | (point) (point-max)))))))) | ||
| 224 | |||
| 225 | (ert-deftest module--test-assertions--load-non-live-object () | ||
| 226 | "Check that -module-assertions verify that non-live objects | ||
| 227 | aren’t accessed." | ||
| 187 | (skip-unless (file-executable-p mod-test-emacs)) | 228 | (skip-unless (file-executable-p mod-test-emacs)) |
| 188 | ;; This doesn’t yet cause undefined behavior. | 229 | ;; This doesn’t yet cause undefined behavior. |
| 189 | (should (eq (mod-test-invalid-store) 123)) | 230 | (should (eq (mod-test-invalid-store) 123)) |
| 190 | ;; To contain any core dumps. | 231 | (module--test-assertion (rx "Emacs value not found in " |
| 191 | (let ((tempdir (make-temp-file "emacs-module-test" t))) | 232 | (+ digit) " values of " |
| 192 | (unwind-protect | 233 | (+ digit) " environments\n") |
| 193 | (with-temp-buffer | 234 | ;; Storing and reloading a local value causes undefined behavior, |
| 194 | (should (string-match-p | 235 | ;; which should be detected by the module assertions. |
| 195 | "Abort" ; eg "Aborted" or "Abort trap: 6" | 236 | (mod-test-invalid-store) |
| 196 | (let ((default-directory tempdir)) | 237 | (mod-test-invalid-load))) |
| 197 | (call-process mod-test-emacs nil t nil | 238 | |
| 198 | "-batch" "-Q" "-module-assertions" "-eval" | 239 | (ert-deftest module--test-assertions--call-emacs-from-gc () |
| 199 | (prin1-to-string | 240 | "Check that -module-assertions prevents calling Emacs functions |
| 200 | `(progn | 241 | during garbage collection." |
| 201 | (require 'mod-test ,mod-test-file) | 242 | (skip-unless (file-executable-p mod-test-emacs)) |
| 202 | ;; Storing and reloading a local | 243 | (module--test-assertion |
| 203 | ;; value causes undefined behavior, | 244 | (rx "Module function called during garbage collection\n") |
| 204 | ;; which should be detected by the | 245 | (mod-test-invalid-finalizer))) |
| 205 | ;; module assertions. | ||
| 206 | (mod-test-invalid-store) | ||
| 207 | (mod-test-invalid-load))))))) | ||
| 208 | (search-backward "Emacs module assertion:") | ||
| 209 | (should (string-match-p (rx bos "Emacs module assertion: " | ||
| 210 | "Emacs value not found in " | ||
| 211 | (+ digit) " values of " | ||
| 212 | (+ digit) " environments" eos) | ||
| 213 | (buffer-substring-no-properties | ||
| 214 | (line-beginning-position) | ||
| 215 | (line-end-position))))) | ||
| 216 | (delete-directory tempdir t)))) | ||
| 217 | 246 | ||
| 218 | ;;; emacs-module-tests.el ends here | 247 | ;;; emacs-module-tests.el ends here |