Skip to content

Commit

Permalink
Add bindings and body prefix test for transcoding
Browse files Browse the repository at this point in the history
Change-Id: I75ad599fa85b8251fc3dbc26635b7f444d8a670a
  • Loading branch information
gurgenh committed Aug 19, 2016
1 parent e70cf45 commit c3153b2
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/nginx/t/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ nginx_suite(
nginx = "//src/nginx/main:nginx-esp",
tests = [
"transcoding.t",
"transcoding_bindings.t",
"transcoding_errors.t",
"transcoding_streaming.t",
],
Expand Down
259 changes: 259 additions & 0 deletions src/nginx/t/transcoding_bindings.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# Copyright (C) Endpoints Server 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;

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

BEGIN { use FindBin; chdir($FindBin::Bin); }

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

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

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

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

$t->write_file('service.json',
ApiManager::get_transcoding_test_service_config(
'endpoints-transcoding-test.cloudendpointsapis.com',
"http://127.0.0.1:${ServiceControlPort}"));

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.json;
%%TEST_CONFIG%%
on;
}
grpc_pass 127.0.0.1:${GrpcServerPort};
}
}
}
EOF

my $report_done = 'report_done';

$t->run_daemon(\&service_control, $t, $ServiceControlPort, 'servicecontrol.log', $report_done);
ApiManager::run_transcoding_test_server($t, 'server.log', "127.0.0.1:${GrpcServerPort}");

is($t->waitforsocket("127.0.0.1:${ServiceControlPort}"), 1, "Service control socket ready.");
is($t->waitforsocket("127.0.0.1:${GrpcServerPort}"), 1, "GRPC test server socket ready.");
$t->run();
is($t->waitforsocket("127.0.0.1:${NginxPort}"), 1, "Nginx socket ready.");

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

# 1. Binding shelf=1 in ListBooksRequest
# HTTP template:
# GET /shelves/{shelf}/books
my $response = ApiManager::http_get($NginxPort,'/shelves/1/books?key=api-key');
ok(ApiManager::verify_http_json_response(
$response,
{ 'books' => [ {'id' => '1', 'author' => 'Neal Stephenson', 'title' => 'Readme'} ] }),
'Got initial books for shelf 1');

# 2. Binding shelf=2 in ListBooksRequest
# HTTP template:
# GET /shelves/{shelf}/books
my $response = ApiManager::http_get($NginxPort,'/shelves/2/books?key=api-key');
ok(ApiManager::verify_http_json_response(
$response,
{ 'books' => [ {'id' => '2', 'author' => 'George R.R. Martin', 'title' => 'A Game of Thrones'} ] }),
'Got initial books for shelf 2');

# 3. Binding shelf=1 and book=<post body> in CreateBookRequest
# HTTP template:
# POST /shelves/{shelf}/books
# body: book
$response = ApiManager::http($NginxPort,<<EOF);
POST /shelves/1/books?key=api-key HTTP/1.0
Host: 127.0.0.1:${NginxPort}
Content-Type: application/json
Content-Length: 53
{"author" : "Leo Tolstoy", "title" : "War and Peace"}
EOF
ok(ApiManager::verify_http_json_response(
$response, {'id' => '3', 'author' => 'Leo Tolstoy', 'title' => 'War and Peace'}),
'Got the new book');

# 4. Binding shelf=1, book.id=4, book.author="Mark Twain" and book.title=<post body>
# in CreateBookRequest.
# HTTP template:
# POST /shelves/{shelf}/books/{book.id}/{book.author}
# body: book.title
$response = ApiManager::http($NginxPort,<<EOF);
POST /shelves/1/books/4/Mark%20Twain?key=api-key HTTP/1.0
Host: 127.0.0.1:${NginxPort}
Content-Type: application/json
Content-Length: 36
"The Adventures of Huckleberry Finn"
EOF
ok(ApiManager::verify_http_json_response(
$response, {'id' => '4', 'author' => 'Mark Twain', 'title' => 'The Adventures of Huckleberry Finn'}),
'Got the new book');

# 5. Binding shelf=1 in ListBooksRequest
# HTTP template:
# GET /shelves/{shelf}/books
my $response = ApiManager::http_get($NginxPort,'/shelves/1/books?key=api-key');
ok(ApiManager::verify_http_json_response(
$response, { 'books' => [
{'id' => '1', 'author' => 'Neal Stephenson', 'title' => 'Readme'},
{'id' => '3', 'author' => 'Leo Tolstoy', 'title' => 'War and Peace'},
{'id' => '4', 'author' => 'Mark Twain', 'title' => 'The Adventures of Huckleberry Finn'},
] }),
'Got all books for shelf 1');

# 6. Binding shelf=1 and book=3 in DeleteBookRequest
# HTTP template:
# DELETE /shelves/{shelf}/books/{book}
my $response = ApiManager::http($NginxPort,<<EOF);
DELETE /shelves/1/books/3?key=api-key HTTP/1.0
HOST: 127.0.0.1:${NginxPort}
EOF
ok(ApiManager::verify_http_json_response($response, {}), 'Got empty resonse for delete');

# 7. Binding shelf=1 in ListBooksRequest
# HTTP template:
# GET /shelves/{shelf}/books
my $response = ApiManager::http_get($NginxPort,'/shelves/1/books?key=api-key');
ok(ApiManager::verify_http_json_response(
$response, { 'books' => [
{'id' => '1', 'author' => 'Neal Stephenson', 'title' => 'Readme'},
{'id' => '4', 'author' => 'Mark Twain', 'title' => 'The Adventures of Huckleberry Finn'},
] }),
'Got final list of books for shelf 1');


# Wait for the service control report
is($t->waitforfile("$t->{_testdir}/${report_done}"), 1, 'Report body file ready.');
$t->stop_daemons();

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

# Read and verify backend logs
my $server_output = $t->read_file('server.log');
my @translated_requests = split /\r\n\r\n/, $server_output;

# Check the translated requests
is (scalar @translated_requests, 7, 'The server got the expected requests');

# 1. ListBooksRequest with shelf=1
ok(ApiManager::compare_json($translated_requests[0], {'shelf'=>'1'}));

# 2. ListBooksRequest with shelf=2
ok(ApiManager::compare_json($translated_requests[1], {'shelf'=>'2'}));

# 3. CreateBookRequest with shelf=1 and book={"author" : "Leo Tolstoy", "title" : "War and Peace"}
ok(ApiManager::compare_json(
$translated_requests[2], {'shelf'=>'1', book => {'author' => 'Leo Tolstoy', 'title' => 'War and Peace'}} ));

# 4. CreateBookRequest with shelf=1 and book={"id" : "4", "author" : "Mark Twain",
# "title" : "The Adventures of Huckleberry Finn"}
ok(ApiManager::compare_json(
$translated_requests[3],
{'shelf'=>'1', book => {'id' => '4', 'author' => 'Mark Twain',
'title' => 'The Adventures of Huckleberry Finn'}} ));

# 5. ListBooksRequest with shelf=1
ok(ApiManager::compare_json($translated_requests[4], {'shelf'=>'1'}));

# 6. DeleteBookRequest with shelf=1 and book=3
ok(ApiManager::compare_json($translated_requests[5], {'shelf'=>'1', 'book'=>'3'}));

# 7. ListBooksRequest with shelf=1
ok(ApiManager::compare_json($translated_requests[6], {'shelf'=>'1'}));

# Check service control calls
# We expect 4 service control calls:
# - 1 check call for all calls to ListBooks (as we are using the same API key the
# second time check response is in the cache)
# - 1 check call for all calls to CreateBook,
# - 1 check call for the call to DeleteBook,
# - 1 aggregated report call
my @servicecontrol_requests = ApiManager::read_http_stream($t, 'servicecontrol.log');
is(scalar @servicecontrol_requests, 4, 'Service control was called 2 times');

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

sub service_control {
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-transcoding-test.cloudendpointsapis.com:check', sub {
my ($headers, $body, $client) = @_;
print $client <<EOF;
HTTP/1.1 200 OK
Content-Type: application/json
Connection: close
EOF
});

$server->on_sub('POST', '/v1/services/endpoints-transcoding-test.cloudendpointsapis.com:report', sub {
my ($headers, $body, $client) = @_;
print $client <<EOF;
HTTP/1.1 200 OK
Content-Type: application/json
Connection: close
EOF
$t->write_file($done, ":report done");
});

$server->run();
}

################################################################################
3 changes: 3 additions & 0 deletions test/transcoding/bookstore-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ http:
- selector: "Bookstore.CreateBook"
post: "/shelves/{shelf}/books"
body: "book"
- selector: "Bookstore.CreateBook"
post: "/shelves/{shelf}/books/{book.id}/{book.author}"
body: "book.title"
- selector: "Bookstore.GetBook"
get: "/shelves/{shelf}/books/{book}"
- selector: "Bookstore.DeleteBook"
Expand Down
4 changes: 4 additions & 0 deletions test/transcoding/service.json
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,10 @@
"selector": "endpoints.examples.bookstore.Bookstore.CreateBook",
"post": "/shelves/{shelf}/books",
"body": "book"
}, {
"selector": "endpoints.examples.bookstore.Bookstore.CreateBook",
"post": "/shelves/{shelf}/books/{book.id}/{book.author}",
"body": "book.title"
}, {
"selector": "endpoints.examples.bookstore.Bookstore.GetBook",
"get": "/shelves/{shelf}/books/{book}"
Expand Down

0 comments on commit c3153b2

Please sign in to comment.