#!/bin/sh # Errors: can't live with 'em can't live without 'em # - Priorities: # 0. db integrity # 1. report comprehensible error to user # 2. comprehensible log (good enough for a quality bug report) # 3. clean close of IMAP connection # - If db open: # 1. clean close if at all possible # 2. if not, report failure along with the original failure # - If nmh connection open: # 1. write blind error # 2. if that write failed log but ignore # 3. Else close the socket, log+ignore error here too # - If IMAP connection is open: # 1. write a blind LOGOUT # 2. if that write failed log but ignore # 3. Else close the socket, log+ignore error here too # - If error is detected at layer that has both nmh and IMAP connection # available, handle nmh first; we fight for the users # - In any case, finally error!(it) # Types: # Environmental # - read/write error # - open error (except ENOENT) # Action: report, log, clean shutdown # Protocol # - either the bytes received were bytes expected or they weren't; # context for logging is useful, but we don't need fine-grained types # - this goes for nmh-folder-manager and IMAP protocols # Action: report, log, clean shutdown # Invalid request # A request is valid or not regardless of the state of the system. # - E.g. # - UID FETCH without mailbox open - protocol violation: EXAMINE first # - UID FETCH fred - `fred` is not a valid UID # - In theory, this maps to IMAP `BAD response code, but can we rely on it? # Action: Internal error, below # Illegal request # A request must be valid before its legality may be judged. # - E.g. # - FETCH 10 on mailbox with 9 messages - NO such message # - EXAMINE nosuchmailbox - NO mailbox by that name exists # - In theory, this maps to IMAP `NO response code, but can we rely on it? # - These SHOULD only be caused by user action, e.g. create folder that already exists. # Action: report, log, NO SHUTDOWN # Internal # Action: report, log, clean shutdown testname=${0#$srcdir/} if test -z "$MH_OBJ_DIR"; then srcdir=`dirname "$0"`/../.. MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR fi . "$MH_OBJ_DIR/test/common.sh" rm -rf "$MH_TEST_DIR/panda" imap_cleanup() { #### Save exit status to use as status for this program. status=$? set +e [ -n "$imapd_pid" ] && kill $imapd_pid # TODO uh oops don't need two profiles for this one for i in 1 2; do set_mh_profile profile$i "$MH_OBJ_DIR/target/debug/mhimap" imap shutdown done # TODO have cleanup allow additional cleanup registration? # Or just allow it to accept status as argument. (exit $status) cleanup } covdir="$MH_OBJ_DIR/covdata/${MH_COVERAGE_PROFILE:-default}/$testname" install -d "$covdir" mkdir "$MH_TEST_DIR/panda" mkdir "$MH_TEST_DIR/panda/test" expected="$MH_TEST_DIR/$$.expected" actual="$MH_TEST_DIR/$$.actual" start_fakeinetd env "HOME=$MH_TEST_DIR/panda" "$PANDA_IMAPD" imapd_pid=$fakeinetd_pid start() { rm -f "$MH_TEST_DIR/$profile/imap.d/socket" status=0 LLVM_PROFILE_FILE="$covdir/$profile-%m.profraw" "$MH_OBJ_DIR/target/debug/mhimap" imap start > "$actual" 2>&1 || status=$? } # setup profile 2 and 1, leaving 1 as active profile for i in 2 1; do setup_test_without_data profile$i trap imap_cleanup 0 cat >> "$MH" <> "$MH" echo "imap-log-$MH_TEST_IMAP_LOG_LEVEL-to: $MH_TEST_DIR/$profile/imap.d/log.$MH_TEST_IMAP_LOG_LEVEL" >> "$MH" fi start done ################################################################################ start_test 'profile1: folder +imap/fold -create' check_exit '-eq 0' folder +imap/fold -create ################################################################################ start_test 'profile2: folder +imap/fold -create' set_mh_profile profile2 # TODO Oops folder -create when folder is already known LOCALLY to exist tries to create over IMAP! cat > "$expected" < "$actual" 2>&1 || exitcode=$? check "$actual" "$expected" if [ $exitcode -ne 1 ]; then fail "folder exited $exitcode rather than 1" fi ################################################################################ start_test 'profile2: inc +imap leaves imap/fold SELECTed' inc +imap ################################################################################ start_test 'profile1: rmf +imap/fold fails because profile1 has it SELECTED' set_mh_profile profile1 rmf +imap/fold -nointeractive || status=$? if ! grep -q 'NO Mailbox test/fold is in use by another process' "$MH_TEST_DIR/$profile/imap.d/stderr"; then cat "$MH_TEST_DIR/$profile/imap.d/stderr" >&2 fail 'mailbox deletion not disallowed' fi finish_test exit ${failed:-0}