Fix the race condition with fakesmtp so it works without needing retries.
[mmh] / test / mhmail / test-mhmail
1 #!/bin/sh
2 ######################################################
3 #
4 # Test mhmail
5 #
6 ######################################################
7
8 set -e
9
10 if test -z "${MH_OBJ_DIR}"; then
11     srcdir=`dirname $0`/../..
12     MH_OBJ_DIR=`cd $srcdir && pwd`; export MH_OBJ_DIR
13 fi
14
15 . "${srcdir}/test/post/test-post-common.sh"
16
17 # Customize test_post () for use with mhmail.
18 # $1 is expected output file, provided by caller
19 # $2 is mhmail switches, except for -body
20 # $3 of -b signifies use -body switch, | signifies provide body on stdin
21 # $4 contains the message body.
22 test_mhmail ()
23 {
24     pid=`"${MH_OBJ_DIR}/test/fakesmtp" "$actual" $localport`
25
26     if [ $3 = '|' ]; then
27         printf '%s' "$4" | mhmail recipient@example.com $2 \
28                         -server 127.0.0.1 -port $localport
29     else
30         mhmail recipient@example.com $2 -body "$4" \
31              -server 127.0.0.1 -port $localport
32     fi
33
34     #
35     # It's hard to calculate the exact Date: header post is going to
36     # use, so we'll just use sed to remove the actual date so we can easily
37     # compare it against our "correct" output.  And same for
38     # Message-ID.
39     #
40
41     sed -e 's/^Date:.*/Date:/' \
42         -e 's/^Resent-Date:.*/Resent-Date:/' \
43         -e 's/^Message-ID:.*/Message-ID:/' "$actual" > "$actual".nodate
44     rm -f "$actual"
45
46     check "$actual".nodate "$1"
47 }
48
49 expected=$MH_TEST_DIR/test-mhmail$$.expected
50 expected_err=$MH_TEST_DIR/test-mhmail$$.expected_err
51 actual=$MH_TEST_DIR/test-mhmail$$.actual
52 actual_err=$MH_TEST_DIR/test-mhmail$$.actual_err
53
54
55 # check -help
56 # Verified behavior consistent with compiled sendmail.
57 cat >$expected <<EOF
58 Usage: mhmail [-t(o)] addrs ... [switches]
59   switches are:
60   -at(tach) file [-at(tach) file] ...
61   -b(ody) text
62   -c(c) addrs ...
63   -f(rom) addr
64   -hea(derfield) name:value [-hea(derfield) name:value] ...
65   -su(bject) text
66   -r(esent)
67   -pr(ofile)
68   -se(nd)
69   -nose(nd)
70   -v(ersion)
71   -hel(p)
72   and all post(8)/send(1) switches
73   mhmail with no arguments is equivalent to inc
74 EOF
75
76 mhmail -help >$actual 2>&1
77 check $expected $actual
78
79
80 # check -version
81 # Verified same behavior as compiled mhmail.
82 case `mhmail -v` in
83   mhmail\ --*) ;;
84   *          ) printf '%s: mhmail -v generated unexpected output\n' "$0" >&2
85                failed=`expr ${failed:-0} + 1`;;
86 esac
87
88 # check for missing argument to switches that require them
89 for switch in attach body cc from headerfield subject to; do
90   run_test "mhmail recipient -$switch" \
91            "mhmail: missing argument to -$switch"
92 done
93 for switch in attach body cc from headerfield subject to; do
94   run_test "mhmail recipient -$switch -nosend" \
95            "mhmail: missing argument to -$switch"
96 done
97 for switch in attach body cc from headerfield subject to; do
98   run_test "mhmail recipient -$switch -server 127.0.0.1" \
99            "mhmail: missing argument to -$switch"
100 done
101
102
103 # check with no switches
104 # That will just run inc, which we don't want to do anything,
105 # so tell inc to just display its version.
106 # Verified same behavior as compiled mhmail.
107 printf 'inc: -version\n' >> $MH
108 case `mhmail` in
109   inc\ --*) ;;
110   *           ) echo "$0: mhmail generated unexpected output" >&2
111                 failed=`expr ${failed:-0} + 1`;;
112 esac
113
114
115 # check -nosend
116 # Not supported by compiled mhmail.
117 mhmail -nosend recipient@example.com -from sender@localhost \
118   -server 127.0.0.1 -port $localport -body '' >"$actual" 2>"$actual_err"
119
120 tmpfil=`head -1 $actual | sed -e 's/://'`
121
122 cat > "$expected" <<EOF
123 To: recipient@example.com
124 From: sender@localhost
125
126
127 EOF
128
129 cat > "$expected_err" <<EOF
130 EOF
131
132 check "$expected" "$actual"
133 check "$expected_err" "$actual_err"
134 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
135
136
137 # check -send
138 # Not supported by compiled mhmail.
139 cat > "$expected" <<EOF
140 EHLO nosuchhost.example.com
141 MAIL FROM:<sender@localhost>
142 RCPT TO:<recipient@example.com>
143 DATA
144 To: recipient@example.com
145 From: sender@localhost
146 Date:
147
148 message
149 .
150 QUIT
151 EOF
152
153 test_mhmail "$expected" "-from sender@localhost -nosend -send" '|' message
154 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
155
156
157 # check -from
158 # Verified same behavior as compiled mhmail.
159 cat > "$expected" <<EOF
160 EHLO nosuchhost.example.com
161 MAIL FROM:<sender@localhost>
162 RCPT TO:<recipient@example.com>
163 DATA
164 To: recipient@example.com
165 From: sender@localhost
166 Date:
167
168 message
169 .
170 QUIT
171 EOF
172
173 test_mhmail "$expected" "-from sender@localhost" '|' message
174 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
175
176
177 # check -from and -body
178 # Verified same behavior as compiled mhmail.
179 cat > "$expected" <<EOF
180 EHLO nosuchhost.example.com
181 MAIL FROM:<sender@localhost>
182 RCPT TO:<recipient@example.com>
183 DATA
184 To: recipient@example.com
185 From: sender@localhost
186 Date:
187
188 body
189 .
190 QUIT
191 EOF
192
193 test_mhmail "$expected" "-from sender@localhost" -b body
194 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
195
196
197 # check -from and -cc
198 # Verified same behavior as compiled mhmail.
199 cat > "$expected" <<EOF
200 EHLO nosuchhost.example.com
201 MAIL FROM:<sender@localhost>
202 RCPT TO:<recipient@example.com>
203 RCPT TO:<recipient2@example.com>
204 DATA
205 To: recipient@example.com
206 Cc: recipient2@example.com
207 From: sender@localhost
208 Date:
209
210 message
211 .
212 QUIT
213 EOF
214
215 test_mhmail "$expected" \
216     "-from sender@localhost -cc recipient2@example.com" '|' message
217 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
218
219
220 # check -from and multiple -cc addresses
221 # Verified same behavior as compiled mhmail.
222 cat > "$expected" <<EOF
223 EHLO nosuchhost.example.com
224 MAIL FROM:<sender@localhost>
225 RCPT TO:<recipient@example.com>
226 RCPT TO:<recipient2@example.com>
227 RCPT TO:<recipient3@example.com>
228 RCPT TO:<recipient4@example.com>
229 DATA
230 To: recipient@example.com
231 Cc: recipient2@example.com, recipient3@example.com,
232     recipient4@example.com
233 From: sender@localhost
234 Date:
235
236 message
237 .
238 QUIT
239 EOF
240
241 test_mhmail "$expected" \
242     '-from sender@localhost -cc recipient2@example.com recipient3@example.com '\
243 'recipient4@example.com' '|' message
244 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
245
246
247 # check -from and -subject
248 # Verified same behavior as compiled mhmail.
249 cat > "$expected" <<EOF
250 EHLO nosuchhost.example.com
251 MAIL FROM:<sender@localhost>
252 RCPT TO:<recipient@example.com>
253 DATA
254 To: recipient@example.com
255 Subject: Test
256 From: sender@localhost
257 Date:
258
259 message
260 .
261 QUIT
262 EOF
263
264 test_mhmail "$expected" '-from sender@localhost -subject Test' '|' message
265 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
266
267
268 # check -from and -profile
269 # Show that -profile causes mhmail to 1) read the profile and
270 # 2) use send(1) by added a send switch to the profile and
271 # verifying that it gets used.
272 # Not supported by compiled mhmail.
273 printf 'send: -msgid\n' >> $MH
274
275 cat > "$expected" <<EOF
276 EHLO nosuchhost.example.com
277 MAIL FROM:<sender@localhost>
278 RCPT TO:<recipient@example.com>
279 DATA
280 To: recipient@example.com
281 From: sender@localhost
282 Date:
283 Message-ID:
284
285 message
286 .
287 QUIT
288 EOF
289
290 test_mhmail "$expected" '-from sender@localhost -profile' '|' message
291 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
292
293
294 # check repeated -from and -subject switches
295 # Verified same behavior as compiled mhmail.
296 cat > "$expected" <<EOF
297 EHLO nosuchhost.example.com
298 MAIL FROM:<sender2@localhost>
299 RCPT TO:<recipient@example.com>
300 DATA
301 To: recipient@example.com
302 Subject: Subject2
303 From: sender2@localhost
304 Date:
305
306 message
307 .
308 QUIT
309 EOF
310
311 test_mhmail "$expected" '-from sender@localhost -from sender2@localhost '\
312 '-subject Subject1 -subject Subject2' -b message
313 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
314
315 # check repeated -body switches
316 # Verified same behavior as compiled mhmail.
317 cat > "$expected" <<EOF
318 EHLO nosuchhost.example.com
319 MAIL FROM:<sender@localhost>
320 RCPT TO:<recipient@example.com>
321 DATA
322 To: recipient@example.com
323 From: sender@localhost
324 Date:
325
326 body2
327 .
328 QUIT
329 EOF
330
331 test_mhmail "$expected" "-from sender@localhost -body body1" -b body2
332 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
333
334
335 # check multiple -cc switches
336 # Verified same behavior as compiled mhmail.
337 cat > "$expected" <<EOF
338 EHLO nosuchhost.example.com
339 MAIL FROM:<sender@localhost>
340 RCPT TO:<recipient@example.com>
341 RCPT TO:<cc1@example.com>
342 RCPT TO:<cc2@example.com>
343 DATA
344 To: recipient@example.com
345 Cc: cc1@example.com, cc2@example.com
346 From: sender@localhost
347 Date:
348
349 message
350 .
351 QUIT
352 EOF
353
354 test_mhmail "$expected" \
355   '-from sender@localhost -cc cc1@example.com -cc cc2@example.com' -b message
356 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
357
358
359 # check separated -cc arguments
360 # Verified same behavior as compiled mhmail.
361 cat > "$expected" <<EOF
362 EHLO nosuchhost.example.com
363 MAIL FROM:<sender@localhost>
364 RCPT TO:<recipient@example.com>
365 RCPT TO:<cc1@example.com>
366 RCPT TO:<cc2@example.com>
367 DATA
368 To: recipient@example.com
369 Cc: cc1@example.com, cc2@example.com
370 Subject: Test
371 From: sender@localhost
372 Date:
373
374 message
375 .
376 QUIT
377 EOF
378
379 test_mhmail "$expected" \
380   '-from sender@localhost -cc cc1@example.com -subject Test cc2@example.com' \
381   -b message
382 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
383
384
385 # check -cc switch followed by -to switch
386 # Verified same behavior as compiled mhmail.
387 cat > "$expected" <<EOF
388 EHLO nosuchhost.example.com
389 MAIL FROM:<sender@localhost>
390 RCPT TO:<recipient@example.com>
391 RCPT TO:<recipient2@example.com>
392 RCPT TO:<cc1@example.com>
393 DATA
394 To: recipient@example.com, recipient2@example.com
395 Cc: cc1@example.com
396 Subject: Test
397 From: sender@localhost
398 Date:
399
400 message
401 .
402 QUIT
403 EOF
404
405 test_mhmail "$expected" \
406   "-from sender@localhost -cc cc1@example.com -subject Test \
407    -to recipient2@example.com" \
408   -b message
409 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
410
411
412 # check with no newline on stdin
413 # Shows different behavior than compiled mhmail, which was silent in this case.
414 cat > "$expected" <<EOF
415 EOF
416
417 cat > "$expected_err" <<EOF
418 mhmail: empty message not sent, use -body '' to force.
419 EOF
420
421 set +e
422 printf '' | mhmail recipient@example.com -server 127.0.0.1 -port $localport \
423   >"$actual" 2>"$actual_err"
424 set -e
425
426 check "$expected" "$actual"
427 check "$expected_err" "$actual_err"
428 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
429
430
431 # check with one newline on stdin
432 # Verified same behavior as compiled mhmail.
433 cat > "$expected" <<EOF
434 EHLO nosuchhost.example.com
435 MAIL FROM:<sender@localhost>
436 RCPT TO:<recipient@example.com>
437 DATA
438 To: recipient@example.com
439 From: sender@localhost
440 Date:
441
442
443 .
444 QUIT
445 EOF
446
447 test_mhmail "$expected" '-from sender@localhost' '|' '
448 '
449 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
450
451
452 # check with multiple newlines on stdin
453 # Verified same behavior as compiled mhmail.
454 cat > "$expected" <<EOF
455 EHLO nosuchhost.example.com
456 MAIL FROM:<sender@localhost>
457 RCPT TO:<recipient@example.com>
458 DATA
459 To: recipient@example.com
460 From: sender@localhost
461 Date:
462
463
464
465
466 .
467 QUIT
468 EOF
469
470 test_mhmail "$expected" '-from sender@localhost' '|' '
471
472
473 '
474 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
475
476
477 # check with text and no trailing newline on stdin
478 # Verified same behavior as compiled mhmail.
479 cat > "$expected" <<EOF
480 EHLO nosuchhost.example.com
481 MAIL FROM:<sender@localhost>
482 RCPT TO:<recipient@example.com>
483 DATA
484 To: recipient@example.com
485 From: sender@localhost
486 Date:
487
488 no newline in input
489 .
490 QUIT
491 EOF
492
493 test_mhmail "$expected" '-from sender@localhost' '|' 'no newline in input'
494 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
495
496
497 # check with text and multiple trailing blank lines on stdin
498 # Verified same behavior as compiled mhmail.
499 cat > "$expected" <<EOF
500 EHLO nosuchhost.example.com
501 MAIL FROM:<sender@localhost>
502 RCPT TO:<recipient@example.com>
503 DATA
504 To: recipient@example.com
505 From: sender@localhost
506 Date:
507
508 here's some text
509
510
511 .
512 QUIT
513 EOF
514
515 test_mhmail "$expected" '-from sender@localhost' '|' "here's some text
516
517
518 "
519 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
520
521
522 # check with no newline to -body
523 # Verified same behavior as compiled mhmail.
524 cat > "$expected" <<EOF
525 EHLO nosuchhost.example.com
526 MAIL FROM:<sender@localhost>
527 RCPT TO:<recipient@example.com>
528 DATA
529 To: recipient@example.com
530 From: sender@localhost
531 Date:
532
533
534 .
535 QUIT
536 EOF
537
538 test_mhmail "$expected" '-from sender@localhost' -b ''
539 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
540
541
542 # check with one newline to -body
543 # Shows different behavior than compiled mhmail, which suppressed the newline.
544 cat > "$expected" <<EOF
545 EHLO nosuchhost.example.com
546 MAIL FROM:<sender@localhost>
547 RCPT TO:<recipient@example.com>
548 DATA
549 To: recipient@example.com
550 From: sender@localhost
551 Date:
552
553
554
555 .
556 QUIT
557 EOF
558
559 test_mhmail "$expected" '-from sender@localhost' -b '
560 '
561 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
562
563
564 # check with multiple newlines to -body
565 # Shows different behavior than compiled mhmail, which suppressed one
566 #   of the newlines.
567 cat > "$expected" <<EOF
568 EHLO nosuchhost.example.com
569 MAIL FROM:<sender@localhost>
570 RCPT TO:<recipient@example.com>
571 DATA
572 To: recipient@example.com
573 From: sender@localhost
574 Date:
575
576
577
578
579
580 .
581 QUIT
582 EOF
583
584 test_mhmail "$expected" '-from sender@localhost' -b '
585
586
587 '
588 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
589
590
591 # check with text and no trailing newline to -body
592 # Verified same behavior as compiled mhmail.
593 cat > "$expected" <<EOF
594 EHLO nosuchhost.example.com
595 MAIL FROM:<sender@localhost>
596 RCPT TO:<recipient@example.com>
597 DATA
598 To: recipient@example.com
599 From: sender@localhost
600 Date:
601
602 no newline in input
603 .
604 QUIT
605 EOF
606
607 test_mhmail "$expected" '-from sender@localhost' -b 'no newline in input'
608 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
609
610
611 # check with text and multiple trailing blank lines to -body
612 # Shows different behavior than compiled mhmail, which suppressed one
613 #   of the newlines.
614 cat > "$expected" <<EOF
615 EHLO nosuchhost.example.com
616 MAIL FROM:<sender@localhost>
617 RCPT TO:<recipient@example.com>
618 DATA
619 To: recipient@example.com
620 From: sender@localhost
621 Date:
622
623 here's some text
624
625
626 .
627 QUIT
628 EOF
629
630 test_mhmail "$expected" '-from sender@localhost' -b "here's some text
631
632 "
633 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
634
635
636 # check -resent
637 # Verified same behavior as compiled mhmail.
638 cat > "$expected" <<EOF
639 EHLO nosuchhost.example.com
640 MAIL FROM:<orig_recipient@example.com>
641 RCPT TO:<recipient@example.com>
642 DATA
643 Resent-To: recipient@example.com
644 Resent-From: orig_recipient@example.com
645 To: recipient@example.com
646 From: sender@localhost
647 Date:
648 Resent-Date:
649
650 please resend this message, 1
651 .
652 QUIT
653 EOF
654
655 test_mhmail "$expected" '-from orig_recipient@example.com -resent' \
656   -b 'To: recipient@example.com
657 From: sender@localhost
658 Date: Sat Jun 16 18:35:15 -0500
659
660 please resend this message, 1'
661
662 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
663
664 # check -resent -profile, using stdin
665 # Not supported by compiled mhmail.
666 cat > "$expected" <<EOF
667 EHLO nosuchhost.example.com
668 MAIL FROM:<orig_recipient@example.com>
669 RCPT TO:<recipient@example.com>
670 DATA
671 To: recipient@example.com
672 From: sender@localhost
673 Date:
674 Resent-To: recipient@example.com
675 Resent-From: orig_recipient@example.com
676 Resent-Date:
677
678 please resend this message, 2
679 .
680 QUIT
681 EOF
682
683 test_mhmail "$expected" \
684   '-from orig_recipient@example.com -resent -profile -nomsgid' \
685   '|' 'To: recipient@example.com
686 From: sender@localhost
687 Date: Sat Jun 16 18:35:15 -0500
688
689 please resend this message, 2'
690
691 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
692
693
694 # check -resent -profile, using -b
695 # Not supported by compiled mhmail.
696 cat > "$expected" <<EOF
697 EHLO nosuchhost.example.com
698 MAIL FROM:<orig_recipient@example.com>
699 RCPT TO:<recipient@example.com>
700 DATA
701 To: recipient@example.com
702 From: sender@localhost
703 Date:
704 Resent-To: recipient@example.com
705 Resent-From: orig_recipient@example.com
706 Resent-Date:
707
708 please resend this message, 3
709 .
710 QUIT
711 EOF
712
713 test_mhmail "$expected" \
714   '-from orig_recipient@example.com -resent -profile -nomsgid' \
715   -b 'To: recipient@example.com
716 From: sender@localhost
717 Date: Sat Jun 16 18:35:15 -0500
718
719 please resend this message, 3'
720
721 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
722
723
724 # check -headerfield.
725 # Not supported by compiled mhmail.
726 cat > "$expected" <<EOF
727 EHLO nosuchhost.example.com
728 MAIL FROM:<sender@example.com>
729 RCPT TO:<recipient@example.com>
730 DATA
731 To: recipient@example.com
732 From: sender@example.com
733 User-Agent: nmh
734 Date:
735
736 with added header field
737 .
738 QUIT
739 EOF
740
741 test_mhmail "$expected" \
742   '-from sender@example.com -headerfield User-Agent:nmh' \
743   -b 'with added header field'
744
745 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
746
747
748 # check multiple -headerfields.
749 # Not supported by compiled mhmail.
750 cat > "$expected" <<EOF
751 EHLO nosuchhost.example.com
752 MAIL FROM:<sender@example.com>
753 RCPT TO:<recipient@example.com>
754 DATA
755 To: recipient@example.com
756 From: sender@example.com
757 MIME-Version: 1.0
758 Content-Type: text/plain;charset=utf-8
759 Content-Transfer-Encoding: 8bit
760 Date:
761
762 with added header fields
763 .
764 QUIT
765 EOF
766
767 test_mhmail "$expected" \
768   "-from sender@example.com -headerfield MIME-Version:1.0 \
769 -headerfield Content-Type:text/plain;charset=utf-8 \
770 -headerfield Content-Transfer-Encoding:8bit" \
771   -b 'with added header fields'
772
773 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
774
775
776 # check -attach
777 # Not supported by compiled mhmail.
778 cat > "$expected" <<EOF
779 EHLO nosuchhost.example.com
780 MAIL FROM:<sender@example.com>
781 RCPT TO:<recipient@example.com>
782 DATA
783 To: recipient@example.com
784 From: sender@example.com
785 MIME-Version: 1.0
786 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
787 Date:
788 Message-ID:
789
790 ------- =_aaaaaaaaaa0
791 Content-Type: text/plain; charset="us-ascii"
792
793 See how easy it is to add an attachment!
794
795 ------- =_aaaaaaaaaa0
796 Content-Type: text/plain; name="attachment.txt"; charset="us-ascii"
797 Content-Description: attachment.txt
798 Content-Disposition: attachment; filename="attachment.txt"
799
800 The future disappears into memory, With only a moment between,
801 Forever dwells in that moment, hope is what remains to be seen
802 Forever dwells in that moment, hope is what remains to be seen.
803
804 ------- =_aaaaaaaaaa0--
805 .
806 QUIT
807 EOF
808
809 test_mhmail "$expected" \
810   "-from sender@example.com -attach ${srcdir}/test/mhmail/attachment.txt" \
811   -b 'See how easy it is to add an attachment!'
812
813 [ ${failed:-0} -eq 0 ] || exit ${failed:-0}
814
815
816 exit ${failed:-0}