Skip to content

Commit

Permalink
Add t-test to test X-HTTP-Method-Override in istio/proxy (#141)
Browse files Browse the repository at this point in the history
* Add t-test to test X-HTTP-Method-Override in istio/proxy

* Fix the test based on code review comments.
  • Loading branch information
sarvaniv authored Apr 12, 2017
1 parent bca7c9e commit 50bc572
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 1 deletion.
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#
# A Bazel (http://bazel.io) workspace for the Google Cloud Endpoints runtime.

ISTIO_PROXY = "970699f3baba062e14d66edd8a5f6c05ddef6b5b"
ISTIO_PROXY = "81f6372cca88a35342fa105b5d65a4a82f0fe39e"
ESP_TOOL = "ff0d6df7f56ca1c2b229aaadd8abe62cb1d508fb"

git_repository(
Expand Down
1 change: 1 addition & 0 deletions src/nginx/t/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ nginx_suite(
"check_api_key.t",
"check_custom_api_key.t",
"check_default.t",
"check_http_method_override.t",
"check_invalid_api_key.t",
"check_key_restriction.t",
"check_no_consumer.t",
Expand Down
206 changes: 206 additions & 0 deletions src/nginx/t/check_http_method_override.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# Copyright (C) Extensible Service Proxy Authors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
################################################################################
#
use strict;
use warnings;

################################################################################

use src::nginx::t::ApiManager; # Must be first (sets up import path to the Nginx test module)
use src::nginx::t::HttpServer;
use src::nginx::t::ServiceControl;
use Test::Nginx; # Imports Nginx's test module
use Test::More; # And the test framework

################################################################################

# Port assignments
my $NginxPort = ApiManager::pick_port();
my $BackendPort = ApiManager::pick_port();
my $ServiceControlPort = ApiManager::pick_port();

my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(12);

# Save service name in the service configuration protocol buffer file.
my $config = ApiManager::get_bookstore_service_config_allow_unregistered .
ApiManager::read_test_file('testdata/logs_metrics.pb.txt') . <<"EOF";
producer_project_id: "esp-project-id"
control {
environment: "http://127.0.0.1:${ServiceControlPort}"
}
EOF
$t->write_file('service.pb.txt', $config);

ApiManager::write_file_expand($t, 'nginx.conf', <<"EOF");
%%TEST_GLOBALS%%
daemon off;
events {
worker_connections 32;
}
http {
%%TEST_GLOBALS_HTTP%%
server_tokens off;
server {
listen 127.0.0.1:${NginxPort};
server_name localhost;
location / {
endpoints {
api service.pb.txt;
%%TEST_CONFIG%%
on;
}
proxy_pass http://127.0.0.1:${BackendPort};
}
}
}
EOF

my $report_done = 'report_done';

$t->run_daemon(\&bookstore, $t, $BackendPort, 'bookstore.log');
$t->run_daemon(\&servicecontrol, $t, $ServiceControlPort, 'servicecontrol.log', $report_done);

is($t->waitforsocket("127.0.0.1:${BackendPort}"), 1, 'Bookstore socket ready.');
is($t->waitforsocket("127.0.0.1:${ServiceControlPort}"), 1, 'Service control socket ready.');

$t->run();

################################################################################

my $response = ApiManager::http($NginxPort,<<'EOF');
POST /shelves HTTP/1.0
X-HTTP-Method-Override: GET
Host: localhost
EOF

is($t->waitforfile("$t->{_testdir}/${report_done}"), 1, 'Report body file ready.');
$t->stop_daemons();

my ($response_headers, $response_body) = split /\r\n\r\n/, $response, 2;

like($response_headers, qr/HTTP\/1\.1 200 OK/, 'Returned HTTP 200.');
is($response_body, <<'EOF', 'Shelves returned in the response body.');
{ "shelves": [
{ "name": "shelves/1", "theme": "Fiction" },
{ "name": "shelves/2", "theme": "Fantasy" }
]
}
EOF

my @servicecontrol_requests = ApiManager::read_http_stream($t, 'servicecontrol.log');
# Check was not called since no api_key and allow_unregisterd_call.
is(scalar @servicecontrol_requests, 1, 'Service control was called once');

# :report
my $r = shift @servicecontrol_requests;
like($r->{uri}, qr/:report$/, 'The call was a :report');

my $report_body = ServiceControl::convert_proto($r->{body}, 'report_request', 'json');
my $expected_report_body = ServiceControl::gen_report_body({
'serviceConfigId' => '2016-08-25r1',
'serviceName' => 'endpoints-test.cloudendpointsapis.com',
'url' => '/shelves',
'producer_project_id' => 'esp-project-id',
'no_consumer_data' => 1,
'location' => 'us-central1',
'api_method' => 'ListShelves',
'http_method' => 'GET',
'log_message' => 'Method: ListShelves',
'response_code' => '200',
'request_size' => 68,
'response_size' => 208,
'request_bytes' => 68,
'response_bytes' => 208,
});
ok(ServiceControl::compare_json($report_body, $expected_report_body), 'Report body is received.');

my @bookstore_requests = ApiManager::read_http_stream($t, 'bookstore.log');
is(scalar @bookstore_requests, 1, 'Bookstore received one request');

# Check backend request.
my $r = shift @bookstore_requests;
is($r->{verb}, 'POST', 'backend received a post');
is($r->{path}, '/shelves', 'backend received get /shelves');
is($r->{headers}->{'x-http-method-override'}, 'GET', 'X-HTTP-Method-Override was received');

################################################################################

sub servicecontrol {
my ($t, $port, $file, $done) = @_;
my $server = HttpServer->new($port, $t->testdir() . '/' . $file)
or die "Can't create test server socket: $!\n";
local $SIG{PIPE} = 'IGNORE';

$server->on_sub('POST', '/v1/services/endpoints-test.cloudendpointsapis.com:check', sub {
my ($headers, $body, $client) = @_;
print $client <<'EOF';
HTTP/1.1 200 OK
Connection: close
EOF
});

$server->on_sub('POST', '/v1/services/endpoints-test.cloudendpointsapis.com:report', sub {
my ($headers, $body, $client) = @_;
print $client <<'EOF';
HTTP/1.1 200 OK
Connection: close
EOF

$t->write_file($done, ':report done');
});

$server->run();
}

################################################################################

sub bookstore {
my ($t, $port, $file) = @_;
my $server = HttpServer->new($port, $t->testdir() . '/' . $file)
or die "Can't create test server socket: $!\n";
local $SIG{PIPE} = 'IGNORE';

$server->on_sub('POST', '/shelves', sub {
my ($headers, $body, $client) = @_;
print $client <<'EOF';
HTTP/1.1 200 OK
Connection: close
{ "shelves": [
{ "name": "shelves/1", "theme": "Fiction" },
{ "name": "shelves/2", "theme": "Fantasy" }
]
}
EOF
});

$server->run();
}

################################################################################

0 comments on commit 50bc572

Please sign in to comment.