blob: 8aaa86be089020bd191ebdf1f0f98489caf51d6c [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for platform2.py"""
import os
import sys
from unittest import mock
sys.path.insert(
0,
os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", ".."),
)
# pylint: disable=wrong-import-position
import platform2
from chromite.lib import cros_test_lib
# pylint: enable=wrong-import-position
PLATFORM_SUBDIR = "platform"
SYSROOT = "/"
TARGET_PREFIX = "//%s:" % PLATFORM_SUBDIR
class Platform2Configure(cros_test_lib.TestCase):
"""A base class of Platform2 unittest."""
@staticmethod
def _CreateTestPlatform2():
p2 = platform2.Platform2()
p2.platform_subdir = PLATFORM_SUBDIR
p2.sysroot = SYSROOT
return p2
def _RunWithDesc(self, func, gn_description):
"""Runs Platform2.|func| with fake |gn_description|."""
p2 = self._CreateTestPlatform2()
with mock.patch(
"platform2.Platform2.gn_desc", return_value=gn_description
):
return getattr(p2, func)()
class Platform2ConfigureTest(Platform2Configure):
"""Tests Platform2.configure_test()."""
@staticmethod
def _CreateTestData(run_test=True, test_config=None):
"""Generates a template of test data."""
# It emulates a data that is generated by the templates in
# //common-mk/BUILDCONFIG.gn for this BUILD.gn rule example
#
# group("all") {
# deps = ["//platform:test"]
# }
#
# executable("test") {
# output_name = "output"
#
# run_test = $run_test
# test_config = $test_config
#
# # some required variables
# }
if test_config is None:
test_config = {}
return {
TARGET_PREFIX
+ "all": {
"deps": [
TARGET_PREFIX + "test",
],
},
TARGET_PREFIX
+ "test": {
"metadata": {
"_run_test": [run_test],
"_test_config": [test_config],
},
"outputs": ["output"],
},
}
def _CheckConfigureTest(self, gn_description, expected):
"""Helper function to verify output of configure_test."""
ret = self._RunWithDesc("configure_test", gn_description)
self.assertEqual(ret, expected)
@staticmethod
def _OutputTemplate(options):
"""Create Output Template.
Add platform2_test.py and some required options to the beginning.
"""
platform_tooldir = os.path.dirname(os.path.abspath(__file__))
p2_test_py = os.path.join(platform_tooldir, "platform2_test.py")
prefix = [p2_test_py, "--action=run", "--sysroot=%s" % SYSROOT]
return prefix + options
def testMultipleTest(self):
"""Verify it can execute multiple tests."""
targets = [TARGET_PREFIX + "test%s" % i for i in range(10)]
desc_data = {
TARGET_PREFIX
+ "all": {
"deps": targets,
},
}
for target in targets:
desc_data[target] = {
"metadata": {
"_run_test": [True],
},
"outputs": [
"test-%s" % target,
],
}
self._CheckConfigureTest(
desc_data,
[
self._OutputTemplate(["--", "test-%s" % target])
for target in targets
],
)
def testRunTest(self):
"""Verify it executes test only when run_test is true."""
self._CheckConfigureTest(
self._CreateTestData(run_test=True),
[self._OutputTemplate(["--", "output"])],
)
self._CheckConfigureTest(self._CreateTestData(run_test=False), [])
def testBooleanConfigs(self):
"""Verify it converts boolean configs to flag options."""
self._CheckConfigureTest(
self._CreateTestData(
test_config={
"run_as_root": True,
}
),
[self._OutputTemplate(["--run_as_root", "--", "output"])],
)
self._CheckConfigureTest(
self._CreateTestData(
test_config={
"run_as_root": False,
}
),
[self._OutputTemplate(["--", "output"])],
)
def testStringConfigs(self):
"""Verify it converts string configs to not-flag options."""
self._CheckConfigureTest(
self._CreateTestData(
test_config={
"gtest_filter": "-*.RunAsRoot",
}
),
[
self._OutputTemplate(
["--gtest_filter=-*.RunAsRoot", "--", "output"]
)
],
)
class Platform2ConfigureInstall(Platform2Configure):
"""Tests Platform2.configure_install()."""
@staticmethod
def _CreateTestData(
sources=None,
install_path=None,
outputs=None,
symlinks=None,
recursive=False,
options=None,
command_type=None,
):
"""Generates a template of test data."""
# It emulates a data that is generated by the templates in
# //common-mk/BUILDCONFIG.gn for this BUILD.gn rule example
#
# group("all") {
# deps = ["//platform:install"]
# }
#
# install_config("install") {
# sources = $sources
# install_path = $install_path
# outputs = $outputs
# symlinks = $symlinks
# recursive = $recursive
# options = $options
# type = $target_type
#
# # some required variables
# }
install_config = {
"sources": sources,
"install_path": install_path,
"outputs": outputs,
"symlinks": symlinks,
"recursive": recursive,
"options": options,
"type": command_type,
}
metadata = {"_install_config": [install_config]}
return {
TARGET_PREFIX
+ "all": {
"deps": [
TARGET_PREFIX + "install",
],
},
TARGET_PREFIX
+ "install": {
"metadata": metadata,
},
}
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testEbuildParameter(self, generate_mock):
"""Makes sure the parameter passed to ebuild_function correctly."""
gn_desc = self._CreateTestData(
sources=["source"],
install_path="/path",
outputs=["output"],
symlinks=["symlink"],
recursive=True,
options="-m0644",
command_type="executable",
)
self._RunWithDesc("configure_install", gn_desc)
generate_mock.assert_called_with(
sources=["source"],
install_path="/path",
outputs=["output"],
symlinks=["symlink"],
recursive=True,
options="-m0644",
command_type="executable",
)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testEbuildParameterWithoutNewNames(self, generate_mock):
"""Makes sure the parameter passed to ebuild_function correctly."""
gn_desc = self._CreateTestData(
sources=["source"],
install_path="/path",
recursive=True,
options="-m0644",
command_type="executable",
)
self._RunWithDesc("configure_install", gn_desc)
generate_mock.assert_called_with(
sources=["source"],
install_path="/path",
outputs=None,
symlinks=None,
recursive=True,
options="-m0644",
command_type="executable",
)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testWithoutSources(self, generate_mock):
"""Tests configure_install without sources.
Makes sure it returns empty list when sources aren't specified.
"""
self._RunWithDesc("configure_install", self._CreateTestData())
self.assertEqual(generate_mock.call_count, 0)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testWithSources(self, generate_mock):
"""Tests configure_install with sources.
Makes sure it returns an install command when sources are specified.
"""
gn_desc = self._CreateTestData(sources=["source"])
self._RunWithDesc("configure_install", gn_desc)
self.assertEqual(generate_mock.call_count, 1)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testMultipleDifferentPathCommands(self, generate_mock):
"""Tests configure_install when having different install_paths.
Checks outputs are separated when having the different install_paths.
"""
num_install = 10
targets = [
TARGET_PREFIX + "test%s" % str(i) for i in range(num_install)
]
gn_desc = {
TARGET_PREFIX
+ "all": {
"deps": targets,
},
}
for target in targets:
gn_desc[target] = {
"metadata": {
"_install_config": [
{
"install_path": target,
"sources": ["source"],
}
],
},
}
self._RunWithDesc("configure_install", gn_desc)
self.assertEqual(generate_mock.call_count, 10)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testMultipleSamePathCommands(self, generate_mock):
"""Tests configure_install with commands having the same install_paths.
Checks an output is combined when having the same install_paths.
"""
num_install = 10
targets = [
TARGET_PREFIX + "test%s" % str(i) for i in range(num_install)
]
gn_desc = {
TARGET_PREFIX
+ "all": {
"deps": targets,
},
}
for target in targets:
gn_desc[target] = {
"metadata": {
"_install_config": [
{
"install_path": "/path",
"sources": ["source"],
}
],
},
}
self._RunWithDesc("configure_install", gn_desc)
self.assertEqual(generate_mock.call_count, 1)
@mock.patch("ebuild_function.generate", return_value=[["test", "command"]])
def testMixedCommands(self, generate_mock):
"""Test configure_install when having both new-cmd and do-cmd.
Checks it returns two commands when having both new-cmd and do-cmd.
"""
# group("all") {
# deps = [
# "//platform:doins",
# "//platform:newins",
# ]
# }
#
# install_config("doins") {
# sources = "source-doins"
# install_path = "/path"
# }
# install_config("newins") {
# sources = "source-oldins"
# install_path = "/path"
# outputs = "source-newins"
# }
doins_target = TARGET_PREFIX + "doins1"
newins_target = TARGET_PREFIX + "newins"
gn_desc = {
TARGET_PREFIX
+ "all": {
"deps": [
doins_target,
newins_target,
],
},
doins_target: {
"metadata": {
"_install_config": [
{
"install_path": "/path",
"sources": ["source-doins"],
}
],
}
},
newins_target: {
"metadata": {
"_install_config": [
{
"install_path": "/path",
"sources": ["source-oldins"],
"outputs": ["source-newins"],
}
],
},
},
}
self._RunWithDesc("configure_install", gn_desc)
generate_mock.assert_any_call(
sources=["source-doins"],
install_path="/path",
outputs=None,
symlinks=None,
recursive=None,
options=None,
command_type=None,
)
generate_mock.assert_any_call(
sources=["source-oldins"],
install_path="/path",
outputs=["source-newins"],
symlinks=None,
recursive=None,
options=None,
command_type=None,
)
if __name__ == "__main__":
cros_test_lib.main(module=__name__)