annotate lib/Test/Nginx.pm @ 15:c6c36d7a4d90

Tests: support config embedded in test itself.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 13 Sep 2008 02:57:01 +0400
parents d4b74207a627
children c57e8bd7bfc7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
1 package Test::Nginx;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
2
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
3 # (C) Maxim Dounin
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
4
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
5 # Generict module for nginx tests.
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
6
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
7 ###############################################################################
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
8
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
9 use warnings;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
10 use strict;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
11
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
12 use base qw/ Exporter /;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
13
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
14 our @EXPORT = qw/ log_in log_out http /;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
15
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
16 ###############################################################################
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
17
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
18 use File::Temp qw/ tempdir /;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
19 use IO::Socket;
7
9eb509695651 Tests: drop our own CRLF constant, use Socket's one instead.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6
diff changeset
20 use Socket qw/ CRLF /;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
21
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
22 ###############################################################################
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
23
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
24 sub new {
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
25 my $self = {};
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
26 bless $self;
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
27
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
28 $self->{_testdir} = tempdir(
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
29 'nginx-test-XXXXXXXXXX',
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
30 TMPDIR => 1,
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
31 CLEANUP => not $ENV{LEAVE}
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
32 )
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
33 or die "Can't create temp directory: $!\n";
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
34
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
35 return $self;
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
36 }
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
37
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
38 sub DESTROY {
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
39 my ($self) = @_;
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
40 $self->stop();
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
41 }
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
42
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
43 sub run {
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
44 my ($self, $conf) = @_;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
45
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
46 my $testdir = $self->{_testdir};
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
47
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
48 if (defined $conf) {
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
49 my $c = `cat $conf`;
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
50 $self->write_file_expand('nginx.conf', $c);
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
51 }
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
52
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
53 my $pid = fork();
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
54 die "Unable to fork(): $!\n" unless defined $pid;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
55
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
56 if ($pid == 0) {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
57 exec('../nginx/objs/nginx', '-c', "$testdir/nginx.conf", '-g',
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
58 "pid $testdir/nginx.pid; "
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
59 . "error_log $testdir/nginx-error.log debug;")
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
60 or die "Unable to exec(): $!\n";
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
61 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
62
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
63 # wait for nginx to start
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
64
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
65 sleep 1;
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
66
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
67 return $self;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
68 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
69
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
70 sub stop() {
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
71 my ($self) = @_;
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
72
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
73 # terminate nginx by SIGTERM
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
74 kill 15, `cat $self->{_testdir}/nginx.pid`;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
75 wait;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
76
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
77 return $self;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
78 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
79
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
80 sub write_file($$) {
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
81 my ($self, $name, $content) = @_;
12
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
82
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
83 open F, '>' . $self->{_testdir} . '/' . $name
12
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
84 or die "Can't create $name: $!";
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
85 print F $content;
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
86 close F;
14
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
87
d4b74207a627 Tests: refactor common functions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 12
diff changeset
88 return $self;
12
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
89 }
d19146b30334 Tests: move write_file() into _common.pm.
Maxim Dounin <mdounin@mdounin.ru>
parents: 8
diff changeset
90
15
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
91 sub write_file_expand($$) {
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
92 my ($self, $name, $content) = @_;
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
93
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
94 $content =~ s/%%TESTDIR%%/$self->{_testdir}/gms;
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
95
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
96 return $self->write_file($name, $content);
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
97 }
c6c36d7a4d90 Tests: support config embedded in test itself.
Maxim Dounin <mdounin@mdounin.ru>
parents: 14
diff changeset
98
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
99 ###############################################################################
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
100
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
101 sub log_out {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
102 my ($msg) = @_;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
103 $msg =~ s/^/# >> /gm;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
104 $msg .= "\n" unless $msg =~ /\n\Z/;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
105 print $msg;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
106 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
107
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
108 sub log_in {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
109 my ($msg) = @_;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
110 $msg =~ s/^/# << /gm;
6
8813a78ab8b5 Tests: drop LWP dependency.
Maxim Dounin <mdounin@mdounin.ru>
parents: 5
diff changeset
111 $msg =~ s/([^\x20-\x7e])/sprintf('\\x%02x', ord($1)) . (($1 eq "\n") ? "\n" : '')/gmxe;
5
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
112 $msg .= "\n" unless $msg =~ /\n\Z/;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
113 print $msg;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
114 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
115
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
116 ###############################################################################
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
117
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
118 sub http {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
119 my ($request) = @_;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
120 my $reply;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
121 eval {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
122 local $SIG{ALRM} = sub { die "alarm\n" };
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
123 alarm(2);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
124 my $s = IO::Socket::INET->new(
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
125 Proto => 'tcp',
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
126 PeerHost => 'localhost:8080'
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
127 );
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
128 log_out($request);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
129 $s->print($request);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
130 local $/;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
131 $reply = $s->getline();
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
132 log_in($reply);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
133 alarm(0);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
134 };
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
135 alarm(0);
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
136 if ($@) {
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
137 log_in('(timeout)');
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
138 return undef;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
139 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
140 return $reply;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
141 }
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
142
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
143 ###############################################################################
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
144
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
145 1;
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
146
4d75bdb05ecf Tests: some generic code and ssi tests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
147 ###############################################################################