374 lines
14 KiB
Python
374 lines
14 KiB
Python
#!/usr/bin/env python
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import os
|
|
import sys
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from mach.registrar import Registrar
|
|
from mozunit import main
|
|
|
|
# Ensure testing category is registered before importing mach_commands
|
|
Registrar.categories["testing"] = []
|
|
Registrar.commands_by_category["testing"] = set()
|
|
Registrar.register_category("testing", "testing", "testing")
|
|
|
|
# Add parent directory to path to import mach_commands
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
from mach_commands import (
|
|
classname_for_test,
|
|
flavor_for_test,
|
|
project_for_ac,
|
|
project_for_test,
|
|
source_dir_for_test,
|
|
submodule_for_test,
|
|
)
|
|
|
|
|
|
class TestAndroidMachCommands(unittest.TestCase):
|
|
TEST_CASES = [
|
|
# (test_path, expected_project, expected_component, expected_flavor, expected_class)
|
|
(
|
|
"mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/GeckoBundleTest.java",
|
|
"geckoview",
|
|
None,
|
|
"unit",
|
|
"org.mozilla.gecko.util.GeckoBundleTest",
|
|
),
|
|
(
|
|
"mobile/android/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineTest.kt",
|
|
"android-components",
|
|
"concept-engine",
|
|
"unit",
|
|
"mozilla.components.concept.engine.EngineTest",
|
|
),
|
|
(
|
|
"mobile/android/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineTest.kt",
|
|
"android-components",
|
|
"browser-engine-gecko",
|
|
"unit",
|
|
"mozilla.components.browser.engine.gecko.GeckoEngineTest",
|
|
),
|
|
(
|
|
"mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt",
|
|
"fenix",
|
|
None,
|
|
"unit",
|
|
"org.mozilla.fenix.home.HomeFragmentTest",
|
|
),
|
|
(
|
|
"mobile/android/focus-android/app/src/test/java/org/mozilla/focus/components/EngineProviderTest.kt",
|
|
"focus-android",
|
|
None,
|
|
"unit",
|
|
"org.mozilla.focus.components.EngineProviderTest",
|
|
),
|
|
(
|
|
"mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/components/MenuItemTest.kt",
|
|
"fenix",
|
|
None,
|
|
"android",
|
|
"org.mozilla.fenix.components.MenuItemTest",
|
|
),
|
|
(
|
|
"mobile/android/fenix/app/longfox/src/test/kotlin/org/mozilla/fenix/longfox/GameStateTest.kt",
|
|
"fenix",
|
|
None,
|
|
"unit",
|
|
"org.mozilla.fenix.longfox.GameStateTest",
|
|
),
|
|
]
|
|
|
|
def cleanup_gradle_args(self, args):
|
|
"""Given a list of arguments for a gradle invocation, remove those that are not
|
|
interesting for this test suite to simplify matching."""
|
|
IGNORE = ["-q", "--rerun"]
|
|
return [x for x in args if x not in IGNORE]
|
|
|
|
def test_classname_for_test(self):
|
|
"""Test extraction of class name from test path."""
|
|
for test_path, _, _, _, expected in self.TEST_CASES:
|
|
with self.subTest(test_path=test_path):
|
|
if flavor_for_test(test_path) == "unit":
|
|
result = classname_for_test(
|
|
test_path, source_dir_for_test(test_path)
|
|
)
|
|
else:
|
|
result = classname_for_test(
|
|
test_path, source_dir_for_test(test_path, "androidTest")
|
|
)
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_project_for_test(self):
|
|
"""Test extraction of project name from test path."""
|
|
PROJECT_PREFIX = "mobile/android"
|
|
|
|
for test_path, expected, _, _, _ in self.TEST_CASES:
|
|
with self.subTest(project=expected):
|
|
result = project_for_test(test_path, PROJECT_PREFIX)
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_project_for_ac(self):
|
|
"""Test extraction of android-components subproject name."""
|
|
COMPONENT_PREFIX = "mobile/android/android-components/components"
|
|
TEST_PATH_PREFIX = "src/test/java"
|
|
for test_path, project, expected, _, _ in self.TEST_CASES:
|
|
if project != "android-components":
|
|
continue
|
|
with self.subTest(component=expected):
|
|
result = project_for_ac(test_path, COMPONENT_PREFIX, TEST_PATH_PREFIX)
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_flavor_for_test(self):
|
|
"""Test extraction of test flavor from test path."""
|
|
for test_path, _, _, expected, _ in self.TEST_CASES:
|
|
with self.subTest(flavor=expected):
|
|
result = flavor_for_test(test_path)
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_android_test_implicit_subproject(self):
|
|
"""Test that run_android_test derives subproject if a specific test is requested."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
TEST_PATH = "mobile/android/focus-android/app/src/test/java/org/mozilla/focus/components/EngineProviderTest.kt"
|
|
run_android_test(command_context, subproject=None, test=TEST_PATH)
|
|
|
|
mock_dispatch.assert_called_once()
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "focus-android", "app"),
|
|
":app:testFocusDebugUnitTest",
|
|
"--tests",
|
|
"org.mozilla.focus.components.EngineProviderTest",
|
|
],
|
|
)
|
|
|
|
def test_run_android_test_fenix(self):
|
|
"""Test that run_android_test calls dispatch with correct arguments for fenix."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
run_android_test(
|
|
command_context,
|
|
subproject="fenix",
|
|
)
|
|
|
|
mock_dispatch.assert_called_once()
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "fenix", "app"),
|
|
"testDebugUnitTest",
|
|
],
|
|
)
|
|
|
|
def test_run_android_test_androidTest(self):
|
|
"""Test that run_android_test can run instrumented test types."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
TEST_PATH = "mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/components/MenuItemTest.kt"
|
|
run_android_test(
|
|
command_context,
|
|
subproject=None,
|
|
test=TEST_PATH,
|
|
)
|
|
|
|
mock_dispatch.assert_called_once()
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "fenix", "app"),
|
|
":app:connectedDebugAndroidTest",
|
|
"-Pandroid.testInstrumentationRunnerArguments.class=org.mozilla.fenix.components.MenuItemTest",
|
|
],
|
|
)
|
|
|
|
def test_run_android_test_gradle_variant(self):
|
|
"""Test that run_android_test handles --gradle-variant."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
run_android_test(
|
|
command_context,
|
|
subproject="geckoview",
|
|
gradle_variant="Release",
|
|
)
|
|
|
|
mock_dispatch.assert_called_once()
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "geckoview"),
|
|
"testReleaseUnitTest",
|
|
],
|
|
)
|
|
|
|
def test_run_android_test_flavor(self):
|
|
"""Test that run_android_test handles --flavor."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
run_android_test(
|
|
command_context,
|
|
subproject="geckoview",
|
|
flavor="both",
|
|
)
|
|
|
|
mock_dispatch.assert_called_once()
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "geckoview"),
|
|
"testDebugUnitTest",
|
|
"connectedDebugAndroidTest",
|
|
],
|
|
)
|
|
|
|
def test_submodule_for_test(self):
|
|
"""Test detection of nested sub-modules."""
|
|
SUBDIR = os.path.join("mobile", "android", "fenix", "app")
|
|
self.assertIsNone(
|
|
submodule_for_test(
|
|
"mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt",
|
|
SUBDIR,
|
|
)
|
|
)
|
|
self.assertEqual(
|
|
submodule_for_test(
|
|
"mobile/android/fenix/app/longfox/src/test/kotlin/org/mozilla/fenix/longfox/GameStateTest.kt",
|
|
SUBDIR,
|
|
),
|
|
"longfox",
|
|
)
|
|
|
|
def test_run_android_test_longfox(self):
|
|
"""Test that run_android_test handles longfox submodule tests."""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = command_context._mach_context.commands.dispatch = (
|
|
mock.MagicMock(return_value=0)
|
|
)
|
|
|
|
test_objects = [
|
|
{
|
|
"name": "mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt",
|
|
},
|
|
{
|
|
"name": "mobile/android/fenix/app/longfox/src/test/kotlin/org/mozilla/fenix/longfox/GameStateTest.kt",
|
|
},
|
|
]
|
|
|
|
run_android_test(
|
|
command_context,
|
|
subproject="fenix",
|
|
test_objects=test_objects,
|
|
)
|
|
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "fenix", "app"),
|
|
":app:testDebugUnitTest",
|
|
"--tests",
|
|
"org.mozilla.fenix.home.HomeFragmentTest",
|
|
":app:longfox:testDebugUnitTest",
|
|
"--tests",
|
|
"org.mozilla.fenix.longfox.GameStateTest",
|
|
],
|
|
)
|
|
|
|
def test_run_android_test_with_multi_component(self):
|
|
"""Test that multiple android-component tests resolve the their component projects"""
|
|
from mach_commands import run_android_test
|
|
|
|
command_context = mock.MagicMock()
|
|
mock_dispatch = mock.MagicMock(return_value=0)
|
|
command_context._mach_context.commands.dispatch = mock_dispatch
|
|
|
|
test_objects = [
|
|
{
|
|
"name": "mobile/android/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineTest.kt",
|
|
},
|
|
{
|
|
"name": "mobile/android/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineViewTest.kt",
|
|
},
|
|
{
|
|
"name": "mobile/android/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineTest.kt",
|
|
},
|
|
{
|
|
"name": "mobile/android/android-components/components/browser/engine-gecko/src/androidTest/java/mozilla/components/browser/engine/gecko/fetch/geckoview/GeckoViewFetchTestCases.kt",
|
|
},
|
|
]
|
|
|
|
run_android_test(
|
|
command_context,
|
|
subproject="android-components",
|
|
test_objects=test_objects,
|
|
)
|
|
|
|
gradle_args = mock_dispatch.call_args[1]["args"]
|
|
self.assertEqual(
|
|
self.cleanup_gradle_args(gradle_args),
|
|
[
|
|
"-p",
|
|
os.path.join("mobile", "android", "android-components"),
|
|
":components:concept-engine:testDebugUnitTest",
|
|
"--tests",
|
|
"mozilla.components.concept.engine.EngineTest",
|
|
"--tests",
|
|
"mozilla.components.concept.engine.EngineViewTest",
|
|
":components:browser-engine-gecko:testDebugUnitTest",
|
|
"--tests",
|
|
"mozilla.components.browser.engine.gecko.GeckoEngineTest",
|
|
":components:browser-engine-gecko:connectedDebugAndroidTest",
|
|
"-Pandroid.testInstrumentationRunnerArguments.class=mozilla.components.browser.engine.gecko.fetch.geckoview.GeckoViewFetchTestCases",
|
|
],
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|