Preliminary changes to git cl and presubmit_support
Added an rdb wrapper and use it to time CheckChangeOn{Commit, Upload} from every PRESUBMIT.py file, then reports the results to ResultSink. Bug: http://crbug.com/1107588 Change-Id: I9bc8a18ba615a76f3e0611eae5b2c4adc5924276 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2242097 Commit-Queue: Saagar Sanghavi <saagarsanghavi@google.com> Reviewed-by: Edward Lesmes <ehmaldonado@chromium.org> Reviewed-by: Garrett Beaty <gbeaty@chromium.org>changes/97/2242097/34
parent
b99e61c58a
commit
9949ab7a4b
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env vpython
|
||||
# Copyright (c) 2020 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import time
|
||||
|
||||
# Constants describing TestStatus for ResultDB
|
||||
STATUS_PASS = 'PASS'
|
||||
STATUS_FAIL = 'FAIL'
|
||||
STATUS_CRASH = 'CRASH'
|
||||
STATUS_ABORT = 'ABORT'
|
||||
STATUS_SKIP = 'SKIP'
|
||||
|
||||
class ResultSinkStatus(object):
|
||||
def __init__(self):
|
||||
self.status = STATUS_PASS
|
||||
|
||||
@contextlib.contextmanager
|
||||
def setup_rdb(function_name, rel_path):
|
||||
"""Context Manager function for ResultDB reporting.
|
||||
|
||||
Args:
|
||||
function_name (str): The name of the function we are about to run.
|
||||
rel_path (str): The relative path from the root of the repository to the
|
||||
directory defining the check being executed.
|
||||
"""
|
||||
sink = None
|
||||
if 'LUCI_CONTEXT' in os.environ:
|
||||
with open(os.environ['LUCI_CONTEXT']) as f:
|
||||
j = json.load(f)
|
||||
if 'result_sink' in j:
|
||||
sink = j['result_sink']
|
||||
|
||||
my_status = ResultSinkStatus()
|
||||
start_time = time.time()
|
||||
try:
|
||||
yield my_status
|
||||
except Exception:
|
||||
my_status.status = STATUS_FAIL
|
||||
raise
|
||||
finally:
|
||||
end_time = time.time()
|
||||
elapsed_time = end_time - start_time
|
||||
if sink != None:
|
||||
tr = {
|
||||
'testId': '{0}/:{1}'.format(rel_path, function_name),
|
||||
'status': my_status.status,
|
||||
'expected': (my_status.status == STATUS_PASS),
|
||||
'duration': '{:.9f}s'.format(elapsed_time)
|
||||
}
|
||||
requests.post(
|
||||
url='http://{0}/prpc/luci.resultsink.v1.Sink/ReportTestResults'
|
||||
.format(sink['address']),
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'ResultSink {0}'.format(sink['auth_token'])
|
||||
},
|
||||
data=json.dumps({'testResults': [tr]})
|
||||
)
|
@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env vpython3
|
||||
# Copyright (c) 2020 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Unit tests for rdb_wrapper.py"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
|
||||
if sys.version_info.major == 2:
|
||||
import mock
|
||||
BUILTIN_OPEN = '__builtin__.open'
|
||||
else:
|
||||
from unittest import mock
|
||||
BUILTIN_OPEN = 'builtins.open'
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
import rdb_wrapper
|
||||
|
||||
class TestSetupRDB(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSetupRDB, self).setUp()
|
||||
mock.patch(BUILTIN_OPEN, mock.mock_open(read_data =
|
||||
'''{"result_sink":{"address": "fakeAddr","auth_token" : "p@$$w0rD"}}''')
|
||||
).start()
|
||||
mock.patch('os.environ', {'LUCI_CONTEXT': 'dummy_file.txt'}).start()
|
||||
mock.patch('requests.post').start()
|
||||
mock.patch('time.time', side_effect=[1.0, 2.0, 3.0, 4.0, 5.0]).start()
|
||||
|
||||
def test_setup_rdb(self):
|
||||
with rdb_wrapper.setup_rdb("_foobar", './my/folder') as my_status_obj:
|
||||
self.assertEqual(my_status_obj.status, rdb_wrapper.STATUS_PASS)
|
||||
my_status_obj.status = rdb_wrapper.STATUS_FAIL
|
||||
|
||||
expectedTr = {
|
||||
'testId' : './my/folder/:_foobar',
|
||||
'status' : rdb_wrapper.STATUS_FAIL,
|
||||
'expected': False,
|
||||
'duration': '1.000000000s'
|
||||
}
|
||||
|
||||
requests.post.assert_called_once_with(
|
||||
url='http://fakeAddr/prpc/luci.resultsink.v1.Sink/ReportTestResults',
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'ResultSink p@$$w0rD'
|
||||
},
|
||||
data=json.dumps({'testResults': [expectedTr]})
|
||||
)
|
||||
|
||||
def test_setup_rdb_exception(self):
|
||||
with self.assertRaises(Exception):
|
||||
with rdb_wrapper.setup_rdb("_foobar", './my/folder'):
|
||||
raise Exception("Generic Error")
|
||||
|
||||
expectedTr = {
|
||||
'testId': './my/folder/:_foobar',
|
||||
'status': rdb_wrapper.STATUS_FAIL,
|
||||
'expected': False,
|
||||
'duration': '1.000000000s'
|
||||
}
|
||||
|
||||
requests.post.assert_called_once_with(
|
||||
url='http://fakeAddr/prpc/luci.resultsink.v1.Sink/ReportTestResults',
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'ResultSink p@$$w0rD'
|
||||
},
|
||||
data=json.dumps({'testResults': [expectedTr]})
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG if '-v' in sys.argv else logging.ERROR)
|
||||
unittest.main()
|
Loading…
Reference in New Issue