/t/35-reproxy.t

http://github.com/perlbal/Perlbal · Perl · 222 lines · 166 code · 38 blank · 18 comment · 6 complexity · 20d8b3d6f8267bca11cb871c355b719f MD5 · raw file

  1. #!/usr/bin/perl
  2. use strict;
  3. use Perlbal::Test;
  4. use Perlbal::Test::WebServer;
  5. use Perlbal::Test::WebClient;
  6. use Test::More 'no_plan';
  7. # option setup
  8. my $start_servers = 2; # web servers to start
  9. # setup a few web servers that we can work with
  10. my @web_ports = map { start_webserver() } 1..$start_servers;
  11. @web_ports = grep { $_ > 0 } map { $_ += 0 } @web_ports;
  12. ok(scalar(@web_ports) == $start_servers, 'web servers started');
  13. # setup a simple perlbal that uses the above server
  14. my $webport = new_port();
  15. my $dir = tempdir();
  16. my $deadport = new_port();
  17. my $pb_port = new_port();
  18. my $conf = qq{
  19. CREATE POOL a
  20. CREATE SERVICE test
  21. SET test.role = reverse_proxy
  22. SET test.listen = 127.0.0.1:$pb_port
  23. SET test.persist_client = 1
  24. SET test.persist_backend = 1
  25. SET test.pool = a
  26. SET test.connect_ahead = 0
  27. SET test.enable_reproxy = 1
  28. SET test.reproxy_cache_maxsize = 150
  29. ENABLE test
  30. CREATE SERVICE ws
  31. SET ws.role = web_server
  32. SET ws.listen = 127.0.0.1:$webport
  33. SET ws.docroot = $dir
  34. SET ws.dirindexing = 0
  35. SET ws.persist_client = 1
  36. ENABLE ws
  37. };
  38. my $msock = start_server($conf);
  39. ok($msock, 'perlbal started');
  40. add_all();
  41. # make first web client
  42. my $wc = Perlbal::Test::WebClient->new;
  43. $wc->server("127.0.0.1:$pb_port");
  44. $wc->keepalive(1);
  45. $wc->http_version('1.0');
  46. # see if a single request works
  47. my $resp = $wc->request('status');
  48. ok($resp, 'status response ok');
  49. # make a file on disk, verifying we can get it via disk/URL
  50. my $file_content = "foo bar yo this is my content.\n" x 1000;
  51. open(F, ">$dir/foo.txt");
  52. print F $file_content;
  53. close(F);
  54. ok(filecontent("$dir/foo.txt") eq $file_content, "file good via disk");
  55. {
  56. my $wc2 = Perlbal::Test::WebClient->new;
  57. $wc2->server("127.0.0.1:$webport");
  58. $wc2->keepalive(1);
  59. $wc2->http_version('1.0');
  60. $resp = $wc2->request('foo.txt');
  61. ok($resp && $resp->content eq $file_content, 'file good via network');
  62. }
  63. # try to get that file, via internal file redirect
  64. ok_reproxy_file();
  65. ok_reproxy_file();
  66. ok($wc->reqdone >= 2, "2 on same conn");
  67. # reproxy URL support
  68. ok_reproxy_url();
  69. ok_reproxy_url();
  70. ok($wc->reqdone >= 4, "4 on same conn");
  71. # reproxy URL support, w/ 204s from backend
  72. ok_reproxy_url_204();
  73. ok_reproxy_url_204();
  74. # reproxy cache support
  75. {
  76. my $sig_counter = 0;
  77. local $SIG{USR1} = sub { $sig_counter++ };
  78. is($sig_counter, 0, "Prior to first hit, counter should be zero.");
  79. ok_reproxy_url_cached("One");
  80. ok_reproxy_url_cached_ims("One");
  81. is($sig_counter, 1, "First hit to populate the cache.");
  82. ok_reproxy_url_cached("Two");
  83. ok_reproxy_url_cached_ims("Two");
  84. is($sig_counter, 1, "Second hit should be cached.");
  85. sleep 2;
  86. is($sig_counter, 1, "Prior to third hit, counter should still be 1.");
  87. ok_reproxy_url_cached("Three");
  88. ok_reproxy_url_cached_ims("Three");
  89. is($sig_counter, 2, "Third hit isn't cached, now 2.");
  90. ok_reproxy_url_cached("Four");
  91. ok_reproxy_url_cached_ims("Four");
  92. is($sig_counter, 2, "Forth hit should be cached again, still 2.");
  93. }
  94. # back and forth every combo
  95. # FROM / TO: status file url
  96. # status X X X
  97. # file X X X
  98. # url X X X
  99. foreach_aio {
  100. my $mode = shift;
  101. ok_status();
  102. ok_status();
  103. ok_reproxy_file();
  104. ok_reproxy_url();
  105. ok_status();
  106. ok_reproxy_url();
  107. ok_reproxy_url();
  108. ok_reproxy_file();
  109. ok_reproxy_file();
  110. ok_reproxy_url();
  111. ok_reproxy_file();
  112. ok_status();
  113. ok($wc->reqdone >= 12, "AIO mode $mode: 9 transitions");
  114. };
  115. # try to reproxy to a list of URLs, where the first one is bogus, and last one is good
  116. ok_reproxy_url_list();
  117. {
  118. my $resp = $wc->request("reproxy_url:http://127.0.0.1:$webport/bar.txt http://127.0.0.1:$webport/foo.txt");
  119. ok($resp->content eq $file_content, "reproxy URL w/ 404 one first");
  120. }
  121. # responses to HEAD requests should not have a body
  122. {
  123. $wc->keepalive(0);
  124. my $resp = $wc->request({
  125. method => "HEAD",
  126. }, "reproxy_url:http://127.0.0.1:$webport/foo.txt");
  127. ok($resp && $resp->content eq '', "no response body when req method is HEAD");
  128. $wc->keepalive(1);
  129. }
  130. my $lm;
  131. sub ok_reproxy_url_cached {
  132. my $resp = $wc->request("reproxy_url_cached:1:http://127.0.0.1:$webport/foo.txt");
  133. ok($resp && $resp->content eq $file_content, "reproxy with cache: $_[0]");
  134. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  135. $lm = $resp->header("Last-Modified");
  136. }
  137. sub ok_reproxy_url_cached_ims {
  138. die "Last-Modified hasn't been set yet" unless defined $lm;
  139. my $resp = $wc->request({ headers => "If-Modified-Since: $lm\r\n", }, "reproxy_url_cached:1:http://127.0.0.1:$webport/foo.txt");
  140. ok($resp, "Got a response");
  141. is($resp->code, 304, "reproxy with cache ims, got 304 correctly: $_[0]");
  142. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  143. }
  144. sub ok_reproxy_url_list {
  145. my $resp = $wc->request("reproxy_url_multi:$deadport:$webport:/foo.txt");
  146. ok($resp->content eq $file_content, "reproxy URL w/ dead one first");
  147. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  148. }
  149. sub ok_reproxy_file {
  150. my $resp = $wc->request("reproxy_file:$dir/foo.txt");
  151. ok($resp && $resp->content eq $file_content, "reproxy file");
  152. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  153. }
  154. sub ok_reproxy_url {
  155. my $resp = $wc->request("reproxy_url:http://127.0.0.1:$webport/foo.txt");
  156. ok($resp->content eq $file_content, "reproxy URL") or diag(dump_res($resp));
  157. is($resp->code, 200, "response code is 200");
  158. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  159. }
  160. sub ok_reproxy_url_204 {
  161. my $resp = $wc->request("reproxy_url204:http://127.0.0.1:$webport/foo.txt");
  162. ok($resp->content eq $file_content, "reproxy URL") or diag(dump_res($resp));
  163. is($resp->code, 200, "204 response code is 200");
  164. like($resp->header("Connection"), qr/Keep-Alive/i, "... and keep-alives are on");
  165. }
  166. sub ok_status {
  167. my $resp = $wc->request('status');
  168. ok($resp && $resp->content =~ /\bpid\b/, 'status ok');
  169. }
  170. sub add_all {
  171. foreach (@web_ports) {
  172. manage("POOL a ADD 127.0.0.1:$_") or die;
  173. }
  174. }
  175. sub remove_all {
  176. foreach (@web_ports) {
  177. manage("POOL a REMOVE 127.0.0.1:$_") or die;
  178. }
  179. }
  180. sub flush_pools {
  181. remove_all();
  182. add_all();
  183. }
  184. 1;