blob: 7476f175e1ecf6de50574cabbe13fd26b4bed8f7 [file]
#!/usr/bin/env python3
#
# Copyright 2024, 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.
"""Integration tests to make sure selected test archetypes works in atest."""
from dataclasses import dataclass
from typing import Callable
import atest_integration_test
class DevicelessJavaTestHostTest(atest_integration_test.AtestTestCase):
_TARGET_NAME = 'deviceless_java_test_host'
def test_passed_failed_counts(self):
_run_and_verify(
self,
atest_command=self._TARGET_NAME + ' --no-bazel-mode --host',
is_device_required=False,
verifiers=_create_pass_fail_ignore_verifiers(
expected_passed_count=2,
expected_failed_count=1,
expected_ignored_count=0,
)
+ _create_elapsed_time_verifiers(max_sec=10),
)
class DevicelessPythonTestHostTest(atest_integration_test.AtestTestCase):
_TARGET_NAME = 'deviceless_python_test_host'
def test_passed_failed_counts(self):
_run_and_verify(
self,
atest_command=self._TARGET_NAME + ' --no-bazel-mode --host',
is_device_required=False,
verifiers=_create_pass_fail_ignore_verifiers(
expected_passed_count=2,
expected_failed_count=1,
expected_ignored_count=0,
)
+ _create_elapsed_time_verifiers(max_sec=10),
)
class DeviceAndroidTestTest(atest_integration_test.AtestTestCase):
def test_passed_failed_counts(self):
_run_and_verify(
self,
atest_command='device_android_test',
is_device_required=True,
verifiers=_create_pass_fail_ignore_verifiers(
expected_passed_count=2,
expected_failed_count=1,
expected_ignored_count=0,
)
+ _create_elapsed_time_verifiers(max_sec=20),
)
def test_instrumentation_early_exit_shows_useful_output(self):
verifiers = [
_Verifier(
lambda test_case, result: test_case.assertIn(
'instrumentation app process died',
result.get_stdout(),
),
'process_died',
),
_Verifier(
lambda test_case, result: test_case.assertNotIn(
'Traceback (most recent call last)', result.get_stdout()
),
'no_traceback',
),
]
_run_and_verify(
self,
atest_command='device_android_test_non_starting',
is_device_required=True,
verifiers=verifiers,
)
class DeviceCcTestTest(atest_integration_test.AtestTestCase):
_TARGET_NAME = 'device_cc_test'
def test_passed_failed_counts(self):
_run_and_verify(
self,
atest_command=self._TARGET_NAME,
is_device_required=True,
verifiers=_create_pass_fail_ignore_verifiers(
expected_passed_count=2,
expected_failed_count=1,
expected_ignored_count=0,
)
+ _create_elapsed_time_verifiers(max_sec=20),
)
@dataclass
class _Verifier:
"""Wrapper class to store a verifier function with a subtest name."""
do_verify: Callable[
atest_integration_test.AtestTestCase,
atest_integration_test.AtestRunResult,
]
name: str
def _create_elapsed_time_verifiers(max_sec: float) -> list[_Verifier]:
return [
_Verifier(
lambda test_case, result: test_case.assertLessEqual(
result.get_elapsed_time(), max_sec
),
'elapsed_time',
)
]
def _create_pass_fail_ignore_verifiers(
expected_passed_count: int,
expected_failed_count: int,
expected_ignored_count: int,
) -> list[_Verifier]:
"""Create a list of verifiers that verify an atest command finished with expected result counts.
Args:
expected_passed_count: Number of expected passed count.
expected_failed_count: Number of expected failed count.
expected_ignored_count: Number of expected ignored count.
"""
return [
_Verifier(
lambda test_case, result: test_case.assertEqual(
result.get_passed_count(), expected_passed_count
),
'pass_count',
),
_Verifier(
lambda test_case, result: test_case.assertEqual(
result.get_failed_count(), expected_failed_count
),
'fail_count',
),
_Verifier(
lambda test_case, result: test_case.assertEqual(
result.get_ignored_count(), expected_ignored_count
),
'ignore_count',
),
]
def _run_and_verify(
test_case: atest_integration_test.AtestTestCase,
atest_command: str,
is_device_required: bool,
verifiers: list[_Verifier],
):
"""Verify an atest command finished with expected result counts.
Args:
test_case: The reference to the calling test case.
atest_command: The atest command to execute. Note: exclude 'atest',
'atest-dev', '-b', '-i', and '-t' from it.
is_device_required: Whether the test requires a device.
verifiers: A list of verifiers to call to verify the result.
"""
script = test_case.create_atest_script()
def build_step(
step_in: atest_integration_test.StepInput,
) -> atest_integration_test.StepOutput:
test_case.run_atest_command(
atest_command + ' -cb', step_in, include_device_serial=False
).check_returncode()
return test_case.create_step_output()
def test_step(step_in: atest_integration_test.StepInput) -> None:
result = test_case.run_atest_command(
atest_command + ' -it',
step_in,
include_device_serial=is_device_required,
print_output=False,
)
for verifier in verifiers:
with test_case.subTest(verifier.name):
verifier.do_verify(test_case, result)
script.add_build_step(build_step)
script.add_test_step(test_step)
script.run()
if __name__ == '__main__':
atest_integration_test.main()