blob: aff3a6060f3ca445e93660430eb3688217ebf915 [file] [log] [blame]
#!/usr/bin/env vpython3
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittests for xcode_log_parser.py."""
import json
import mock
import os
import unittest
from test_result_util import TestStatus
import test_runner
import test_runner_test
import xcode_log_parser
OUTPUT_PATH = '/tmp/attempt_0'
XCRESULT_PATH = '/tmp/attempt_0.xcresult'
XCODE11_DICT = {
'path': '/Users/user1/Xcode.app',
'version': '11.0',
'build': '11M336w',
}
# A sample of json result when executing xcresulttool on .xcresult dir without
# --id. Some unused keys and values were removed.
XCRESULT_ROOT = """
{
"_type" : {
"_name" : "ActionsInvocationRecord"
},
"actions" : {
"_values" : [
{
"actionResult" : {
"_type" : {
"_name" : "ActionResult"
},
"diagnosticsRef" : {
"id" : {
"_value" : "DIAGNOSTICS_REF_ID"
}
},
"logRef" : {
"id" : {
"_value" : "0~6jr1GkZxoWVzWfcUNA5feff3l7g8fPHJ1rqKetCBa3QXhCGY74PnEuRwzktleMTFounMfCdDpSr1hRfhUGIUEQ=="
}
},
"testsRef" : {
"id" : {
"_value" : "0~iRbOkDnmtKVIvHSV2jkeuNcg4RDTUaCLZV7KijyxdCqvhqtp08MKxl0MwjBAPpjmruoI7qNHzBR1RJQAlANNHA=="
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
},
"testsCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "2"
},
"testsFailedCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "2"
}
}
}
}
]
},
"issues" : {
"testFailureSummaries" : {
"_values" : [
{
"documentLocationInCreatingWorkspace" : {
"url" : {
"_value" : "file:\/\/\/..\/..\/ios\/web\/shell\/test\/page_state_egtest.mm#CharacterRangeLen=0&EndingLineNumber=130&StartingLineNumber=130"
}
},
"message" : {
"_value": "Fail. Screenshots: {\\n\\"Failure\\": \\"path.png\\"\\n}"
},
"testCaseName" : {
"_value": "-[PageStateTestCase testZeroContentOffsetAfterLoad]"
}
}
]
}
},
"metrics" : {
"testsCount" : {
"_value" : "2"
},
"testsFailedCount" : {
"_value" : "1"
}
}
}"""
REF_ID = b"""
{
"actions": {
"_values": [{
"actionResult": {
"testsRef": {
"id": {
"_value": "REF_ID"
}
}
}
}]
}
}"""
# A sample of json result when executing xcresulttool on .xcresult dir with
# "testsRef" as --id input. Some unused keys and values were removed.
TESTS_REF = """
{
"summaries": {
"_values": [{
"testableSummaries": {
"_type": {
"_name": "Array"
},
"_values": [{
"tests": {
"_type": {
"_name": "Array"
},
"_values": [{
"identifier" : {
"_value" : "All tests"
},
"name" : {
"_value" : "All tests"
},
"subtests": {
"_values": [{
"identifier" : {
"_value" : "ios_web_shell_eg2tests_module.xctest"
},
"name" : {
"_value" : "ios_web_shell_eg2tests_module.xctest"
},
"subtests": {
"_values": [{
"identifier" : {
"_value" : "PageStateTestCase"
},
"name" : {
"_value" : "PageStateTestCase"
},
"subtests": {
"_values": [{
"testStatus": {
"_value": "Success"
},
"duration" : {
"_type" : {
"_name" : "Double"
},
"_value" : "35.38412606716156"
},
"identifier": {
"_value": "PageStateTestCase/testMethod1"
},
"name": {
"_value": "testMethod1"
}
},
{
"summaryRef": {
"id": {
"_value": "0~7Q_uAuUSJtx9gtHM08psXFm3g_xiTTg5bpdoDO88nMXo_iMwQTXpqlrlMe5AtkYmnZ7Ux5uEgAe83kJBfoIckw=="
}
},
"testStatus": {
"_value": "Failure"
},
"identifier": {
"_value": "PageStateTestCase\/testZeroContentOffsetAfterLoad"
},
"name": {
"_value": "testZeroContentOffsetAfterLoad"
}
},
{
"testStatus": {
"_value": "Expected Failure"
},
"duration" : {
"_type" : {
"_name" : "Double"
},
"_value" : "28.988606716156"
},
"identifier": {
"_value": "PageStateTestCase/testMethod2"
},
"name": {
"_value": "testMethod2"
}
},
{
"testStatus": {
"_value": "Skipped"
},
"duration" : {
"_type" : {
"_name" : "Double"
},
"_value" : "0.0606716156"
},
"identifier": {
"_value": "PageStateTestCase/testMethod3"
},
"name": {
"_value": "testMethod3"
}
}]
}
}]
}
}]
}
}]
}
}]
}
}]
}
}
"""
# A sample of json result when executing xcresulttool on .xcresult dir with
# a single test summaryRef id value as --id input. Some unused keys and values
# were removed.
SINGLE_TEST_SUMMARY_REF = """
{
"_type" : {
"_name" : "ActionTestSummary",
"_supertype" : {
"_name" : "ActionTestSummaryIdentifiableObject",
"_supertype" : {
"_name" : "ActionAbstractTestSummary"
}
}
},
"activitySummaries" : {
"_values" : [
{
"attachments" : {
"_values" : [
{
"filename" : {
"_value" : "Screenshot_25659115-F3E4-47AE-AA34-551C94333D7E.jpg"
},
"payloadRef" : {
"id" : {
"_value" : "SCREENSHOT_REF_ID_1"
}
}
}
]
},
"title" : {
"_value" : "Start Test at 2020-10-19 14:12:58.111"
}
},
{
"subactivities" : {
"_values" : [
{
"attachments" : {
"_values" : [
{
"filename" : {
"_value" : "Screenshot_23D95D0E-8B97-4F99-BE3C-A46EDE5999D7.jpg"
},
"payloadRef" : {
"id" : {
"_value" : "SCREENSHOT_REF_ID_2"
}
}
}
]
},
"subactivities" : {
"_values" : [
{
"subactivities" : {
"_values" : [
{
"attachments" : {
"_values" : [
{
"filename" : {
"_value" : "Crash_3F0A2B1C-7ADA-436E-A54C-D4C39B8411F8.crash"
},
"payloadRef" : {
"id" : {
"_value" : "CRASH_REF_ID_IN_ACTIVITY_SUMMARIES"
}
}
}
]
},
"title" : {
"_value" : "Wait for org.chromium.ios-web-shell-eg2tests to idle"
}
}
]
},
"title" : {
"_value" : "Activate org.chromium.ios-web-shell-eg2tests"
}
}
]
},
"title" : {
"_value" : "Open org.chromium.ios-web-shell-eg2tests"
}
}
]
},
"title" : {
"_value" : "Set Up"
}
},
{
"title" : {
"_value" : "Find the Target Application 'org.chromium.ios-web-shell-eg2tests'"
}
},
{
"attachments" : {
"_values" : [
{
"filename" : {
"_value" : "Screenshot_278BA84B-2196-4CCD-9D31-2C07DDDC9DFC.jpg"
},
"payloadRef" : {
"id" : {
"_value" : "SCREENSHOT_REF_ID_3"
}
}
}
]
},
"title" : {
"_value" : "Uncaught Exception at page_state_egtest.mm:131: \\nCannot scroll, the..."
}
},
{
"title" : {
"_value" : "Uncaught Exception: Immediately halt execution of testcase (EarlGreyInternalTestInterruptException)"
}
},
{
"title" : {
"_value" : "Tear Down"
}
}
]
},
"failureSummaries" : {
"_values" : [
{
"attachments" : {
"_values" : [
{
"filename" : {
"_value" : "kXCTAttachmentLegacyScreenImageData_1_6CED1FE5-96CA-47EA-9852-6FADED687262.jpeg"
},
"payloadRef" : {
"id" : {
"_value" : "SCREENSHOT_REF_ID_IN_FAILURE_SUMMARIES"
}
}
}
]
},
"fileName" : {
"_value" : "\/..\/..\/ios\/web\/shell\/test\/page_state_egtest.mm"
},
"lineNumber" : {
"_value" : "131"
},
"message" : {
"_value" : "Some logs."
}
},
{
"message" : {
"_value" : "Immediately halt execution of testcase (EarlGreyInternalTestInterruptException)"
}
}
]
},
"identifier" : {
"_value" : "PageStateTestCase\/testZeroContentOffsetAfterLoad"
},
"name" : {
"_value" : "testZeroContentOffsetAfterLoad"
},
"testStatus" : {
"_value" : "Failure"
}
}"""
def _xcresulttool_get_side_effect(xcresult_path, ref_id=None):
"""Side effect for _xcresulttool_get in Xcode11LogParser tested."""
if ref_id is None:
return XCRESULT_ROOT
if ref_id == 'testsRef':
return TESTS_REF
# Other situation in use cases of xcode_log_parser is asking for single test
# summary ref.
return SINGLE_TEST_SUMMARY_REF
class UtilMethodsTest(test_runner_test.TestCase):
"""Test case for utility methods not related with Parser class."""
def testParseTestsForInterruptedRun(self):
test_output = """
Test case '-[DownloadManagerTestCase testVisibleFileNameAndOpenInDownloads]' passed on 'Clone 2 of iPhone X 15.0 test simulator - ios_chrome_ui_eg2tests_module-Runner (34498)' (20.715 seconds)
Test case '-[SyncFakeServerTestCase testSyncDownloadBookmark]' passed on 'Clone 1 of iPhone X 15.0 test simulator - ios_chrome_ui_eg2tests_module-Runner (34249)' (14.880 seconds)
Random lines
t = 53.90s Tear Down
Test Case '-[LinkToTextTestCase testGenerateLinkForSimpleText]' failed (55.316 seconds).
t = nans Suite Tear Down
Test Suite 'LinkToTextTestCase' failed at 2021-06-15 07:13:17.406.
Executed 1 test, with 6 failures (6 unexpected) in 55.316 (55.338) seconds
Test Suite 'ios_chrome_ui_eg2tests_module.xctest' failed at 2021-06-15 07:13:17.407.
Executed 1 test, with 6 failures (6 unexpected) in 55.316 (55.340) seconds
Test Suite 'Selected tests' failed at 2021-06-15 07:13:17.408.
Executed 1 test, with 6 failures (6 unexpected) in 55.316 (55.342) seconds
"""
test_output_list = test_output.split('\n')
expected_passed = set([
'DownloadManagerTestCase/testVisibleFileNameAndOpenInDownloads',
'SyncFakeServerTestCase/testSyncDownloadBookmark'
])
expected_failed = set(['LinkToTextTestCase/testGenerateLinkForSimpleText'])
expected_failed_message = 'Test failed in interrupted(timedout) run.'
results = xcode_log_parser.parse_passed_failed_tests_for_interrupted_run(
test_output_list)
self.assertEqual(results.expected_tests(), expected_passed)
self.assertEqual(results.unexpected_tests(), expected_failed)
for result in results.test_results:
if result.name == 'LinkToTextTestCase/testGenerateLinkForSimpleText':
self.assertEqual(result.test_log, expected_failed_message)
class XCode11LogParserTest(test_runner_test.TestCase):
"""Test case to test Xcode11LogParser."""
def setUp(self):
super(XCode11LogParserTest, self).setUp()
self.mock(test_runner, 'get_current_xcode_info', lambda: XCODE11_DICT)
@mock.patch('xcode_util.version', autospec=True)
def testGetParser(self, mock_xcode_version):
mock_xcode_version.return_value = ('12.0', '12A7209')
self.assertEqual(xcode_log_parser.get_parser().__class__.__name__,
'Xcode11LogParser')
mock_xcode_version.return_value = ('11.4', '11E146')
self.assertEqual(xcode_log_parser.get_parser().__class__.__name__,
'Xcode11LogParser')
mock_xcode_version.return_value = ('10.3', '10G8')
self.assertEqual(xcode_log_parser.get_parser().__class__.__name__,
'XcodeLogParser')
@mock.patch('subprocess.check_output', autospec=True)
def testXcresulttoolGetRoot(self, mock_process):
mock_process.return_value = b'%JSON%'
xcode_log_parser.Xcode11LogParser()._xcresulttool_get('xcresult_path')
self.assertTrue(
os.path.join(XCODE11_DICT['path'], 'usr', 'bin') in os.environ['PATH'])
self.assertEqual(
['xcresulttool', 'get', '--format', 'json', '--path', 'xcresult_path'],
mock_process.mock_calls[0][1][0])
@mock.patch('subprocess.check_output', autospec=True)
def testXcresulttoolGetRef(self, mock_process):
mock_process.side_effect = [REF_ID, b'JSON']
xcode_log_parser.Xcode11LogParser()._xcresulttool_get('xcresult_path',
'testsRef')
self.assertEqual(
['xcresulttool', 'get', '--format', 'json', '--path', 'xcresult_path'],
mock_process.mock_calls[0][1][0])
self.assertEqual([
'xcresulttool', 'get', '--format', 'json', '--path', 'xcresult_path',
'--id', 'REF_ID'], mock_process.mock_calls[1][1][0])
def testXcresulttoolListFailedTests(self):
failure_message = (
'file:///../../ios/web/shell/test/page_state_egtest.mm#'
'CharacterRangeLen=0&EndingLineNumber=130&StartingLineNumber=130\n'
'Fail. Screenshots: {\n\"Failure\": \"path.png\"\n}')
expected = set(['PageStateTestCase/testZeroContentOffsetAfterLoad'])
results = xcode_log_parser.Xcode11LogParser()._list_of_failed_tests(
json.loads(XCRESULT_ROOT))
self.assertEqual(expected, results.failed_tests())
log = results.test_results[0].test_log
self.assertEqual(log, failure_message)
def testXcresulttoolListFailedTestsExclude(self):
excluded = set(['PageStateTestCase/testZeroContentOffsetAfterLoad'])
results = xcode_log_parser.Xcode11LogParser()._list_of_failed_tests(
json.loads(XCRESULT_ROOT), excluded=excluded)
self.assertEqual(set([]), results.all_test_names())
@mock.patch('xcode_log_parser.Xcode11LogParser._export_data')
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testGetTestStatuses(self, mock_xcresult, mock_export):
mock_xcresult.side_effect = _xcresulttool_get_side_effect
# self.assertEqual(test_result.test_log, lo
expected_failure_log = (
'Logs from "failureSummaries" in .xcresult:\n'
'file: /../../ios/web/shell/test/page_state_egtest.mm, line: 131\n'
'Some logs.\n'
'file: , line: \n'
'Immediately halt execution of testcase '
'(EarlGreyInternalTestInterruptException)\n')
expected_expected_tests = set([
'PageStateTestCase/testMethod1', 'PageStateTestCase/testMethod2',
'PageStateTestCase/testMethod3'
])
results = xcode_log_parser.Xcode11LogParser()._get_test_statuses(
OUTPUT_PATH)
self.assertEqual(expected_expected_tests, results.expected_tests())
seen_failed_test = False
for test_result in results.test_results:
if test_result.name == 'PageStateTestCase/testZeroContentOffsetAfterLoad':
seen_failed_test = True
self.assertEqual(test_result.test_log, expected_failure_log)
self.assertEqual(test_result.duration, None)
crash_file_name = (
'attempt_0_PageStateTestCase_testZeroContentOffsetAfterLoad_'
'Crash_3F0A2B1C-7ADA-436E-A54C-D4C39B8411F8.crash'
)
jpeg_file_name = (
'attempt_0_PageStateTestCase_testZeroContentOffsetAfterLoad'
'_kXCTAttachmentLegacyScreenImageData_1'
'_6CED1FE5-96CA-47EA-9852-6FADED687262.jpeg')
self.assertDictEqual(
{
crash_file_name: '/tmp/%s' % crash_file_name,
jpeg_file_name: '/tmp/%s' % jpeg_file_name,
}, test_result.attachments)
if test_result.name == 'PageStateTestCase/testMethod1':
self.assertEqual(test_result.duration, 35384)
if test_result.name == 'PageStateTestCase/testMethod2':
self.assertEqual(test_result.duration, 28988)
if test_result.name == 'PageStateTestCase/testMethod3':
self.assertEqual(test_result.duration, 60)
self.assertTrue(seen_failed_test)
@mock.patch('file_util.zip_and_remove_folder')
@mock.patch('xcode_log_parser.Xcode11LogParser._extract_artifacts_for_test')
@mock.patch('xcode_log_parser.Xcode11LogParser.export_diagnostic_data')
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testCollectTestTesults(self, mock_root, mock_exist_file, *args):
expected_passed = set([
'PageStateTestCase/testMethod1', 'PageStateTestCase/testMethod2',
'PageStateTestCase/testMethod3'
])
expected_failed = set(['PageStateTestCase/testZeroContentOffsetAfterLoad'])
mock_root.side_effect = _xcresulttool_get_side_effect
mock_exist_file.return_value = True
results = xcode_log_parser.Xcode11LogParser().collect_test_results(
OUTPUT_PATH, [])
# Length ensures no duplicate results from |_get_test_statuses| and
# |_list_of_failed_tests|.
self.assertEqual(len(results.test_results), 4)
self.assertEqual(expected_passed, results.expected_tests())
self.assertEqual(expected_failed, results.unexpected_tests())
# Ensure format.
for test in results.test_results:
self.assertTrue(isinstance(test.name, str))
if test.status == TestStatus.FAIL:
self.assertTrue(isinstance(test.test_log, str))
@mock.patch('file_util.zip_and_remove_folder')
@mock.patch('xcode_log_parser.Xcode11LogParser.copy_artifacts')
@mock.patch('xcode_log_parser.Xcode11LogParser.export_diagnostic_data')
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testCollectTestsRanZeroTests(self, mock_root, mock_exist_file, *args):
metrics_json = '{"actions": {}}'
mock_root.return_value = metrics_json
mock_exist_file.return_value = True
results = xcode_log_parser.Xcode11LogParser().collect_test_results(
OUTPUT_PATH, [])
self.assertTrue(results.crashed)
self.assertEqual(results.crash_message, '0 tests executed!')
self.assertEqual(len(results.all_test_names()), 0)
@mock.patch('os.path.exists', autospec=True)
def testCollectTestsDidNotRun(self, mock_exist_file):
mock_exist_file.return_value = False
results = xcode_log_parser.Xcode11LogParser().collect_test_results(
OUTPUT_PATH, [])
self.assertTrue(results.crashed)
self.assertEqual(results.crash_message,
'/tmp/attempt_0 with staging data does not exist.\n')
self.assertEqual(len(results.all_test_names()), 0)
@mock.patch('os.path.exists', autospec=True)
def testCollectTestsInterruptedRun(self, mock_exist_file):
mock_exist_file.side_effect = [True, False]
results = xcode_log_parser.Xcode11LogParser().collect_test_results(
OUTPUT_PATH, [])
self.assertTrue(results.crashed)
self.assertEqual(
results.crash_message,
'/tmp/attempt_0.xcresult with test results does not exist.\n')
self.assertEqual(len(results.all_test_names()), 0)
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testCopyScreenshots(self, mock_xcresulttool_get, mock_path_exists,
mock_process):
mock_path_exists.return_value = True
mock_xcresulttool_get.side_effect = _xcresulttool_get_side_effect
xcode_log_parser.Xcode11LogParser().copy_artifacts(OUTPUT_PATH)
mock_process.assert_any_call([
'xcresulttool', 'export', '--type', 'file', '--id',
'SCREENSHOT_REF_ID_IN_FAILURE_SUMMARIES', '--path', XCRESULT_PATH,
'--output-path',
'/tmp/attempt_0_PageStateTestCase_testZeroContentOffsetAfterLoad'
'_kXCTAttachmentLegacyScreenImageData_1'
'_6CED1FE5-96CA-47EA-9852-6FADED687262.jpeg'
])
mock_process.assert_any_call([
'xcresulttool', 'export', '--type', 'file', '--id',
'CRASH_REF_ID_IN_ACTIVITY_SUMMARIES', '--path', XCRESULT_PATH,
'--output-path',
'/tmp/attempt_0_PageStateTestCase_testZeroContentOffsetAfterLoad'
'_Crash_3F0A2B1C-7ADA-436E-A54C-D4C39B8411F8.crash'
])
# Ensures screenshots in activitySummaries are not copied.
self.assertEqual(2, mock_process.call_count)
@mock.patch('file_util.zip_and_remove_folder')
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testExportDiagnosticData(self, mock_xcresulttool_get, mock_path_exists,
mock_process, _):
mock_path_exists.return_value = True
mock_xcresulttool_get.side_effect = _xcresulttool_get_side_effect
xcode_log_parser.Xcode11LogParser.export_diagnostic_data(OUTPUT_PATH)
mock_process.assert_called_with([
'xcresulttool', 'export', '--type', 'directory', '--id',
'DIAGNOSTICS_REF_ID', '--path', XCRESULT_PATH, '--output-path',
'/tmp/attempt_0.xcresult_diagnostic'
])
@mock.patch('file_util.zip_and_remove_folder')
@mock.patch('shutil.copy')
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
def testStdoutCopiedInExportDiagnosticData(self, mock_xcresulttool_get,
mock_path_exists, mock_process,
mock_copy, _):
output_path_in_test = 'test_data/attempt_0'
xcresult_path_in_test = 'test_data/attempt_0.xcresult'
mock_path_exists.return_value = True
mock_xcresulttool_get.side_effect = _xcresulttool_get_side_effect
xcode_log_parser.Xcode11LogParser.export_diagnostic_data(
output_path_in_test)
# os.walk() walks folders in unknown sequence. Use try-except blocks to
# assert that any of the 2 assertions is true.
try:
mock_copy.assert_any_call(
'test_data/attempt_0.xcresult_diagnostic/test_module-UUID/test_module-UUID1/StandardOutputAndStandardError.txt',
'test_data/attempt_0/../attempt_0_simulator#1_StandardOutputAndStandardError.txt'
)
except AssertionError:
mock_copy.assert_any_call(
'test_data/attempt_0.xcresult_diagnostic/test_module-UUID/test_module-UUID1/StandardOutputAndStandardError.txt',
'test_data/attempt_0/../attempt_0_simulator#0_StandardOutputAndStandardError.txt'
)
try:
mock_copy.assert_any_call(
'test_data/attempt_0.xcresult_diagnostic/test_module-UUID/test_module-UUID2/StandardOutputAndStandardError-org.chromium.gtest.ios-chrome-eg2tests.txt',
'test_data/attempt_0/../attempt_0_simulator#1_StandardOutputAndStandardError-org.chromium.gtest.ios-chrome-eg2tests.txt'
)
except AssertionError:
mock_copy.assert_any_call(
'test_data/attempt_0.xcresult_diagnostic/test_module-UUID/test_module-UUID2/StandardOutputAndStandardError-org.chromium.gtest.ios-chrome-eg2tests.txt',
'test_data/attempt_0/../attempt_0_simulator#0_StandardOutputAndStandardError-org.chromium.gtest.ios-chrome-eg2tests.txt'
)
@mock.patch('os.path.exists', autospec=True)
def testCollectTestResults_interruptedTests(self, mock_path_exists):
mock_path_exists.side_effect = [True, False]
output = [
'[09:03:42:INFO] Test case \'-[TestCase1 method1]\' passed on device.',
'[09:06:40:INFO] Test Case \'-[TestCase2 method1]\' passed on device.',
'[09:09:00:INFO] Test case \'-[TestCase2 method1]\' failed on device.',
'** BUILD INTERRUPTED **',
]
not_found_message = ['%s with test results does not exist.' % XCRESULT_PATH]
res = xcode_log_parser.Xcode11LogParser().collect_test_results(
OUTPUT_PATH, output)
self.assertTrue(res.crashed)
self.assertEqual('\n'.join(not_found_message + output), res.crash_message)
self.assertEqual(
set(['TestCase1/method1', 'TestCase2/method1']), res.expected_tests())
@mock.patch('file_util.zip_and_remove_folder')
@mock.patch('xcode_log_parser.Xcode11LogParser._extract_artifacts_for_test')
@mock.patch('xcode_log_parser.Xcode11LogParser.export_diagnostic_data')
@mock.patch('os.path.exists', autospec=True)
@mock.patch('xcode_log_parser.Xcode11LogParser._xcresulttool_get')
@mock.patch('xcode_log_parser.Xcode11LogParser._list_of_failed_tests')
def testArtifactsDiagnosticLogsExportedInCollectTestTesults(
self, mock_get_failed_tests, mock_root, mock_exist_file,
mock_export_diagnostic_data, mock_extract_artifacts, mock_zip):
mock_root.side_effect = _xcresulttool_get_side_effect
mock_exist_file.return_value = True
xcode_log_parser.Xcode11LogParser().collect_test_results(OUTPUT_PATH, [])
mock_export_diagnostic_data.assert_called_with(OUTPUT_PATH)
mock_extract_artifacts.assert_called()
if __name__ == '__main__':
unittest.main()