From 99577c5a0b582e6d0c3d9fd495dec9f27d0cb7a2 Mon Sep 17 00:00:00 2001 From: Matt Armstrong Date: Mon, 15 Feb 2021 12:59:08 -0800 Subject: [PATCH] Add some test coverage for src/filelock.c (Bug#46397). * test/src/filelock-tests.el: new file --- test/src/filelock-tests.el | 115 +++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test/src/filelock-tests.el diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el new file mode 100644 index 0000000000..8cdcec09e7 --- /dev/null +++ b/test/src/filelock-tests.el @@ -0,0 +1,115 @@ +;;; filelock-tests.el --- test file locking -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This file tests code in src/filelock.c and, to some extent, the +;; related code in src/fileio.c. + +;;; Code: + +(require 'ert) + +(defun filelock-tests--call-with-fixture (body) + (let ((test-dir (make-temp-file "filelock-tests-" t))) + (unwind-protect + (let ((file-name (concat (file-name-as-directory test-dir)))) + (with-temp-buffer + (setq-local buffer-file-name file-name) + (setq-local buffer-file-truename file-name) + (unwind-protect + (save-current-buffer + (let ((create-lockfiles t)) + (funcall body))) + (set-buffer-modified-p nil)))) + (delete-directory test-dir t nil)))) + +(defmacro filelock-tests--with-fixture (&rest body) + "Create a test fixture and evaluate BODY there like `progn'. +Create a temporary directory, then create a temporary buffer and +set it the variable `buffer-file-name' and `buffer-file-truename' +to it, let bind `create-lockfiles' to 't' and evaluate BODY." + (declare (indent 0)) + `(filelock-tests--call-with-fixture + (lambda () ,@body))) + +(defun filelock-tests--call-with-directory-modes (modes body) + (let* ((dir (file-name-directory (buffer-file-name))) + (original-modes (file-modes dir))) + (set-file-modes dir modes) + (unwind-protect + (funcall body) + (set-file-modes dir original-modes)))) + +(defmacro filelock-tests--with-directory-modes (modes &rest body) + "Evaluate BODY forms with directory MODES set. +The directory is taken from the buffer local variable +`buffer-file-name'. Afterwards, restore the modes to what they +were." + (declare (indent 1)) + `(filelock-tests--call-with-directory-modes + ,modes (lambda () ,@body))) + +(ert-deftest filelock-tests-lock-buffer-permission-denied () + "Check that locking a buffer in a directory with no write +permissions does not work." + (filelock-tests--with-fixture + (should (not (file-locked-p (buffer-file-name)))) + (filelock-tests--with-directory-modes #o500 + ;; FIXME: (lock-buffer) should raise some sort of + ;; error/warning here that we should verify in test. + ;; Currently lock_file() ignores errors from lock_if_free(). + ;; See the related FIXME in filelock.c. + (lock-buffer) + (should (not (file-locked-p (buffer-file-name))))))) + +(ert-deftest filelock-tests-file-locked-p-permission-denied () + "Check that `file-locked-p' fails if the directory is inaccesible." + (filelock-tests--with-fixture + (filelock-tests--with-directory-modes #o000 + (set-buffer-modified-p t) + ;; FIXME: Bug#46397: `file-locked-p' currently signals errors, + ;; but this prevents the user from killing the buffer. It also + ;; prevents Emacs shutdown. + (should + (equal + (butlast (should-error (file-locked-p (buffer-file-name))) + 2) + '(file-error "Testing file lock")))))) + +(ert-deftest filelock-tests-unlock-permission-denied () + "Check that `unlock-buffer' fails in directories that cannot be +modified." + (filelock-tests--with-fixture + (set-buffer-modified-p t) + (lock-buffer) + (should (file-locked-p (buffer-file-name))) + (filelock-tests--with-directory-modes #o500 + ;; FIXME: Bug#46397: `unlock-buffer' currently signals errors, + ;; but this prevents the user from killing the buffer. It also + ;; prevents Emacs shutdown. + (should + (equal + (butlast (should-error (unlock-buffer)) + 2) + '(file-error "Unlocking file")))))) + +(provide 'filelock-tests) + +;;; filelock-tests.el ends here -- 2.30.0