Commit 7e19a18e authored by Zhaoyang Li's avatar Zhaoyang Li Committed by Commit Bot

[iOS][test runner] Reuse connection when reporting to result sink.

Use the post method from requests.Session so connection can be reused,
saving reporting time and potentially fix a connection error.

Added a finalize method to StdJson class, to close the connection after
reporting all results.

Bug: 1136998
Change-Id: I7e5c5e40b700655f4ac32ca8f84813c9b35cce5d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521514Reviewed-by: default avatarJustin Cohen <justincohen@chromium.org>
Reviewed-by: default avatarNodir Turakulov <nodir@chromium.org>
Commit-Queue: Zhaoyang Li <zhaoyangli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826653}
parent 26b0eea6
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import atexit
import base64
import cgi
import json
......@@ -100,6 +101,17 @@ class ResultSinkClient(object):
'Accept': 'application/json',
'Authorization': 'ResultSink %s' % self.sink['auth_token'],
}
self._session = requests.Session()
# Ensure session is closed at exit.
atexit.register(self.close)
def close(self):
"""Closes the connection to result sink server."""
if not self.sink:
return
LOGGER.info('Closing connection with result sink server.')
self._session.close()
def post(self, test_result):
"""Posts single test result to server.
......@@ -111,7 +123,7 @@ class ResultSinkClient(object):
if not self.sink:
return
res = requests.post(
res = self._session.post(
url=self.url,
headers=self.headers,
data=json.dumps({'testResults': [test_result]}),
......
......@@ -3,11 +3,32 @@
# found in the LICENSE file.
import base64
import json
import mock
import requests
import unittest
import result_sink_util
SINK_ADDRESS = 'sink/address'
SINK_POST_URL = 'http://%s/prpc/luci.resultsink.v1.Sink/ReportTestResults' % SINK_ADDRESS
AUTH_TOKEN = 'some_sink_token'
LUCI_CONTEXT_FILE_DATA = """
{
"result_sink": {
"address": "%s",
"auth_token": "%s"
}
}
""" % (SINK_ADDRESS, AUTH_TOKEN)
HEADERS = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'ResultSink %s' % AUTH_TOKEN
}
class UnitTest(unittest.TestCase):
def test_compose_test_result(self):
......@@ -100,6 +121,43 @@ class UnitTest(unittest.TestCase):
tags=[('disabled_test', 'true')])
self.assertEqual(test_result, expected)
@mock.patch.object(requests.Session, 'post')
@mock.patch('%s.open' % 'result_sink_util',
mock.mock_open(read_data=LUCI_CONTEXT_FILE_DATA))
@mock.patch('os.environ.get', return_value='filename')
def test_post(self, mock_open_file, mock_session_post):
test_result = {
'testId': 'TestCase/testSomething',
'status': 'SKIP',
'expected': True,
'tags': [{
'key': 'disabled_test',
'value': 'true',
}]
}
client = result_sink_util.ResultSinkClient()
client.post(test_result)
mock_session_post.assert_called_with(
url=SINK_POST_URL,
headers=HEADERS,
data=json.dumps({'testResults': [test_result]}))
@mock.patch.object(requests.Session, 'close')
@mock.patch.object(requests.Session, 'post')
@mock.patch('%s.open' % 'result_sink_util',
mock.mock_open(read_data=LUCI_CONTEXT_FILE_DATA))
@mock.patch('os.environ.get', return_value='filename')
def test_close(self, mock_open_file, mock_session_post, mock_session_close):
client = result_sink_util.ResultSinkClient()
client.post({'some': 'result'})
mock_session_post.assert_called()
client.close()
mock_session_close.assert_called()
if __name__ == '__main__':
unittest.main()
......@@ -42,6 +42,11 @@ class StdJson():
return test
def finalize(self):
"""Teardown and finalizing tasks needed after all results are reported."""
LOGGER.info('Finalizing in standard json util.')
self.result_sink.close()
def mark_passed(self, test, flaky=False):
"""Sets test as passed
......
......@@ -670,6 +670,7 @@ class TestRunner(object):
retry_results[test] = retry_result
output.mark_all_skipped(disabled)
output.finalize()
# Build test_results.json.
# Check if if any of the retries crashed in addition to the original run.
......
......@@ -462,6 +462,7 @@ class SimulatorParallelTestRunner(test_runner.SimulatorTestRunner):
output.mark_passed(test)
output.mark_all_skipped(self.logs['disabled tests'])
output.finalize()
self.test_results['tests'] = output.tests
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment