comparison smtp.t @ 0:de28d9f761be

Tests for nginx. Initial smtp testing.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 15 Aug 2008 18:17:24 +0400
parents
children c731d50dd6b1
comparison
equal deleted inserted replaced
-1:000000000000 0:de28d9f761be
1 #!/usr/bin/perl
2
3 # (C) Maxim Dounin
4
5 # Tests for nginx mail smtp module.
6
7 ###############################################################################
8
9 use warnings;
10 use strict;
11
12 use Test::More tests => 24;
13
14 use IO::Socket;
15 use MIME::Base64;
16
17 use constant CRLF => "\x0D\x0A";
18
19 $| = 1;
20
21 my $s = smtp_connect();
22 smtp_check(qr/^220 /, "greeting");
23
24 smtp_send('EHLO example.com');
25 smtp_check(qr/^250 /, "ehlo");
26
27 smtp_send('AUTH PLAIN ' . encode_base64("test\@example.com\0\0bad", ''));
28 smtp_check(qr/^5.. /, 'auth plain with bad password');
29
30 smtp_send('AUTH PLAIN ' . encode_base64("test\@example.com\0\0secret", ''));
31 smtp_ok('auth plain');
32
33 # We are talking to backend from this point
34
35 smtp_send('MAIL FROM:<test@example.com> SIZE=100');
36 smtp_ok('mail from after auth');
37
38 smtp_send('RSET');
39 smtp_ok('rset');
40
41 smtp_send('MAIL FROM:<test@xn--e1afmkfd.xn--80akhbyknj4f> SIZE=100');
42 smtp_ok("idn mail from (example.test in russian)");
43
44 smtp_send('QUIT');
45 smtp_ok("quit");
46
47 # Try auth plain with pipelining
48
49 $s = smtp_connect();
50 smtp_check(qr/^220 /, "greeting");
51
52 smtp_send('EHLO example.com');
53 smtp_check(qr/^250 /, "ehlo");
54
55 TODO: {
56 local $TODO = "pipelining not implemented yet";
57
58 smtp_send('AUTH PLAIN '
59 . encode_base64("test\@example.com\0\0bad", '') . CRLF
60 . 'MAIL FROM:<test@example.com> SIZE=100');
61 smtp_read();
62 smtp_ok('mail from after failed pipelined auth');
63
64 smtp_send('AUTH PLAIN '
65 . encode_base64("test\@example.com\0\0secret", '') . CRLF
66 . 'MAIL FROM:<test@example.com> SIZE=100');
67 smtp_read();
68 smtp_ok('mail from after pipelined auth');
69 }
70
71 # Try auth none
72
73 $s = smtp_connect();
74 smtp_check(qr/^220 /, "greeting");
75
76 smtp_send('EHLO example.com');
77 smtp_check(qr/^250 /, "ehlo");
78
79 smtp_send('MAIL FROM:<test@example.com> SIZE=100');
80 smtp_ok('auth none - mail from');
81
82 smtp_send('RCPT TO:<test@example.com>');
83 smtp_ok('auth none - rcpt to');
84
85 smtp_send('RSET');
86 smtp_ok('auth none - rset, should go to backend');
87
88 # Auth none with pipelining
89
90 $s = smtp_connect();
91 smtp_check(qr/^220 /, "greeting");
92
93 smtp_send('EHLO example.com');
94 smtp_check(qr/^250 /, "ehlo");
95
96 TODO: {
97 smtp_send('MAIL FROM:<test@example.com> SIZE=100' . CRLF
98 . 'RCPT TO:<test@example.com>' . CRLF
99 . 'RSET');
100
101 smtp_ok('pipelined mail from');
102
103 local $TODO = "pipelining not implemented yet";
104
105 smtp_ok('pipelined rcpt to');
106 smtp_ok('pipelined rset');
107 }
108
109 # Connection must stay even if error returned to rcpt to command
110
111 $s = smtp_connect();
112 smtp_read(); # skip greeting
113
114 smtp_send('EHLO example.com');
115 smtp_read(); # skip ehlo reply
116
117 smtp_send('MAIL FROM:<test@example.com> SIZE=100');
118 smtp_read(); # skip mail from reply
119
120 smtp_send('RCPT TO:<example.com>');
121 smtp_check(qr/^5.. /, "bad rcpt to");
122
123 smtp_send('RCPT TO:<test@example.com>');
124 smtp_ok('good rcpt to');
125
126
127 ###############################################################################
128
129 sub log_out {
130 my ($msg) = @_;
131 $msg =~ s/^/# >> /gm;
132 $msg .= "\n" unless $msg =~ /\n\Z/;
133 print $msg;
134 }
135
136 sub log_in {
137 my ($msg) = @_;
138 $msg =~ s/\x0d/\\x0d/gm;
139 $msg =~ s/\x0a/\\x0a/gm;
140 print '# << ' . $msg . "\n";
141 }
142
143 sub smtp_connect {
144 my $s = IO::Socket::INET->new(
145 Proto => "tcp",
146 PeerAddr => "localhost",
147 PeerPort => 10025,
148 )
149 or die "Can't connect to nginx: $!\n";
150
151 $s->autoflush(1);
152
153 return $s;
154 }
155
156 sub smtp_send {
157 my ($cmd) = @_;
158 log_out($cmd);
159 $s->print($cmd . CRLF);
160 }
161
162 sub smtp_read {
163 my ($regex, $name) = @_;
164 eval {
165 alarm(2);
166 local $SIG{ALRM} = sub { die "alarm\n" };
167 while (<$s>) {
168 log_in($_);
169 next if m/^\d\d\d-/;
170 last;
171 }
172 alarm(0);
173 };
174 alarm(0);
175 if ($@) {
176 return undef;
177 }
178 return $_;
179 }
180
181 sub smtp_check {
182 my ($regex, $name) = @_;
183 like(smtp_read(), $regex, $name);
184 }
185
186 sub smtp_ok {
187 smtp_check(qr/^2\d\d /, @_);
188 }
189
190 ###############################################################################