blob: af614549f5cb74fde882c27a69443ba130d297c8 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2019, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unittest for atest_execution_info."""
import os
import pathlib
import time
import unittest
from unittest.mock import patch
from atest import arg_parser
from atest import atest_execution_info as aei
from atest import constants
from atest import result_reporter
from atest.metrics import metrics
from atest.test_runners import test_runner_base
from pyfakefs import fake_filesystem_unittest
RESULT_TEST_TEMPLATE = test_runner_base.TestResult(
runner_name='someRunner',
group_name='someModule',
test_name='someClassName#sostName',
status=test_runner_base.PASSED_STATUS,
details=None,
test_count=1,
test_time='(10ms)',
runner_total=None,
group_total=2,
additional_info={},
test_run_name='com.android.UnitTests',
)
class CopyBuildTraceToLogsTests(fake_filesystem_unittest.TestCase):
def setUp(self):
super().setUp()
self.setUpPyfakefs()
self.fs.create_dir(constants.ATEST_RESULT_ROOT)
def test_copy_build_artifacts_to_log_dir_new_trace_copy(self):
start_time = 10
log_path = pathlib.Path('/logs')
self.fs.create_dir(log_path)
out_path = pathlib.Path('/out')
build_trace_path = out_path / 'build.trace'
self.fs.create_file(build_trace_path)
# Set the trace file's mtime greater than start time
os.utime(build_trace_path, (20, 20))
end_time = 30
aei.AtestExecutionInfo._copy_build_artifacts_to_log_dir(
start_time, end_time, out_path, log_path, 'build.trace'
)
self.assertTrue(
self._is_dir_contains_files_with_prefix(log_path, 'build.trace')
)
def test_copy_build_artifacts_to_log_dir_old_trace_does_not_copy(self):
start_time = 10
log_path = pathlib.Path('/logs')
self.fs.create_dir(log_path)
out_path = pathlib.Path('/out')
build_trace_path = out_path / 'build.trace'
self.fs.create_file(build_trace_path)
# Set the trace file's mtime smaller than start time
os.utime(build_trace_path, (5, 5))
end_time = 30
aei.AtestExecutionInfo._copy_build_artifacts_to_log_dir(
start_time, end_time, out_path, log_path, 'build.trace'
)
self.assertFalse(
self._is_dir_contains_files_with_prefix(log_path, 'build.trace')
)
def test_copy_multiple_build_trace_to_log_dir(self):
start_time = 10
log_path = pathlib.Path('/logs')
self.fs.create_dir(log_path)
out_path = pathlib.Path('/out')
build_trace_path1 = out_path / 'build.trace.1.gz'
build_trace_path2 = out_path / 'build.trace.2.gz'
self.fs.create_file(build_trace_path1)
self.fs.create_file(build_trace_path2)
# Set the trace file's mtime greater than start time
os.utime(build_trace_path1, (20, 20))
os.utime(build_trace_path2, (20, 20))
end_time = 30
aei.AtestExecutionInfo._copy_build_artifacts_to_log_dir(
start_time, end_time, out_path, log_path, 'build.trace'
)
self.assertTrue(
self._is_dir_contains_files_with_prefix(log_path, 'build.trace.1.gz')
)
self.assertTrue(
self._is_dir_contains_files_with_prefix(log_path, 'build.trace.2.gz')
)
def _is_dir_contains_files_with_prefix(
self, dir: pathlib.Path, prefix: str
) -> bool:
for file in dir.iterdir():
if file.is_file() and file.name.startswith(prefix):
return True
return False
# pylint: disable=protected-access
class AtestExecutionInfoUnittests(unittest.TestCase):
"""Unit tests for atest_execution_info.py"""
@patch('atest.metrics.metrics.is_internal_user', return_value=False)
def test_create_bug_report_url_is_external_user_return_empty(self, _):
url = aei.AtestExecutionInfo._create_bug_report_url()
self.assertFalse(url)
@patch('atest.metrics.metrics.is_internal_user', return_value=True)
def test_create_bug_report_url_is_internal_user_return_url(self, _):
url = aei.AtestExecutionInfo._create_bug_report_url()
self.assertTrue(url)
@patch('atest.metrics.metrics.is_internal_user', return_value=True)
@patch('atest.logstorage.log_uploader.is_uploading_logs', return_value=True)
def test_create_bug_report_url_is_uploading_logs_use_contains_run_id(
self, _, __
):
url = aei.AtestExecutionInfo._create_bug_report_url()
self.assertIn(metrics.get_run_id(), url)
@patch('atest.metrics.metrics.is_internal_user', return_value=True)
@patch('atest.logstorage.log_uploader.is_uploading_logs', return_value=False)
def test_create_bug_report_url_is_not_uploading_logs_use_contains_run_id(
self, _, __
):
url = aei.AtestExecutionInfo._create_bug_report_url()
self.assertNotIn(metrics.get_run_id(), url)
def test_arrange_test_result_one_module(self):
"""Test _arrange_test_result method with only one module."""
pass_1 = self._create_test_result(status=test_runner_base.PASSED_STATUS)
pass_2 = self._create_test_result(status=test_runner_base.PASSED_STATUS)
pass_3 = self._create_test_result(status=test_runner_base.PASSED_STATUS)
fail_1 = self._create_test_result(status=test_runner_base.FAILED_STATUS)
fail_2 = self._create_test_result(status=test_runner_base.FAILED_STATUS)
ignore_1 = self._create_test_result(status=test_runner_base.IGNORED_STATUS)
reporter_1 = result_reporter.ResultReporter()
reporter_1.all_test_results.extend([pass_1, pass_2, pass_3])
reporter_2 = result_reporter.ResultReporter()
reporter_2.all_test_results.extend([fail_1, fail_2, ignore_1])
info_dict = {}
aei.AtestExecutionInfo._arrange_test_result(
info_dict, [reporter_1, reporter_2]
)
expect_summary = {
aei._STATUS_IGNORED_KEY: 1,
aei._STATUS_FAILED_KEY: 2,
aei._STATUS_PASSED_KEY: 3,
}
self.assertEqual(expect_summary, info_dict[aei._TOTAL_SUMMARY_KEY])
def test_arrange_test_result_multi_module(self):
"""Test _arrange_test_result method with multi module."""
group_a_pass_1 = self._create_test_result(
group_name='grpup_a', status=test_runner_base.PASSED_STATUS
)
group_b_pass_1 = self._create_test_result(
group_name='grpup_b', status=test_runner_base.PASSED_STATUS
)
group_c_pass_1 = self._create_test_result(
group_name='grpup_c', status=test_runner_base.PASSED_STATUS
)
group_b_fail_1 = self._create_test_result(
group_name='grpup_b', status=test_runner_base.FAILED_STATUS
)
group_c_fail_1 = self._create_test_result(
group_name='grpup_c', status=test_runner_base.FAILED_STATUS
)
group_c_ignore_1 = self._create_test_result(
group_name='grpup_c', status=test_runner_base.IGNORED_STATUS
)
reporter_1 = result_reporter.ResultReporter()
reporter_1.all_test_results.extend(
[group_a_pass_1, group_b_pass_1, group_c_pass_1]
)
reporter_2 = result_reporter.ResultReporter()
reporter_2.all_test_results.extend(
[group_b_fail_1, group_c_fail_1, group_c_ignore_1]
)
info_dict = {}
aei.AtestExecutionInfo._arrange_test_result(
info_dict, [reporter_1, reporter_2]
)
expect_group_a_summary = {
aei._STATUS_IGNORED_KEY: 0,
aei._STATUS_FAILED_KEY: 0,
aei._STATUS_PASSED_KEY: 1,
}
self.assertEqual(
expect_group_a_summary,
info_dict[aei._TEST_RUNNER_KEY]['someRunner']['grpup_a'][
aei._SUMMARY_KEY
],
)
expect_group_b_summary = {
aei._STATUS_IGNORED_KEY: 0,
aei._STATUS_FAILED_KEY: 1,
aei._STATUS_PASSED_KEY: 1,
}
self.assertEqual(
expect_group_b_summary,
info_dict[aei._TEST_RUNNER_KEY]['someRunner']['grpup_b'][
aei._SUMMARY_KEY
],
)
expect_group_c_summary = {
aei._STATUS_IGNORED_KEY: 1,
aei._STATUS_FAILED_KEY: 1,
aei._STATUS_PASSED_KEY: 1,
}
self.assertEqual(
expect_group_c_summary,
info_dict[aei._TEST_RUNNER_KEY]['someRunner']['grpup_c'][
aei._SUMMARY_KEY
],
)
expect_total_summary = {
aei._STATUS_IGNORED_KEY: 1,
aei._STATUS_FAILED_KEY: 2,
aei._STATUS_PASSED_KEY: 3,
}
self.assertEqual(expect_total_summary, info_dict[aei._TOTAL_SUMMARY_KEY])
def test_preparation_time(self):
"""Test preparation_time method."""
start_time = time.time()
aei.PREPARE_END_TIME = None
self.assertTrue(aei.preparation_time(start_time) is None)
aei.PREPARE_END_TIME = time.time()
self.assertFalse(aei.preparation_time(start_time) is None)
def test_arrange_test_result_multi_runner(self):
"""Test _arrange_test_result method with multi runner."""
runner_a_pass_1 = self._create_test_result(
runner_name='runner_a', status=test_runner_base.PASSED_STATUS
)
runner_a_pass_2 = self._create_test_result(
runner_name='runner_a', status=test_runner_base.PASSED_STATUS
)
runner_a_pass_3 = self._create_test_result(
runner_name='runner_a', status=test_runner_base.PASSED_STATUS
)
runner_b_fail_1 = self._create_test_result(
runner_name='runner_b', status=test_runner_base.FAILED_STATUS
)
runner_b_fail_2 = self._create_test_result(
runner_name='runner_b', status=test_runner_base.FAILED_STATUS
)
runner_b_ignore_1 = self._create_test_result(
runner_name='runner_b', status=test_runner_base.IGNORED_STATUS
)
reporter_1 = result_reporter.ResultReporter()
reporter_1.all_test_results.extend(
[runner_a_pass_1, runner_a_pass_2, runner_a_pass_3]
)
reporter_2 = result_reporter.ResultReporter()
reporter_2.all_test_results.extend(
[runner_b_fail_1, runner_b_fail_2, runner_b_ignore_1]
)
info_dict = {}
aei.AtestExecutionInfo._arrange_test_result(
info_dict, [reporter_1, reporter_2]
)
expect_group_a_summary = {
aei._STATUS_IGNORED_KEY: 0,
aei._STATUS_FAILED_KEY: 0,
aei._STATUS_PASSED_KEY: 3,
}
self.assertEqual(
expect_group_a_summary,
info_dict[aei._TEST_RUNNER_KEY]['runner_a']['someModule'][
aei._SUMMARY_KEY
],
)
expect_group_b_summary = {
aei._STATUS_IGNORED_KEY: 1,
aei._STATUS_FAILED_KEY: 2,
aei._STATUS_PASSED_KEY: 0,
}
self.assertEqual(
expect_group_b_summary,
info_dict[aei._TEST_RUNNER_KEY]['runner_b']['someModule'][
aei._SUMMARY_KEY
],
)
expect_total_summary = {
aei._STATUS_IGNORED_KEY: 1,
aei._STATUS_FAILED_KEY: 2,
aei._STATUS_PASSED_KEY: 3,
}
self.assertEqual(expect_total_summary, info_dict[aei._TOTAL_SUMMARY_KEY])
def _create_test_result(self, **kwargs):
"""A Helper to create TestResult"""
test_info = test_runner_base.TestResult(**RESULT_TEST_TEMPLATE._asdict())
return test_info._replace(**kwargs)
if __name__ == '__main__':
unittest.main()