268 lines
9.2 KiB
Python
268 lines
9.2 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2023, 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.
|
|
|
|
"""Unittests for roboleaf_test_runner."""
|
|
|
|
import json
|
|
import unittest
|
|
import subprocess
|
|
import logging
|
|
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
from pyfakefs import fake_filesystem_unittest
|
|
|
|
from atest import atest_utils
|
|
from atest import unittest_constants
|
|
from atest.test_finders.test_info import TestInfo
|
|
from atest.test_runners import roboleaf_test_runner
|
|
from atest.test_runners.roboleaf_test_runner import RoboleafTestRunner
|
|
from atest.test_runners.roboleaf_test_runner import RoboleafModuleMap
|
|
|
|
# TODO(b/274706697): Refactor to remove disable=protected-access
|
|
# pylint: disable=protected-access
|
|
class RoboleafTestRunnerUnittests(fake_filesystem_unittest.TestCase):
|
|
"""Unit tests for roboleaf_test_runner.py"""
|
|
def setUp(self):
|
|
self.test_runner = RoboleafTestRunner(results_dir='')
|
|
self.setUpPyfakefs()
|
|
out_dir = atest_utils.get_build_out_dir()
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ROBOLEAF_MODULE_MAP_PATH,
|
|
contents="{}")
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ALLOW_LIST_PROD_PATH,
|
|
contents="")
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ALLOW_LIST_STAGING_PATH,
|
|
contents="")
|
|
|
|
def tearDown(self):
|
|
RoboleafModuleMap()._module_map = {}
|
|
mock.patch.stopall()
|
|
|
|
def test_read_allow_list(self):
|
|
"""Test _read_allow_list method"""
|
|
self.fs.create_file(
|
|
atest_utils.get_build_out_dir()+"allow_list",
|
|
contents="""test1\ntest2\n#comment1\n//comment2""")
|
|
|
|
self.assertEqual(
|
|
roboleaf_test_runner._read_allow_list("allow_list"),
|
|
['test1','test2'])
|
|
|
|
def test_roboleaf_eligible_tests_filtering(self):
|
|
"""Test roboleaf_eligible_tests method when _module_map has entries"""
|
|
RoboleafModuleMap._instances = {}
|
|
|
|
self.setUpPyfakefs()
|
|
out_dir = atest_utils.get_build_out_dir()
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ROBOLEAF_MODULE_MAP_PATH,
|
|
contents=json.dumps({
|
|
'test1': "//a",
|
|
'test2': "//a/b",
|
|
'test3': "//a/b",
|
|
}))
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ALLOW_LIST_STAGING_PATH,
|
|
contents="test1\ntest2")
|
|
self.fs.create_file(
|
|
out_dir+roboleaf_test_runner._ALLOW_LIST_PROD_PATH,
|
|
contents="test1")
|
|
module_names = [
|
|
'test1',
|
|
'test2',
|
|
'test3',
|
|
'test4',
|
|
]
|
|
|
|
eligible_tests = self.test_runner.roboleaf_eligible_tests(
|
|
roboleaf_test_runner.BazelBuildMode.DEV,
|
|
module_names)
|
|
|
|
self.assertEqual(len(eligible_tests), 3)
|
|
self.assertEqual(eligible_tests["test1"].test_name, 'test1')
|
|
self.assertEqual(eligible_tests["test1"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
self.assertEqual(eligible_tests["test2"].test_name, 'test2')
|
|
self.assertEqual(eligible_tests["test2"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
self.assertEqual(eligible_tests["test3"].test_name, 'test3')
|
|
self.assertEqual(eligible_tests["test3"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
|
|
eligible_tests = self.test_runner.roboleaf_eligible_tests(
|
|
roboleaf_test_runner.BazelBuildMode.STAGING,
|
|
module_names)
|
|
|
|
self.assertEqual(len(eligible_tests), 2)
|
|
self.assertEqual(eligible_tests["test1"].test_name, 'test1')
|
|
self.assertEqual(eligible_tests["test1"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
self.assertEqual(eligible_tests["test2"].test_name, 'test2')
|
|
self.assertEqual(eligible_tests["test2"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
|
|
eligible_tests = self.test_runner.roboleaf_eligible_tests(
|
|
roboleaf_test_runner.BazelBuildMode.PROD,
|
|
module_names)
|
|
|
|
self.assertEqual(len(eligible_tests), 1)
|
|
self.assertEqual(eligible_tests["test1"].test_name, 'test1')
|
|
self.assertEqual(eligible_tests["test1"].test_runner,
|
|
RoboleafTestRunner.NAME)
|
|
|
|
def test_roboleaf_eligible_tests_empty_map(self):
|
|
"""Test roboleaf_eligible_tests method when _module_map is empty"""
|
|
module_names = [
|
|
'test1',
|
|
'test2',
|
|
]
|
|
RoboleafModuleMap()._module_map = {}
|
|
|
|
eligible_tests = self.test_runner.roboleaf_eligible_tests(
|
|
roboleaf_test_runner.BazelBuildMode.DEV,
|
|
module_names)
|
|
self.assertEqual(eligible_tests, {})
|
|
|
|
def test_generate_bp2build_command(self):
|
|
"""Test generate_bp2build method."""
|
|
cmd = roboleaf_test_runner._generate_bp2build_command()
|
|
|
|
self.assertTrue('build/soong/soong_ui.bash --make-mode bp2build' in
|
|
' '.join(cmd))
|
|
|
|
def test_get_map(self):
|
|
"""Test get_map method."""
|
|
data = {
|
|
"test1": "//platform/a",
|
|
"test2": "//platform/b"
|
|
}
|
|
RoboleafModuleMap()._module_map = data
|
|
|
|
self.assertEqual(RoboleafModuleMap().get_map(), data)
|
|
|
|
@mock.patch.object(subprocess, "check_call")
|
|
def test_generate_map(self, mock_subprocess):
|
|
"""Test test_generate_map method fomr file."""
|
|
module_map_location = Path(unittest_constants.TEST_DATA_DIR).joinpath(
|
|
"roboleaf_testing/converted_modules_path_map.json"
|
|
)
|
|
self.fs.create_file(
|
|
module_map_location,
|
|
contents=json.dumps({
|
|
"test1": "//platform/a",
|
|
"test2": "//platform/b"
|
|
}))
|
|
|
|
data = roboleaf_test_runner._generate_map(module_map_location)
|
|
|
|
# Expected to not call a subprocess with the roboleaf bp2build
|
|
# command since file already exists.
|
|
self.assertEqual(mock_subprocess.called, False)
|
|
self.assertEqual(data, {
|
|
"test1": "//platform/a",
|
|
"test2": "//platform/b"
|
|
})
|
|
|
|
@mock.patch('builtins.open', mock.mock_open(read_data=json.dumps(
|
|
{"test3": "//a/b"})))
|
|
@mock.patch.object(subprocess, "check_call")
|
|
def test_generate_map_with_command(self, mock_subprocess):
|
|
"""Test that _generate_map runs the bp2build command"""
|
|
module_map_location = Path(unittest_constants.TEST_DATA_DIR).joinpath(
|
|
"roboleaf_testing/does_not_exist.json"
|
|
)
|
|
|
|
# Disable expected warning log message "converted modules file was not
|
|
# found." to reduce noise during tests.
|
|
logging.disable(logging.WARNING)
|
|
data = roboleaf_test_runner._generate_map(module_map_location)
|
|
logging.disable(logging.NOTSET)
|
|
|
|
self.assertEqual(mock_subprocess.called, True)
|
|
self.assertEqual(data, {"test3": "//a/b"})
|
|
|
|
def test_info_target_label(self):
|
|
"""Test info_target_label method."""
|
|
RoboleafModuleMap()._module_map = {
|
|
"test1": "//a",
|
|
}
|
|
|
|
target_label = self.test_runner.test_info_target_label(
|
|
TestInfo(
|
|
"test1",
|
|
RoboleafTestRunner.NAME,
|
|
set()),
|
|
)
|
|
|
|
self.assertEqual(target_label, "//a:test1")
|
|
|
|
def test_generate_run_commands(self):
|
|
"""Test generate_run_commands method."""
|
|
RoboleafModuleMap()._module_map = {
|
|
"test1": "//a",
|
|
"test2": "//b",
|
|
}
|
|
test_infos = (
|
|
TestInfo(
|
|
"test1",
|
|
RoboleafTestRunner.NAME,
|
|
set()),
|
|
TestInfo(
|
|
"test2",
|
|
RoboleafTestRunner.NAME,
|
|
set()),
|
|
)
|
|
|
|
cmds = self.test_runner.generate_run_commands(test_infos, extra_args={})
|
|
|
|
self.assertEqual(len(cmds), 1)
|
|
self.assertTrue('b test //a:test1 //b:test2' in cmds[0])
|
|
|
|
@mock.patch.object(RoboleafTestRunner, 'run')
|
|
def test_run_tests(self, mock_run):
|
|
"""Test run_tests_raw method."""
|
|
RoboleafModuleMap()._module_map = {
|
|
"test1": "//a",
|
|
"test2": "//b",
|
|
}
|
|
test_infos = (
|
|
TestInfo(
|
|
"test1",
|
|
RoboleafTestRunner.NAME,
|
|
set()),
|
|
TestInfo(
|
|
"test2",
|
|
RoboleafTestRunner.NAME,
|
|
set()),
|
|
)
|
|
extra_args = {}
|
|
mock_subproc = mock.Mock()
|
|
mock_run.return_value = mock_subproc
|
|
mock_subproc.returncode = 0
|
|
mock_reporter = mock.Mock()
|
|
|
|
result = self.test_runner.run_tests(
|
|
test_infos, extra_args, mock_reporter)
|
|
|
|
self.assertEqual(result, 0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|