From 3b2e1bd243395c7b471bda2dc4fbdfb8248fe96d Mon Sep 17 00:00:00 2001
From: Carl Mastrangelo
Date: Fri, 6 Nov 2015 14:31:55 -0800
Subject: Enable interop tests for http2
---
tools/run_tests/run_interop_tests.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
(limited to 'tools/run_tests/run_interop_tests.py')
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 1686942b0a..2634164a21 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -624,7 +624,9 @@ try:
docker_image=docker_images.get(str(language)))
jobs.append(test_job)
- if args.http2_interop:
+ # TODO(carl-mastrangelo): Currently prod TLS terminators aren't spec compliant. Reenable
+ # this once a better solution is in place.
+ if args.http2_interop and False:
for test_case in _HTTP2_TEST_CASES:
test_job = cloud_to_prod_jobspec(http2Interop, test_case,
docker_image=docker_images.get(str(http2Interop)))
@@ -660,6 +662,9 @@ try:
if args.http2_interop:
for test_case in _HTTP2_TEST_CASES:
+ if server_name == "go":
+ # TODO(carl-mastrangelo): Reenable after https://github.com/grpc/grpc-go/issues/434
+ continue
test_job = cloud_to_cloud_jobspec(http2Interop,
test_case,
server_name,
--
cgit v1.2.3
From 3bc7ba4d950796fcb92ce19d3072e26bb62420f0 Mon Sep 17 00:00:00 2001
From: Adele Zhou
Date: Thu, 5 Nov 2015 10:21:58 -0800
Subject: Use mako template for HTML report.
---
templates/interop_html_report.template | 141 +++++++++++++++++++++++++++
tools/run_tests/report_utils.py | 172 +++++++--------------------------
tools/run_tests/run_interop_tests.py | 4 +-
tools/run_tests/run_tests.py | 2 +-
4 files changed, 179 insertions(+), 140 deletions(-)
create mode 100644 templates/interop_html_report.template
(limited to 'tools/run_tests/run_interop_tests.py')
diff --git a/templates/interop_html_report.template b/templates/interop_html_report.template
new file mode 100644
index 0000000000..1ba2e6cfc2
--- /dev/null
+++ b/templates/interop_html_report.template
@@ -0,0 +1,141 @@
+
+
+Interop Test Result
+
+
+<%def name="fill_one_test_result(shortname, resultset)">
+ % if shortname in resultset:
+ ## Because interop tests does not have runs_per_test flag, each test is
+ ## run once. So there should only be one element for each result.
+ <% result = resultset[shortname][0] %>
+ % if result.state == 'PASSED':
+ PASS |
+ % else:
+ <%
+ tooltip = ''
+ if result.returncode > 0 or result.message:
+ if result.returncode > 0:
+ tooltip = 'returncode: %d ' % result.returncode
+ if result.message:
+ tooltip = '%smessage: %s' % (tooltip, result.message)
+ %>
+ % if result.state == 'FAILED':
+
+ % if tooltip:
+ FAIL |
+ % else:
+ FAIL
+ % endif
+ % elif result.state == 'TIMEOUT':
+
+ % if tooltip:
+ TIMEOUT |
+ % else:
+ TIMEOUT
+ % endif
+ % endif
+ % endif
+ % else:
+ Not implemented |
+ % endif
+%def>
+
+% if num_failures > 1:
+ ${num_failures} tests failed!
+% elif num_failures:
+ ${num_failures} test failed!
+% else:
+ All tests passed!
+% endif
+
+% if cloud_to_prod:
+ ## Each column header is the client language.
+ Cloud to Prod
+
+
+ Client languages ► Test Cases ▼ |
+ % for client_lang in client_langs:
+ ${client_lang} |
+ % endfor
+
+ % for test_case in test_cases + auth_test_cases:
+ ${test_case} |
+ % for client_lang in client_langs:
+ <%
+ if test_case in auth_test_cases:
+ shortname = 'cloud_to_prod_auth:%s:%s' % (client_lang, test_case)
+ else:
+ shortname = 'cloud_to_prod:%s:%s' % (client_lang, test_case)
+ %>
+ ${fill_one_test_result(shortname, resultset)}
+ % endfor
+
+ % endfor
+
+% endif
+
+% if http2_interop:
+ ## Each column header is the server language.
+ HTTP/2 Interop
+
+
+ Servers ► Test Cases ▼ |
+ % for server_lang in server_langs:
+ ${server_lang} |
+ % endfor
+ % if cloud_to_prod:
+ prod |
+ % endif
+
+ % for test_case in http2_cases:
+ ${test_case} |
+ ## Fill up the cells with test result.
+ % for server_lang in server_langs:
+ <%
+ shortname = 'cloud_to_cloud:http2:%s_server:%s' % (
+ server_lang, test_case)
+ %>
+ ${fill_one_test_result(shortname, resultset)}
+ % endfor
+ % if cloud_to_prod:
+ <% shortname = 'cloud_to_prod:http2:%s' % test_case %>
+ ${fill_one_test_result(shortname, resultset)}
+ % endif
+
+ % endfor
+
+% endif
+
+% if server_langs:
+ % for test_case in test_cases:
+ ## Each column header is the client language.
+ ${test_case}
+
+
+ Client languages ► Server languages ▼ |
+ % for client_lang in client_langs:
+ ${client_lang} |
+ % endfor
+
+ ## Each row head is the server language.
+ % for server_lang in server_langs:
+
+ ${server_lang} |
+ % for client_lang in client_langs:
+ <%
+ shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
+ client_lang, server_lang, test_case)
+ %>
+ ${fill_one_test_result(shortname, resultset)}
+ % endfor
+
+ % endfor
+
+ % endfor
+% endif
+
+
+
+
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py
index bb9eca4254..dcc66f057d 100644
--- a/tools/run_tests/report_utils.py
+++ b/tools/run_tests/report_utils.py
@@ -29,6 +29,11 @@
"""Generate XML and HTML test reports."""
+try:
+ from mako.runtime import Context
+ from mako.template import Template
+except (ImportError):
+ pass # Mako not installed but it is ok.
import os
import string
import xml.etree.cElementTree as ET
@@ -49,7 +54,7 @@ def _filter_msg(msg, output_format):
return msg
-def render_xml_report(resultset, xml_report):
+def render_junit_xml_report(resultset, xml_report):
"""Generate JUnit-like XML report."""
root = ET.Element('testsuites')
testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc',
@@ -69,147 +74,40 @@ def render_xml_report(resultset, xml_report):
tree.write(xml_report, encoding='UTF-8')
-# TODO(adelez): Use mako template.
-def fill_one_test_result(shortname, resultset, html_str):
- if shortname in resultset:
- # Because interop tests does not have runs_per_test flag, each test is run
- # once. So there should only be one element for each result.
- result = resultset[shortname][0]
- if result.state == 'PASSED':
- html_str = '%sPASS | \n' % html_str
- else:
- tooltip = ''
- if result.returncode > 0 or result.message:
- if result.returncode > 0:
- tooltip = 'returncode: %d ' % result.returncode
- if result.message:
- escaped_msg = _filter_msg(result.message, 'HTML')
- tooltip = '%smessage: %s' % (tooltip, escaped_msg)
- if result.state == 'FAILED':
- html_str = '%s' % html_str
- if tooltip:
- html_str = ('%sFAIL | \n' %
- (html_str, tooltip))
- else:
- html_str = '%sFAIL\n' % html_str
- elif result.state == 'TIMEOUT':
- html_str = '%s' % html_str
- if tooltip:
- html_str = ('%sTIMEOUT | \n'
- % (html_str, tooltip))
- else:
- html_str = '%sTIMEOUT\n' % html_str
- else:
- html_str = '%sNot implemented | \n' % html_str
-
- return html_str
+def render_interop_html_report(
+ client_langs, server_langs, test_cases, auth_test_cases, http2_cases,
+ resultset, num_failures, cloud_to_prod, http2_interop):
+ """Generate HTML report for interop tests."""
+ template_file = 'templates/interop_html_report.template'
+ try:
+ mytemplate = Template(filename=template_file, format_exceptions=True)
+ except NameError:
+ print 'Mako template is not installed. Skipping HTML report generation.'
+ return
+ except IOError as e:
+ print 'Failed to find the template %s: %s' % (template_file, e)
+ return
+ # Write to reports/index.html as set up in Jenkins plugin.
+ html_report_dir = 'reports'
+ if not os.path.exists(html_report_dir):
+ os.mkdir(html_report_dir)
+ html_file_path = os.path.join(html_report_dir, 'index.html')
-def render_html_report(client_langs, server_langs, test_cases, auth_test_cases,
- http2_cases, resultset, num_failures, cloud_to_prod,
- http2_interop):
- """Generate html report."""
sorted_test_cases = sorted(test_cases)
sorted_auth_test_cases = sorted(auth_test_cases)
sorted_http2_cases = sorted(http2_cases)
sorted_client_langs = sorted(client_langs)
sorted_server_langs = sorted(server_langs)
- html_str = ('\n'
- '\n'
- 'Interop Test Result\n'
- '\n')
- if num_failures > 1:
- html_str = (
- '%s%d tests failed!
\n' %
- (html_str, num_failures))
- elif num_failures:
- html_str = (
- '%s%d test failed!
\n' %
- (html_str, num_failures))
- else:
- html_str = (
- '%sAll tests passed!
\n' %
- html_str)
- if cloud_to_prod:
- # Each column header is the client language.
- html_str = ('%sCloud to Prod
\n'
- '\n'
- '\n'
- 'Client languages ► | \n') % html_str
- for client_lang in sorted_client_langs:
- html_str = '%s%s\n' % (html_str, client_lang)
- html_str = '%s |
\n' % html_str
- for test_case in sorted_test_cases + sorted_auth_test_cases:
- html_str = '%s%s | \n' % (html_str, test_case)
- for client_lang in sorted_client_langs:
- if not test_case in sorted_auth_test_cases:
- shortname = 'cloud_to_prod:%s:%s' % (client_lang, test_case)
- else:
- shortname = 'cloud_to_prod_auth:%s:%s' % (client_lang, test_case)
- html_str = fill_one_test_result(shortname, resultset, html_str)
- html_str = '%s
\n' % html_str
- html_str = '%s
\n' % html_str
- if http2_interop:
- # Each column header is the server language.
- html_str = ('%sHTTP/2 Interop
\n'
- '\n'
- '\n'
- 'Servers ► '
- 'Test Cases ▼ | \n') % html_str
- for server_lang in sorted_server_langs:
- html_str = '%s%s\n' % (html_str, server_lang)
- if cloud_to_prod:
- html_str = '%s | %s\n' % (html_str, "prod")
- html_str = '%s |
\n' % html_str
- for test_case in sorted_http2_cases:
- html_str = '%s%s | \n' % (html_str, test_case)
- # Fill up the cells with test result.
- for server_lang in sorted_server_langs:
- shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
- "http2", server_lang, test_case)
- html_str = fill_one_test_result(shortname, resultset, html_str)
- if cloud_to_prod:
- shortname = 'cloud_to_prod:%s:%s' % ("http2", test_case)
- html_str = fill_one_test_result(shortname, resultset, html_str)
- html_str = '%s
\n' % html_str
- html_str = '%s
\n' % html_str
- if server_langs:
- for test_case in sorted_test_cases:
- # Each column header is the client language.
- html_str = ('%s%s
\n'
- '\n'
- '\n'
- 'Client languages ► '
- 'Server languages ▼ | \n') % (html_str, test_case)
- for client_lang in sorted_client_langs:
- html_str = '%s%s\n' % (html_str, client_lang)
- html_str = '%s |
\n' % html_str
- # Each row head is the server language.
- for server_lang in sorted_server_langs:
- html_str = '%s%s | \n' % (html_str, server_lang)
- # Fill up the cells with test result.
- for client_lang in sorted_client_langs:
- shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
- client_lang, server_lang, test_case)
- html_str = fill_one_test_result(shortname, resultset, html_str)
- html_str = '%s
\n' % html_str
- html_str = '%s
\n' % html_str
- html_str = ('%s\n'
- '\n'
- '\n'
- '') % html_str
-
- # Write to reports/index.html as set up in Jenkins plugin.
- html_report_dir = 'reports'
- if not os.path.exists(html_report_dir):
- os.mkdir(html_report_dir)
- html_file_path = os.path.join(html_report_dir, 'index.html')
- with open(html_file_path, 'w') as f:
- f.write(html_str)
+ args = {'client_langs': sorted_client_langs,
+ 'server_langs': sorted_server_langs,
+ 'test_cases': sorted_test_cases,
+ 'auth_test_cases': sorted_auth_test_cases,
+ 'http2_cases': sorted_http2_cases,
+ 'resultset': resultset,
+ 'num_failures': num_failures,
+ 'cloud_to_prod': cloud_to_prod,
+ 'http2_interop': http2_interop}
+ with open(html_file_path, 'w') as output_file:
+ mytemplate.render_context(Context(output_file, **args))
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 2634164a21..ee3cddddd9 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -686,9 +686,9 @@ try:
else:
jobset.message('SUCCESS', 'All tests passed', do_newline=True)
- report_utils.render_xml_report(resultset, 'report.xml')
+ report_utils.render_junit_xml_report(resultset, 'report.xml')
- report_utils.render_html_report(
+ report_utils.render_interop_html_report(
set([str(l) for l in languages]), servers, _TEST_CASES, _AUTH_TEST_CASES,
_HTTP2_TEST_CASES, resultset, num_failures,
args.cloud_to_prod_auth or args.cloud_to_prod, args.http2_interop)
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index ab2b71b80e..aa43337263 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -902,7 +902,7 @@ def _build_and_run(
for antagonist in antagonists:
antagonist.kill()
if xml_report and resultset:
- report_utils.render_xml_report(resultset, xml_report)
+ report_utils.render_junit_xml_report(resultset, xml_report)
number_failures, _ = jobset.run(
post_tests_steps, maxjobs=1, stop_on_failure=True,
--
cgit v1.2.3
From 2dd55db4c10d32a5d7442e977fed878c3feb72c0 Mon Sep 17 00:00:00 2001
From: Carl Mastrangelo
Date: Thu, 19 Nov 2015 10:51:48 -0800
Subject: Add framing http2 test case, enable verbose output, and properly skip
tests
---
tools/http2_interop/http2interop_test.go | 17 +++++++++++++----
tools/run_tests/run_interop_tests.py | 4 ++--
2 files changed, 15 insertions(+), 6 deletions(-)
(limited to 'tools/run_tests/run_interop_tests.py')
diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go
index 8fd838422b..e3d366f2f2 100644
--- a/tools/http2_interop/http2interop_test.go
+++ b/tools/http2_interop/http2interop_test.go
@@ -17,7 +17,7 @@ var (
serverHost = flag.String("server_host", "", "The host to test")
serverPort = flag.Int("server_port", 443, "The port to test")
useTls = flag.Bool("use_tls", true, "Should TLS tests be run")
- testCase = flag.String("test_case", "", "What test cases to run")
+ testCase = flag.String("test_case", "", "What test cases to run (tls, framing)")
// The rest of these are unused, but present to fulfill the client interface
serverHostOverride = flag.String("server_host_override", "", "Unused")
@@ -69,6 +69,9 @@ func (ctx *HTTP2InteropCtx) Close() error {
}
func TestShortPreface(t *testing.T) {
+ if *testCase != "framing" {
+ t.SkipNow()
+ }
ctx := InteropCtx(t)
for i := 0; i < len(Preface)-1; i++ {
if err := testShortPreface(ctx, Preface[:i]+"X"); err != io.EOF {
@@ -78,6 +81,9 @@ func TestShortPreface(t *testing.T) {
}
func TestUnknownFrameType(t *testing.T) {
+ if *testCase != "framing" {
+ t.SkipNow()
+ }
ctx := InteropCtx(t)
if err := testUnknownFrameType(ctx); err != nil {
t.Fatal(err)
@@ -86,7 +92,7 @@ func TestUnknownFrameType(t *testing.T) {
func TestTLSApplicationProtocol(t *testing.T) {
if *testCase != "tls" {
- return
+ t.SkipNow()
}
ctx := InteropCtx(t)
err := testTLSApplicationProtocol(ctx)
@@ -95,7 +101,7 @@ func TestTLSApplicationProtocol(t *testing.T) {
func TestTLSMaxVersion(t *testing.T) {
if *testCase != "tls" {
- return
+ t.SkipNow()
}
ctx := InteropCtx(t)
err := testTLSMaxVersion(ctx, tls.VersionTLS11)
@@ -106,7 +112,7 @@ func TestTLSMaxVersion(t *testing.T) {
func TestTLSBadCipherSuites(t *testing.T) {
if *testCase != "tls" {
- return
+ t.SkipNow()
}
ctx := InteropCtx(t)
err := testTLSBadCipherSuites(ctx)
@@ -114,6 +120,9 @@ func TestTLSBadCipherSuites(t *testing.T) {
}
func TestClientPrefaceWithStreamId(t *testing.T) {
+ if *testCase != "framing" {
+ t.SkipNow()
+ }
ctx := InteropCtx(t)
err := testClientPrefaceWithStreamId(ctx)
matchError(t, err, "EOF")
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index ee3cddddd9..b1fb657733 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -170,7 +170,7 @@ class Http2Client:
self.safename = str(self)
def client_args(self):
- return ['tools/http2_interop/http2_interop.test']
+ return ['tools/http2_interop/http2_interop.test', '-v']
def cloud_to_prod_env(self):
return {}
@@ -306,7 +306,7 @@ _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong',
_AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
'oauth2_auth_token', 'per_rpc_creds']
-_HTTP2_TEST_CASES = ["tls"]
+_HTTP2_TEST_CASES = ["tls", "framing"]
def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None):
"""Wraps given cmdline array to create 'docker run' cmdline from it."""
--
cgit v1.2.3
From 59096b404462742a769696e56510c7ea1bdc6946 Mon Sep 17 00:00:00 2001
From: Carl Mastrangelo
Date: Thu, 19 Nov 2015 12:54:01 -0800
Subject: fix flag
---
tools/run_tests/run_interop_tests.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'tools/run_tests/run_interop_tests.py')
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index b1fb657733..747ba4bd59 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -170,7 +170,7 @@ class Http2Client:
self.safename = str(self)
def client_args(self):
- return ['tools/http2_interop/http2_interop.test', '-v']
+ return ['tools/http2_interop/http2_interop.test', '-test.v']
def cloud_to_prod_env(self):
return {}
--
cgit v1.2.3
From 2d248a29f73be0cc9a6514afbe392ec0ed990485 Mon Sep 17 00:00:00 2001
From: Carl Mastrangelo
Date: Thu, 19 Nov 2015 13:09:52 -0800
Subject: Fix stdin on run_interop_tests
---
tools/run_tests/dockerjob.py | 3 +++
tools/run_tests/run_interop_tests.py | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
(limited to 'tools/run_tests/run_interop_tests.py')
diff --git a/tools/run_tests/dockerjob.py b/tools/run_tests/dockerjob.py
index 7d64222ba0..326c4faed9 100755
--- a/tools/run_tests/dockerjob.py
+++ b/tools/run_tests/dockerjob.py
@@ -47,6 +47,7 @@ def random_name(base_name):
def docker_kill(cid):
"""Kills a docker container. Returns True if successful."""
return subprocess.call(['docker','kill', str(cid)],
+ stdin=subprocess.PIPE,
stdout=_DEVNULL,
stderr=subprocess.STDOUT) == 0
@@ -78,6 +79,7 @@ def finish_jobs(jobs):
def image_exists(image):
"""Returns True if given docker image exists."""
return subprocess.call(['docker','inspect', image],
+ stdin=subprocess.PIPE,
stdout=_DEVNULL,
stderr=subprocess.STDOUT) == 0
@@ -88,6 +90,7 @@ def remove_image(image, skip_nonexistent=False, max_retries=10):
return True
for attempt in range(0, max_retries):
if subprocess.call(['docker','rmi', '-f', image],
+ stdin=subprocess.PIPE,
stdout=_DEVNULL,
stderr=subprocess.STDOUT) == 0:
return True
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index ee3cddddd9..37b8ab19f6 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -37,7 +37,6 @@ import jobset
import multiprocessing
import os
import report_utils
-import subprocess
import sys
import tempfile
import time
--
cgit v1.2.3