Skip to content

Instantly share code, notes, and snippets.

@shibayu36
Created April 8, 2014 12:59
Show Gist options
  • Save shibayu36/10120365 to your computer and use it in GitHub Desktop.
Save shibayu36/10120365 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use Test::TCP;
use File::Temp;
use LWP::UserAgent;
use HTTP::Server::PSGI;
use Path::Class;
use Cwd;
use Data::Dumper::Concise;
use Plack::Request;
use JSON::XS;
use Test::More;
# app serverを立てる
my $app1 = start_http_server(sub {
my $env = shift;
my $req = Plack::Request->new($env);
my $headers = { map { $_ => $req->header($_) } $req->headers->header_field_names };
# リクエストheaderをテストするために、responseに入れる
[ 200, [ 'Content-Type' => 'text/plain' ], [ encode_json $headers ] ];
});
my $app2 = start_http_server(sub {
[ 200, [ 'Content-Type' => 'text/plain' ], [ 'Hello App2' ] ];
});
# 立ちあげたapp1, app2を利用して、nginxを立てる
# proxy.nginx.confのテストをしたい
my $nginx = start_nginx_server(
app1_port => $app1->port,
app2_port => $app2->port,
conf_file => 'proxy.nginx.conf',
);
my $ua = LWP::UserAgent->new;
subtest '/へのリクエスト' => sub {
my $data = decode_json($ua->get('http://localhost:' . $nginx->port)->content);
# app1のリクエストヘッダがレスポンスに含まれるはずなのでそれを検証
is $data->{Host}, 'dummy.host', 'Hostヘッダがリクエストに付く';
};
subtest '/app2へのリクエスト' => sub {
my $content = $ua->get('http://localhost:' . $nginx->port . '/app2')->content;
is $content, 'Hello App2', 'app2にリクエストがいく';
};
subtest '/html/sample.htmlへのリクエスト' => sub {
# responseヘッダは普通に取得できるはずなのでそれを検証
subtest 'versionというクエリがついた時、キャッシュ用ヘッダが出力' => sub {
my $res = $ua->get('http://localhost:' . $nginx->port . '/html/sample.html?version=123');
ok $res->header('Expires'), 'ヘッダが出力される';
};
subtest 'クエリがつかない時、Expiresのヘッダが出ない' => sub {
my $res = $ua->get('http://localhost:' . $nginx->port . '/html/sample.html');
ok ! $res->header('Expires'), 'ヘッダが出力されない';
};
};
done_testing();
# テスト用app serverを立てるutility
sub start_http_server {
my ($app) = @_;
return Test::TCP->new(
code => sub {
my $port = shift;
my $server = HTTP::Server::PSGI->new(
host => "127.0.0.1",
port => $port,
);
$server->run($app);
},
);
}
# テスト用nginxを立てるutility
sub start_nginx_server {
my %opts = @_;
my $app1_port = $opts{app1_port};
my $app2_port = $opts{app2_port};
my $conf_file = $opts{conf_file};
return Test::TCP->new(
code => sub {
my $port = shift;
my $temp_dir = File::Temp::tempdir;
my $nginx_conf = file($conf_file)->slurp;
# ---- 設定ファイルの書き換えを行う ----
# listenの番号書き換え
$nginx_conf =~ s{listen 8080}{listen $port}g;
# upstreamをdummy serverに書き換え
$nginx_conf =~ s!upstream app1 {.*?}!upstream app1 { server localhost:$app1_port; }!s;
$nginx_conf =~ s!upstream app2 {.*?}!upstream app2 { server localhost:$app2_port; }!s;
# ファイルパスを現在のディレクトリに書き換え
my $current_directory = Cwd::getcwd();
$nginx_conf =~ s{/path/to/repository}{$current_directory}g;
# 設定ファイルを書き換えた内容をテストしやすいwrapperにくるんで
# nginxにそのまま渡せる形に
my $conf = <<"EOS";
daemon off;
error_log $temp_dir/error_log crit;
lock_file $temp_dir/lock_file;
pid $temp_dir/nginx.pid;
events {
worker_connections 1024;
}
http {
client_body_temp_path $temp_dir/client_body_temp;
proxy_temp_path $temp_dir/proxy_temp;
$nginx_conf
}
EOS
my $fh = Path::Class::file("$temp_dir/nginx.conf")->openw;
print { $fh } $conf;
close $fh;
# 起動
exec "nginx -c $temp_dir/nginx.conf -p $temp_dir";
},
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment