blob: 839f0a2c6cc0957dbcf52d8dd7df39759836a9d7 [file] [log] [blame]
# Copyright (C) 2019 Apple Inc. 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
from webkitcorepy import BytesIO
import json
import requests
import sys
import time
import unittest
try:
from collections.abc import Iterable, Mapping
except ImportError:
from collections import Iterable, Mapping
from webkitpy.results.upload import Upload
from webkitpy.thirdparty import mock
if sys.version_info > (3, 0):
basestring = str
class UploadTest(unittest.TestCase):
class Options(object):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
class MockResponse(object):
def __init__(self, status_code=200, text=''):
self.status_code = status_code
self.text = text
def json(self):
return json.loads(self.text)
@staticmethod
def normalize(data):
if isinstance(data, basestring):
return str(data)
elif isinstance(data, Mapping):
return dict(map(UploadTest.normalize, data.items()))
elif isinstance(data, Iterable):
return type(data)(map(UploadTest.normalize, data))
return data
@staticmethod
def raise_requests_ConnectionError():
raise requests.exceptions.ConnectionError()
def test_encoding(self):
start_time, end_time = time.time() - 3, time.time()
upload = Upload(
suite='webkitpy-tests',
configuration=Upload.create_configuration(
platform='mac',
version='10.13.0',
version_name='High Sierra',
architecture='x86_64',
sdk='17A405',
),
details=Upload.create_details(link='https://webkit.org'),
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
run_stats=Upload.create_run_stats(
start_time=start_time,
end_time=end_time,
tests_skipped=0,
),
results={
'webkitpy.test1': {},
'webkitpy.test2': Upload.create_test_result(expected=Upload.Expectations.PASS, actual=Upload.Expectations.FAIL),
},
)
generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))
self.assertEqual(generated_dict['version'], 0)
self.assertEqual(generated_dict['suite'], 'webkitpy-tests')
self.assertEqual(generated_dict['configuration'], self.normalize(dict(
platform='mac',
is_simulator=False,
version='10.13.0',
version_name='High Sierra',
architecture='x86_64',
sdk='17A405',
)))
self.assertEqual(generated_dict['commits'], [dict(
repository_id='webkit',
id='5',
branch='trunk',
)])
self.assertEqual(generated_dict['test_results']['details'], self.normalize(dict(link='https://webkit.org')))
self.assertEqual(generated_dict['test_results']['run_stats'], self.normalize(dict(
start_time=start_time,
end_time=end_time,
tests_skipped=0,
)))
self.assertEqual(generated_dict['test_results']['results'], self.normalize({
'webkitpy.test1': {},
'webkitpy.test2': Upload.create_test_result(expected=Upload.Expectations.PASS, actual=Upload.Expectations.FAIL),
}))
def test_upload(self):
upload = Upload(
suite='webkitpy-tests',
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
)
with mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.MockResponse()):
self.assertTrue(upload.upload('https://results.webkit.org', log_line_func=lambda _: None))
with mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.raise_requests_ConnectionError()):
lines = []
self.assertFalse(upload.upload('https://results.webkit.org', log_line_func=lambda line: lines.append(line)))
self.assertEqual([' ' * 4 + 'Failed to upload to https://results.webkit.org, results server not online'], lines)
mock_404 = mock.patch('requests.post', new=lambda url, headers={}, data={}, verify=True: self.MockResponse(
status_code=404,
text=json.dumps(dict(description='No such address')),
))
with mock_404:
self.assertFalse(upload.upload('https://results.webkit.org', log_line_func=lambda _: None))
def test_packed_test(self):
upload = Upload(
suite='webkitpy-tests',
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
results={
'dir1/sub-dir1/test1': Upload.create_test_result(actual=Upload.Expectations.FAIL),
'dir1/sub-dir1/test2': Upload.create_test_result(actual=Upload.Expectations.TIMEOUT),
'dir1/sub-dir2/test3': {},
'dir1/sub-dir2/test4': {},
'dir2/sub-dir3/test5': {},
'dir2/test6': {},
}
)
generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))
self.assertEqual(generated_dict['test_results']['results'], self.normalize({
'dir1': {
'sub-dir1': {
'test1': {'actual': Upload.Expectations.FAIL},
'test2': {'actual': Upload.Expectations.TIMEOUT},
}, 'sub-dir2': {
'test3': {},
'test4': {},
}
}, 'dir2': {
'sub-dir3': {'test5': {}},
'test6': {},
},
}))
def test_no_suite(self):
upload = Upload(
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
)
with self.assertRaises(ValueError):
json.dumps(upload, cls=Upload.Encoder)
def test_no_commits(self):
upload = Upload(
suite='webkitpy-tests',
)
with self.assertRaises(ValueError):
json.dumps(upload, cls=Upload.Encoder)
def test_buildbot(self):
upload = Upload(
suite='webkitpy-tests',
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
details=Upload.create_details(options=self.Options(
buildbot_master='webkit.org',
builder_name='Queue-1',
build_number=1,
)))
with self.assertRaises(ValueError):
json.dumps(upload, cls=Upload.Encoder)
upload.details['buildbot-worker'] = 'bot123'
generated_dict = self.normalize(json.loads(json.dumps(upload, cls=Upload.Encoder)))
self.assertEqual(generated_dict['test_results']['details'], self.normalize({
'buildbot-master': 'webkit.org',
'builder-name': 'Queue-1',
'build-number': 1,
'buildbot-worker': 'bot123',
}))
def test_archive_upload(self):
upload = Upload(
suite='webkitpy-tests',
commits=[Upload.create_commit(
repository_id='webkit',
id='5',
branch='trunk',
)],
)
with mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse()):
self.assertTrue(upload.upload_archive('https://results.webkit.org', archive=BytesIO(b'content'), log_line_func=lambda _: None))
with mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.raise_requests_ConnectionError()):
lines = []
self.assertTrue(upload.upload_archive('https://results.webkit.org', archive=BytesIO(b'content'), log_line_func=lambda line: lines.append(line)))
self.assertEqual([
' ' * 4 + 'Failed to upload test archive to https://results.webkit.org, results server dropped connection, likely due to archive size (0.0 MB).',
' ' * 4 + 'This error is not fatal, continuing'
], lines)
mock_404 = mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse(
status_code=404,
text=json.dumps(dict(description='No such address')),
))
with mock_404:
lines = []
self.assertFalse(upload.upload_archive('https://results.webkit.org', archive='content', log_line_func=lambda line: lines.append(line)))
self.assertEqual([
' ' * 4 + 'Error uploading archive to https://results.webkit.org',
' ' * 8 + 'No such address',
], lines)
mock_413 = mock.patch('requests.post', new=lambda url, headers={}, data={}, files={}, verify=True: self.MockResponse(
status_code=413,
text=json.dumps(dict(description='Request Entity Too Large')),
))
with mock_413:
lines = []
self.assertTrue(upload.upload_archive('https://results.webkit.org', archive='content', log_line_func=lambda line: lines.append(line)))
self.assertEqual([
' ' * 4 + 'Upload to https://results.webkit.org failed:',
' ' * 8 + 'Request Entity Too Large',
' ' * 4 + 'This error is not fatal, continuing',
], lines)