]> git.notmuchmail.org Git - notmuch/blob - test/T400-hooks.sh
CLI/new: drop the write lock to run the pre-new hook.
[notmuch] / test / T400-hooks.sh
1 #!/usr/bin/env bash
2 test_description='hooks'
3 . $(dirname "$0")/test-lib.sh || exit 1
4
5 test_require_external_prereq xapian-delve
6
7 create_echo_hook () {
8     local TOKEN="${RANDOM}"
9     mkdir -p ${HOOK_DIR}
10     cat <<EOF >"${HOOK_DIR}/${1}"
11 #!/bin/sh
12 echo "${TOKEN}" > ${3}
13 EOF
14     chmod +x "${HOOK_DIR}/${1}"
15     echo "${TOKEN}" > ${2}
16 }
17
18 create_write_hook () {
19     local TOKEN="${RANDOM}"
20     mkdir -p ${HOOK_DIR}
21     cat <<EOF >"${HOOK_DIR}/${1}"
22 #!/bin/sh
23 if xapian-delve ${MAIL_DIR}/.notmuch/xapian | grep -q "writing = false"; then
24    echo "${TOKEN}" > ${3}
25 fi
26 EOF
27     chmod +x "${HOOK_DIR}/${1}"
28     echo "${TOKEN}" > ${2}
29 }
30
31 create_failing_hook () {
32     local HOOK_DIR=${2}
33     mkdir -p ${HOOK_DIR}
34     cat <<EOF >"${HOOK_DIR}/${1}"
35 #!/bin/sh
36 exit 13
37 EOF
38     chmod +x "${HOOK_DIR}/${1}"
39 }
40
41 # add a message to generate mail dir and database
42 add_message
43 # create maildir structure for notmuch-insert
44 mkdir -p "$MAIL_DIR"/{cur,new,tmp}
45
46 for config in traditional profile explicit XDG; do
47     unset NOTMUCH_PROFILE
48     notmuch config set database.hook_dir
49     case $config in
50         traditional)
51             HOOK_DIR=${MAIL_DIR}/.notmuch/hooks
52             ;;
53         profile)
54             dir=${HOME}/.config/notmuch/other
55             mkdir -p ${dir}
56             HOOK_DIR=${dir}/hooks
57             cp ${NOTMUCH_CONFIG} ${dir}/config
58             export NOTMUCH_PROFILE=other
59             ;;
60         explicit)
61             HOOK_DIR=${HOME}/.notmuch-hooks
62             mkdir -p $HOOK_DIR
63             notmuch config set database.hook_dir $HOOK_DIR
64             ;;
65         XDG)
66             HOOK_DIR=${HOME}/.config/notmuch/default/hooks
67             ;;
68     esac
69
70     test_begin_subtest "pre-new is run [${config}]"
71     rm -rf ${HOOK_DIR}
72     generate_message
73     create_echo_hook "pre-new" expected output $HOOK_DIR
74     notmuch new > /dev/null
75     test_expect_equal_file expected output
76
77     test_begin_subtest "post-new is run [${config}]"
78     rm -rf ${HOOK_DIR}
79     generate_message
80     create_echo_hook "post-new" expected output $HOOK_DIR
81     notmuch new > /dev/null
82     test_expect_equal_file expected output
83
84     test_begin_subtest "post-insert hook is run [${config}]"
85     rm -rf ${HOOK_DIR}
86     generate_message
87     create_echo_hook "post-insert" expected output $HOOK_DIR
88     notmuch insert < "$gen_msg_filename"
89     test_expect_equal_file expected output
90
91     test_begin_subtest "pre-new is run before post-new [${config}]"
92     rm -rf ${HOOK_DIR}
93     generate_message
94     create_echo_hook "pre-new" pre-new.expected pre-new.output $HOOK_DIR
95     create_echo_hook "post-new" post-new.expected post-new.output $HOOK_DIR
96     notmuch new > /dev/null
97     test_expect_equal_file post-new.expected post-new.output
98
99     test_begin_subtest "pre-new non-zero exit status (hook status) [${config}]"
100     rm -rf ${HOOK_DIR}
101     generate_message
102     create_failing_hook "pre-new" $HOOK_DIR
103     output=`notmuch new 2>&1`
104     test_expect_equal "$output" "Error: pre-new hook failed with status 13"
105
106     # depends on the previous subtest leaving broken hook behind
107     test_begin_subtest "pre-new non-zero exit status (notmuch status) [${config}]"
108     test_expect_code 1 "notmuch new"
109
110     # depends on the previous subtests leaving 1 new message behind
111     test_begin_subtest "pre-new non-zero exit status aborts new [${config}]"
112     rm -rf ${HOOK_DIR}
113     output=$(NOTMUCH_NEW)
114     test_expect_equal "$output" "Added 1 new message to the database."
115
116     test_begin_subtest "post-new non-zero exit status (hook status) [${config}]"
117     rm -rf ${HOOK_DIR}
118     generate_message
119     create_failing_hook "post-new" $HOOK_DIR
120     NOTMUCH_NEW 2>output.stderr >output
121     cat output.stderr >> output
122     echo "Added 1 new message to the database." > expected
123     echo "Error: post-new hook failed with status 13" >> expected
124     test_expect_equal_file expected output
125
126     # depends on the previous subtest leaving broken hook behind
127     test_begin_subtest "post-new non-zero exit status (notmuch status) [${config}]"
128     test_expect_code 1 "notmuch new"
129
130     test_begin_subtest "post-insert hook does not affect insert status [${config}]"
131     rm -rf ${HOOK_DIR}
132     generate_message
133     create_failing_hook "post-insert" $HOOK_DIR
134     test_expect_success "notmuch insert < \"$gen_msg_filename\" > /dev/null"
135
136     test_begin_subtest "hook without executable permissions [${config}]"
137     rm -rf ${HOOK_DIR}
138     mkdir -p ${HOOK_DIR}
139     cat <<EOF >"${HOOK_DIR}/pre-new"
140     #!/bin/sh
141     echo foo
142 EOF
143     output=`notmuch new 2>&1`
144     test_expect_code 1 "notmuch new"
145
146     test_begin_subtest "hook execution failure [${config}]"
147     rm -rf ${HOOK_DIR}
148     mkdir -p ${HOOK_DIR}
149     cat <<EOF >"${HOOK_DIR}/pre-new"
150     no hashbang, execl fails
151 EOF
152     chmod +x "${HOOK_DIR}/pre-new"
153     test_expect_code 1 "notmuch new"
154
155     test_begin_subtest "post-new with write access [${config}]"
156     rm -rf ${HOOK_DIR}
157     create_write_hook "post-new" write.expected write.output $HOOK_DIR
158     NOTMUCH_NEW
159     test_expect_equal_file write.expected write.output
160
161     test_begin_subtest "pre-new with write access [${config}]"
162     rm -rf ${HOOK_DIR}
163     create_write_hook "pre-new" write.expected write.output $HOOK_DIR
164     NOTMUCH_NEW
165     test_expect_equal_file write.expected write.output
166
167     rm -rf ${HOOK_DIR}
168 done
169 test_done