File: reload_test

package info (click to toggle)
sniproxy 0.6.1%2Bgit20240321-0.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 644 kB
  • sloc: ansic: 5,594; perl: 1,673; sh: 237; makefile: 131
file content (188 lines) | stat: -rwxr-xr-x 4,387 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/env perl

use strict;
use warnings;
use File::Basename;
use lib dirname (__FILE__);
use TestUtils;
use TestHTTPD;
use File::Temp;

sub proxy {
    my $config = shift;

    exec(@_, '../src/sniproxy', '-f', '-c', $config);
}

sub worker($$$$) {
    my ($hostname, $path, $port, $requests) = @_;

    for (my $i = 0; $i < $requests; $i++) {
        system('curl',
                '-s', '-S',
                '-H', "Host: $hostname",
                '-o', '/dev/null',
                "http://localhost:$port/$path");

        if ($? == -1) {
            die "failed to execute: $!\n";
        } elsif ($? & 127) {
            printf STDERR "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
            exit 255;
        } elsif ($? >> 8) {
            exit $? >> 8;
        }
    }
    # Success
    exit 0;
}

sub make_config($$$) {
    my $proxy_port1 = shift;
    my $proxy_port2 = shift;
    my $httpd_port = shift;

    my ($fh, $filename) = File::Temp::tempfile();
    my ($unused, $logfile) = File::Temp::tempfile();
    chmod(0644, $filename);
    chmod(0666, $logfile);

    # Write out a test config file
    print $fh <<END;
# Minimal test configuration

listen 127.0.0.1 $proxy_port1 {
    proto http
    table table_a
    access_log $logfile
}

listen 127.0.0.1 $proxy_port2 {
    proto http
    table table_b
    access_log $logfile
}

table table_a {
    localhost 127.0.0.1 $httpd_port
}

table table_b  {
    localhost 127.0.0.1 $httpd_port
}
END

    close ($fh);

    return $filename;
}

sub alter_config($$$$) {
    my $filename = shift;
    my $proxy_port1 = shift;
    my $proxy_port2 = shift;
    my $httpd_port = shift;

    my $fh = undef;
    open($fh, '>', $filename)
        or die("open(): $!");

    # Write out a test config file
    print $fh <<END;
# Minimal test configuration

listen 127.0.0.1 $proxy_port1 {
    proto http
    table table_c
}

listen 127.0.0.1 $proxy_port2 {
    proto http
    table table_a
}

table table_a {
    localhost 127.0.0.1 $httpd_port
}

table table_c  {
    localhost 127.0.0.1 $httpd_port
}
END

    close ($fh);
}


sub main {
    my $proxy_port1 = $ENV{SNI_PROXY_PORT} || 8080;
    my $proxy_port2 = $ENV{SNI_PROXY_PORT2} || 8081;
    my $proxy_port3 = $ENV{SNI_PROXY_PORT3} || 8082;
    my $httpd_port1 = $ENV{TEST_HTTPD_PORT} || 8083;
    my $httpd_port2 = $ENV{TEST_HTTPD_PORT2} || 8084;
    my $workers = $ENV{WORKERS} || 10;
    my $iterations = $ENV{ITERATIONS} || 10;

    my $config = make_config($proxy_port1, $proxy_port2, $httpd_port1);
    my $proxy_pid = start_child('server', \&proxy, $config, @ARGV);
    my $httpd_pid = start_child('server', \&TestHTTPD::httpd, port => $httpd_port1);

    # Wait for proxy to load and parse config
    wait_for_port(port => $httpd_port1);
    wait_for_port(port => $proxy_port1);
    wait_for_port(port => $proxy_port2);

    for (my $i = 0; $i < $workers; $i++) {
        start_child('worker', \&worker, 'localhost', '', $proxy_port1, $iterations);
    }
    for (my $i = 0; $i < $workers; $i++) {
        start_child('worker', \&worker, 'localhost', '', $proxy_port2, $iterations);
    }

    # Wait for all our children to finish
    wait_for_type('worker');

    kill 15, $httpd_pid;

    # edit config
    alter_config($config, $proxy_port2, $proxy_port3, $httpd_port2);

    kill 1, $proxy_pid;

    $httpd_pid = start_child('server', \&TestHTTPD::httpd, port => $httpd_port2);
    wait_for_port(port => $httpd_port2);

    for (my $i = 0; $i < $workers; $i++) {
        start_child('worker', \&worker, 'localhost', '', $proxy_port2, $iterations);
    }
    for (my $i = 0; $i < $workers; $i++) {
        start_child('worker', \&worker, 'localhost', '', $proxy_port3, $iterations);
    }

    # Wait for all our children to finish
    wait_for_type('worker');


    # Give the proxy a second to flush buffers and close server connections
    sleep 1;

    # For troubleshooting connections stuck in CLOSE_WAIT state
    #kill 10, $proxy_pid;
    #system("netstat -ptn | grep $proxy_pid\/sniproxy");

    # For troubleshooting 100% CPU usage
    #system("top -n 1 -p $proxy_pid -b");

    # Orderly shutdown of the server
    kill 15, $proxy_pid;
    kill 15, $httpd_pid;
    sleep 1;

    # Delete our test configuration
    unlink($config);

    # Kill off any remaining children
    reap_children();
}

main();