aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorPo Lu2025-03-02 16:02:46 +0800
committerPo Lu2025-03-02 16:05:04 +0800
commita8988ce80004af57f3741dc059c5a97cb83dca64 (patch)
treed32e2b21cb04bd61b18ba46c67e3d42dad17359e /test
parent7fcb01e76ba9b2c74019f3863975cfe32c8b0da0 (diff)
downloademacs-a8988ce80004af57f3741dc059c5a97cb83dca64.tar.gz
emacs-a8988ce80004af57f3741dc059c5a97cb83dca64.zip
Run Android tests in the initial frame
* test/infra/android/early-init.el: New file. * test/infra/android/test-controller.el (ats-connect): Upload `early-init.el' to the staging directory and configure that directory as the Emacs instance's initialization directory. (ats-run-test): Always append to the test buffer. Execute tests within terminal-frame. (ats-run-all-tests): Gracefully respond to errors. (ats-cmd-error): New function. (ats-execute-tests-batch): Accept a number of command line arguments.
Diffstat (limited to 'test')
-rw-r--r--test/infra/android/early-init.el33
-rw-r--r--test/infra/android/test-controller.el223
2 files changed, 204 insertions, 52 deletions
diff --git a/test/infra/android/early-init.el b/test/infra/android/early-init.el
new file mode 100644
index 00000000000..abf8eed2692
--- /dev/null
+++ b/test/infra/android/early-init.el
@@ -0,0 +1,33 @@
1;;; Suppress deletion of the initial frame by `frame-initialize'.
2
3;; Copyright (C) 2025 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20
21
22(message "Loading early-init.el...")
23
24(advice-add 'frame-initialize :around
25 (lambda (oldfun &rest args)
26 (let ((subr (symbol-function 'delete-frame))
27 (terminal-frame terminal-frame))
28 (unwind-protect
29 (progn
30 (message "Suppressed deletion of the initial frame.")
31 (fset 'delete-frame #'ignore)
32 (apply oldfun args))
33 (fset 'delete-frame subr)))))
diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el
index 38d486c3c02..4a8b592648b 100644
--- a/test/infra/android/test-controller.el
+++ b/test/infra/android/test-controller.el
@@ -1764,13 +1764,25 @@ this machine and an SSH daemon be executing on the host)."
1764 device emacs-username "org.gnu.emacs" "org.gnu.emacs" user)))))) 1764 device emacs-username "org.gnu.emacs" "org.gnu.emacs" user))))))
1765 ;; Upload the test driver. 1765 ;; Upload the test driver.
1766 (let* ((ats-adb-host host) 1766 (let* ((ats-adb-host host)
1767 (staging-directory (ats-get-staging-directory device
1768 "org.gnu.emacs"
1769 user))
1767 (ats-file (let ((file (and ats-file-directory 1770 (ats-file (let ((file (and ats-file-directory
1768 (concat (file-name-as-directory 1771 (concat (file-name-as-directory
1769 ats-file-directory) 1772 ats-file-directory)
1770 "test-driver.el")))) 1773 "test-driver.el"))))
1771 (or (and file (file-exists-p file) file) 1774 (or (and file (file-exists-p file) file)
1772 (read-file-name "ATS test driver file: ")))) 1775 (read-file-name "ATS test driver file: "))))
1776 (ats-early-init-file
1777 (let ((file (and ats-file-directory
1778 (concat (file-name-as-directory
1779 ats-file-directory)
1780 "early-init.el"))))
1781 (or (and file (file-exists-p file) file)
1782 (read-file-name "ATS early-init file: "))))
1773 (file (ats-upload device ats-file "org.gnu.emacs" user)) 1783 (file (ats-upload device ats-file "org.gnu.emacs" user))
1784 (_ (ats-upload device ats-early-init-file
1785 "org.gnu.emacs" user))
1774 ;; Start the server. 1786 ;; Start the server.
1775 (server-port (ats-start-server)) 1787 (server-port (ats-start-server))
1776 ;; Forward the server to the ADB host. 1788 ;; Forward the server to the ADB host.
@@ -1806,7 +1818,13 @@ this machine and an SSH daemon be executing on the host)."
1806 device user 1818 device user
1807 `((:component . "org.gnu.emacs/.EmacsActivity") 1819 `((:component . "org.gnu.emacs/.EmacsActivity")
1808 ("org.gnu.emacs.STARTUP_ARGUMENTS" 1820 ("org.gnu.emacs.STARTUP_ARGUMENTS"
1809 "-q" "--load" ,file "--eval" 1821 "--load" ,file
1822 ;; Set the Emacs home directory to the ATS staging
1823 ;; directory, where an early-init.el should be
1824 ;; uploaded that inhibits the deletion of the
1825 ;; initial frame.
1826 "--init-directory" ,staging-directory
1827 "--eval"
1810 ,(format "(ats-establish-connection \"localhost\" %d \"%s\")" 1828 ,(format "(ats-establish-connection \"localhost\" %d \"%s\")"
1811 remote-port uuid)))) 1829 remote-port uuid))))
1812 (setq process 1830 (setq process
@@ -1837,7 +1855,12 @@ this machine and an SSH daemon be executing on the host)."
1837 device user 1855 device user
1838 `((:component . "org.gnu.emacs/.EmacsActivity") 1856 `((:component . "org.gnu.emacs/.EmacsActivity")
1839 ("org.gnu.emacs.STARTUP_ARGUMENTS" 1857 ("org.gnu.emacs.STARTUP_ARGUMENTS"
1840 "-q" "--load" ,file "--eval" 1858 "--load" ,file
1859 ;; Set the Emacs home directory to the ATS staging
1860 ;; directory, where an early-init.el should be uploaded that
1861 ;; inhibits the deletion of the initial frame.
1862 "--init-directory" ,staging-directory
1863 "--eval"
1841 ,(format "(ats-initiate-connection %S)" commfile)))) 1864 ,(format "(ats-initiate-connection %S)" commfile))))
1842 (let* ((portno (with-timeout 1865 (let* ((portno (with-timeout
1843 (ats-await-connection-timeout 1866 (ats-await-connection-timeout
@@ -2422,6 +2445,7 @@ Display the output of the tests executed in a buffer."
2422 ;; Delete all tests, load the byte-compiled test file, and execute 2445 ;; Delete all tests, load the byte-compiled test file, and execute
2423 ;; those tests just defined subject to SELECTOR. 2446 ;; those tests just defined subject to SELECTOR.
2424 (with-current-buffer (get-buffer-create "*Test Output*") 2447 (with-current-buffer (get-buffer-create "*Test Output*")
2448 (goto-char (point-max))
2425 (insert (format "=== Executing %s on %s ===\n" test device)) 2449 (insert (format "=== Executing %s on %s ===\n" test device))
2426 (redisplay) 2450 (redisplay)
2427 (setq rc (ats-eval process 2451 (setq rc (ats-eval process
@@ -2429,23 +2453,23 @@ Display the output of the tests executed in a buffer."
2429 (require 'ert) 2453 (require 'ert)
2430 (ert-delete-all-tests) 2454 (ert-delete-all-tests)
2431 (load ,file-name) 2455 (load ,file-name)
2432 (with-temp-buffer 2456 (with-selected-frame terminal-frame
2433 (let* ((temp-buffer (current-buffer)) 2457 (with-temp-buffer
2434 (standard-output temp-buffer) 2458 (let* ((temp-buffer (current-buffer))
2435 ;; Disable remote tests for the 2459 (standard-output temp-buffer)
2436 ;; present... 2460 ;; Disable remote tests for the
2437 (ert-remote-temporary-file-directory 2461 ;; present...
2438 null-device) 2462 (ert-remote-temporary-file-directory
2439 (overriding-text-conversion-style nil) 2463 null-device)
2440 (set-message-function 2464 (overriding-text-conversion-style nil)
2441 (lambda (message) 2465 (message-log-max t)
2442 (with-current-buffer temp-buffer 2466 ;; It isn't possible for
2443 (insert message "\n"))))) 2467 ;; Vset_message_function to take
2444 (let ((noninteractive t)) 2468 ;; effect when the initial frame
2445 ;; Prevent activation of the mark and 2469 ;; is selected.
2446 ;; other actions taken by the tests 2470 (messages-buffer-name
2447 ;; from affecting the test buffer. 2471 (buffer-name temp-buffer)))
2448 (with-temp-buffer 2472 (let ((noninteractive t))
2449 (ert-run-tests-batch ',selector))) 2473 (ert-run-tests-batch ',selector)))
2450 (insert "=== Test execution complete ===\n") 2474 (insert "=== Test execution complete ===\n")
2451 (buffer-substring-no-properties 2475 (buffer-substring-no-properties
@@ -2480,10 +2504,18 @@ subject to SELECTOR, as in `ert-run-tests'."
2480 (let ((tests (ats-list-tests process))) 2504 (let ((tests (ats-list-tests process)))
2481 (dolist-with-progress-reporter (test tests) 2505 (dolist-with-progress-reporter (test tests)
2482 "Running tests..." 2506 "Running tests..."
2483 (ats-run-test process test selector)))) 2507 (condition-case err
2508 (ats-run-test process test selector)
2509 (t (progn
2510 (message "Error in executing `%s': %S" test err)))))))
2484 2511
2485 2512
2486 2513
2514(defun ats-cmd-error (format &rest args)
2515 "Print an error message FORMAT, formatted with ARGS, and exit."
2516 (apply #'message format args)
2517 (kill-emacs 1))
2518
2487;; Batch mode text execution. 2519;; Batch mode text execution.
2488(defun ats-execute-tests-batch () 2520(defun ats-execute-tests-batch ()
2489 "Execute tests in batch mode, in the manner of `test/Makefile'. 2521 "Execute tests in batch mode, in the manner of `test/Makefile'.
@@ -2491,46 +2523,133 @@ Prompt for a device and execute tests on the same. Save log
2491files to a directory specified by the user. 2523files to a directory specified by the user.
2492Call this function from the command line, with, for example: 2524Call this function from the command line, with, for example:
2493 2525
2494 $ emacs --batch -l test-controller.el -f ats-execute-tests-batch" 2526 $ emacs --batch -l test-controller.el -f ats-execute-tests-batch
2527
2528The following command-line arguments are also accepted:
2529
2530 -h Print help text.
2531 --device, -s DEVICE Serial number of a device to which to connect.
2532 --user, -a UID ID of the user as which to execute tests.
2533 --stub-file Name of `stub.zip' wrapper required on Android <= 4.4.
2534 --test-dir Directory in which Emacs's tests are situated.
2535 --output-dir, -o DIR Name of a directory into which to save test logs.
2536 --no-upload Don't upload tests; only run those which already exist."
2495 (let* ((ats-adb-host (getenv "ATS_ADB_HOST")) 2537 (let* ((ats-adb-host (getenv "ATS_ADB_HOST"))
2496 (devices (ats-enumerate-devices 2538 (devices (ats-enumerate-devices
2497 (lambda (name state _) 2539 (lambda (name state _)
2498 (and (equal state "device") 2540 (and (equal state "device")
2499 (ignore-errors 2541 (ignore-errors
2500 (ats-get-package-aid name "org.gnu.emacs"))))))) 2542 (ats-get-package-aid name "org.gnu.emacs"))))))
2501 (message "These devices are presently available for test execution:") 2543 (cmd-device nil)
2502 (let ((nth 0)) 2544 (cmd-user nil)
2503 (dolist (device devices) 2545 (cmd-output-dir nil)
2504 (message "%2d. %-24s(API level %d, %s)" 2546 (cmd-no-upload nil))
2505 (setq nth (1+ nth)) (car device) 2547 ;; Read command-line arguments.
2506 (ats-get-sdk-version (car device)) 2548 (let (arg)
2507 (ats-getprop (car device) "ro.product.cpu.abi")))) 2549 (while (setq arg (pop argv))
2508 (let* ((number (string-to-number 2550 (cond ((equal arg "-f") (pop argv)) ;; Do nothing. Emacs does
2509 (read-string 2551 ;; not remove this from argv
2510 "Select a device by typing its number, and Return: "))) 2552 ;; for unknown reasons.
2511 (device (if (or (< number 1) (> number (length devices))) 2553 ((equal arg "-h")
2512 (user-error "Invalid selection: %s" number) 2554 (message "Execute this file from the command line, with,\
2513 (car (nth (1- number) devices)))) 2555 for example:
2556
2557 $ emacs --batch -l test-controller.el -f ats-execute-tests-batch
2558
2559The following command-line arguments are also accepted:
2560
2561 --h Print this help text.
2562 --device, -s DEVICE Serial number of a device to which to connect.
2563 --user, -a UID ID of the user as which to execute tests.
2564 --stub-file Name of `stub.zip' wrapper required on Android <= 4.4.
2565 --test-dir Directory in which Emacs's tests are situated.
2566 --output-dir, -o DIR Name of a directory into which to save test logs.
2567 --no-upload Don't upload tests; only run those which already exist.")
2568 (kill-emacs 0))
2569 ((or (equal arg "-s") (equal arg "--device"))
2570 (setq cmd-device
2571 (or (pop argv)
2572 (ats-cmd-error
2573 "Expected argument to `--device' option"))))
2574 ((or (equal arg "-a") (equal arg "--user"))
2575 (setq cmd-user
2576 (or (pop argv)
2577 (ats-cmd-error
2578 "Expected argument to `--user' option"))))
2579 ((or (equal arg "-o") (equal arg "--output-dir"))
2580 (setq cmd-output-dir
2581 (or (pop argv)
2582 (ats-cmd-error
2583 "Expected argument to `--output-dir' option"))))
2584 ((equal arg "--stub-file")
2585 (setq ats-working-stub-file
2586 (or (pop argv)
2587 (ats-cmd-error
2588 "Expected argument to `--stub-file' option."))))
2589 ((equal arg "--test-dir")
2590 (setq ats-emacs-test-directory
2591 (or (pop argv)
2592 (ats-cmd-error
2593 "Expected argument to `--test-dir' option."))))
2594 ((equal arg "--no-upload")
2595 (setq cmd-no-upload t))
2596 (t (ats-cmd-error "Unknown command line argument `%s'" arg)))))
2597 ;; Validate and apply command-line arguments or prompt the user for
2598 ;; parameters in their absence.
2599 (if cmd-device
2600 (unless (member cmd-device (mapcar #'car devices))
2601 (ats-cmd-error
2602 "Device `%s' does not exist or has no installation of Emacs"
2603 cmd-device))
2604 (message "These devices are presently available for test execution:")
2605 (let ((nth 0))
2606 (dolist (device devices)
2607 (message "%2d. %-24s(API level %d, %s)"
2608 (setq nth (1+ nth)) (car device)
2609 (ats-get-sdk-version (car device))
2610 (ats-getprop (car device) "ro.product.cpu.abi")))))
2611 (let* ((number (and (not cmd-device)
2612 (string-to-number
2613 (read-string
2614 "Select a device by typing its number, and Return: "))))
2615 (device (or cmd-device
2616 (if (or (< number 1) (> number (length devices)))
2617 (ats-cmd-error "Invalid selection: %s" number)
2618 (car (nth (1- number) devices)))))
2514 (users (ats-list-users device)) 2619 (users (ats-list-users device))
2515 (nth 0)) 2620 (nth 0)
2516 (dolist (user users) 2621 (user nil))
2517 (message "%2d. %s (id=%d)" (setq nth (1+ nth)) 2622 (if cmd-user
2518 (cadr user) (car user))) 2623 (progn
2519 (setq number (string-to-number 2624 (let ((valid-number (string-match-p "^[[:digit:]]+$" cmd-user))
2520 (read-string 2625 (uid (string-to-number cmd-user)))
2521 "As which user should tests be executed? "))) 2626 (unless valid-number
2522 (when (or (< number 1) (> number (length users))) 2627 (ats-cmd-error "Invalid value for `--user' argument: %s"
2523 (user-error "Invalid selection: %s" number)) 2628 cmd-user))
2524 (let* ((user (car (nth (1- number) users))) 2629 (unless (assq uid users)
2630 (ats-cmd-error "No such user exists: %d" uid))
2631 ;; Don't prompt the user afterwards.
2632 (setq user uid)))
2633 (dolist (user users)
2634 (message "%2d. %s (id=%d)" (setq nth (1+ nth))
2635 (cadr user) (car user)))
2636 (setq number (string-to-number
2637 (read-string
2638 "As which user should tests be executed? ")))
2639 (when (or (< number 1) (> number (length users)))
2640 (ats-cmd-error "Invalid selection: %s" number)))
2641 (let* ((user (or user (car (nth (1- number) users))))
2525 (connection (ats-connect device user))) 2642 (connection (ats-connect device user)))
2526 (ats-upload-all-tests 2643 (unless cmd-no-upload
2527 connection 2644 (ats-upload-all-tests
2528 (or ats-emacs-test-directory 2645 connection
2529 (read-directory-name "Test base directory: " 2646 (or ats-emacs-test-directory
2530 nil nil t))) 2647 (read-directory-name "Test base directory: "
2648 nil nil t))))
2531 (let ((output-directory 2649 (let ((output-directory
2532 (read-directory-name 2650 (or cmd-output-dir
2533 "Where to save test log files? "))) 2651 (read-directory-name
2652 "Where to save test log files? "))))
2534 (mkdir output-directory t) 2653 (mkdir output-directory t)
2535 (let ((tests (ats-list-tests connection))) 2654 (let ((tests (ats-list-tests connection)))
2536 (dolist (test tests) 2655 (dolist (test tests)