1# 2# Copyright (c) 2010-2020 Notmuch Developers 3# 4# This program is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 2 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see https://www.gnu.org/licenses/ . 16 17test_require_emacs () { 18 local ret=0 19 test_require_external_prereq "$TEST_EMACS" || ret=1 20 test_require_external_prereq "$TEST_EMACSCLIENT" || ret=1 21 test_require_external_prereq dtach || ret=1 22 return $ret 23} 24 25# Deliver a message with emacs and add it to the database 26# 27# Uses emacs to generate and deliver a message to the mail store. 28# Accepts arbitrary extra emacs/elisp functions to modify the message 29# before sending, which is useful to doing things like attaching files 30# to the message and encrypting/signing. 31emacs_deliver_message () { 32 local subject body smtp_dummy_pid smtp_dummy_port 33 subject="$1" 34 body="$2" 35 shift 2 36 # before we can send a message, we have to prepare the FCC maildir 37 mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp} 38 # eval'ing smtp-dummy --background will set smtp_dummy_pid and -_port 39 smtp_dummy_pid= smtp_dummy_port= 40 eval `$TEST_DIRECTORY/smtp-dummy --background sent_message` 41 test -n "$smtp_dummy_pid" || return 1 42 test -n "$smtp_dummy_port" || return 1 43 44 test_emacs \ 45 "(let ((message-send-mail-function 'message-smtpmail-send-it) 46 (mail-host-address \"example.com\") 47 (smtpmail-smtp-server \"localhost\") 48 (smtpmail-smtp-service \"${smtp_dummy_port}\")) 49 (notmuch-mua-mail) 50 (message-goto-to) 51 (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\") 52 (message-goto-subject) 53 (insert \"${subject}\") 54 (message-goto-body) 55 (insert \"${body}\") 56 $* 57 (notmuch-mua-send-and-exit))" 58 59 # In case message was sent properly, client waits for confirmation 60 # before exiting and resuming control here; therefore making sure 61 # that server exits by sending (KILL) signal to it is safe. 62 kill -9 $smtp_dummy_pid 63 notmuch new >/dev/null 64} 65 66# Pretend to deliver a message with emacs. Really save it to a file 67# and add it to the database 68# 69# Uses emacs to generate and deliver a message to the mail store. 70# Accepts arbitrary extra emacs/elisp functions to modify the message 71# before sending, which is useful to doing things like attaching files 72# to the message and encrypting/signing. 73# 74# If any GNU-style long-arguments (like --quiet or --decrypt=true) are 75# at the head of the argument list, they are sent directly to "notmuch 76# new" after message delivery 77emacs_fcc_message () { 78 local nmn_args subject body 79 nmn_args='' 80 while [[ "$1" =~ ^-- ]]; do 81 nmn_args="$nmn_args $1" 82 shift 83 done 84 subject="$1" 85 body="$2" 86 shift 2 87 # before we can send a message, we have to prepare the FCC maildir 88 mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp} 89 90 test_emacs \ 91 "(let ((message-send-mail-function (lambda () t)) 92 (mail-host-address \"example.com\")) 93 (notmuch-mua-mail) 94 (message-goto-to) 95 (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\") 96 (message-goto-subject) 97 (insert \"${subject}\") 98 (message-goto-body) 99 (insert \"${body}\") 100 $* 101 (let ((mml-secure-smime-sign-with-sender t) 102 (mml-secure-openpgp-sign-with-sender t)) 103 (notmuch-mua-send-and-exit)))" || return 1 104 notmuch new $nmn_args >/dev/null 105} 106 107test_emacs_expect_t () { 108 local result 109 test "$#" = 1 || 110 error "bug in the test script: not 1 parameter to test_emacs_expect_t" 111 if [ -z "$inside_subtest" ]; then 112 error "bug in the test script: test_emacs_expect_t without test_begin_subtest" 113 fi 114 115 # Run the test. 116 if ! test_skip "$test_subtest_name" 117 then 118 test_emacs "(notmuch-test-run $1)" >/dev/null 119 120 # Restore state after the test. 121 exec 1>&6 2>&7 # Restore stdout and stderr 122 inside_subtest= 123 124 # test_emacs may update missing external prerequisites 125 test_check_missing_external_prereqs_ "$test_subtest_name" && return 126 127 # Report success/failure. 128 result=$(cat OUTPUT) 129 if [ "$result" = t ] 130 then 131 test_ok_ 132 else 133 test_failure_ "${result}" 134 fi 135 else 136 # Restore state after the (non) test. 137 exec 1>&6 2>&7 # Restore stdout and stderr 138 inside_subtest= 139 fi 140} 141 142emacs_generate_script () { 143 # Construct a little test script here for the benefit of the user, 144 # (who can easily run "run_emacs" to get the same emacs environment 145 # for investigating any failures). 146 cat <<EOF >"$TMP_DIRECTORY/run_emacs" 147#!/bin/sh 148export PATH=$PATH 149export NOTMUCH_CONFIG=$NOTMUCH_CONFIG 150 151# Here's what we are using here: 152# 153# --quick Use minimal customization. This implies --no-init-file, 154# --no-site-file and (emacs 24) --no-site-lisp 155# 156# --directory Ensure that the local elisp sources are found 157# 158# --load Force loading of notmuch.el and test-lib.el 159 160exec ${TEST_EMACS} --quick \ 161 --directory "$NOTMUCH_BUILDDIR/emacs" --load notmuch.el \ 162 --directory "$NOTMUCH_SRCDIR/test" --load test-lib.el \ 163 "\$@" 164EOF 165 chmod a+x "$TMP_DIRECTORY/run_emacs" 166} 167 168test_emacs () { 169 # test dependencies beforehand to avoid the waiting loop below 170 test_require_emacs || return 171 172 if [ -z "$EMACS_SERVER" ]; then 173 emacs_tests="$NOTMUCH_SRCDIR/test/${this_test_bare}.el" 174 if [ -f "$emacs_tests" ]; then 175 load_emacs_tests="--eval '(load \"$emacs_tests\")'" 176 else 177 load_emacs_tests= 178 fi 179 server_name="notmuch-test-suite-$$" 180 # start a detached session with an emacs server 181 # user's TERM (or 'vt100' in case user's TERM is known dumb 182 # or unknown) is given to dtach which assumes a minimally 183 # VT100-compatible terminal -- and emacs inherits that 184 TERM=$SMART_TERM dtach -n "$TEST_TMPDIR/emacs-dtach-socket.$$" \ 185 sh -c "stty rows 24 cols 80; exec '$TMP_DIRECTORY/run_emacs' \ 186 --no-window-system \ 187 $load_emacs_tests \ 188 --eval '(setq server-name \"$server_name\")' \ 189 --eval '(server-start)' \ 190 --eval '(orphan-watchdog $$)'" || return 191 EMACS_SERVER="$server_name" 192 # wait until the emacs server is up 193 until test_emacs '()' >/dev/null 2>/dev/null; do 194 sleep 1 195 done 196 fi 197 198 # Clear test-output output file. Most Emacs tests end with a 199 # call to (test-output). If the test code fails with an 200 # exception before this call, the output file won't get 201 # updated. Since we don't want to compare against an output 202 # file from another test, so start out with an empty file. 203 rm -f OUTPUT 204 touch OUTPUT 205 206 ${TEST_EMACSCLIENT} --socket-name="$EMACS_SERVER" --eval "(notmuch-test-progn $*)" 207} 208 209emacs_generate_script 210