Skip to content

Commit

Permalink
Utilities to create subsystem instances. (#9528)
Browse files Browse the repository at this point in the history
Introduce utility functions to create GoalSubsystem and Subsystem
instances for testing.

Fixes #9141
  • Loading branch information
jsirois authored Apr 14, 2020
1 parent 2f17315 commit 4779d3a
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 98 deletions.
25 changes: 10 additions & 15 deletions src/python/pants/engine/goal_test.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from unittest.mock import Mock

import pytest

from pants.engine.console import Console
from pants.engine.goal import Goal, GoalSubsystem, LineOriented
from pants.engine.rules import goal_rule
from pants.testutil.engine.util import MockConsole, run_rule
from pants.testutil.engine.util import MockConsole, create_goal_subsystem, run_rule


@pytest.mark.skip(
reason="Figure out how to create a GoalSubsystem for tests. We can't call global_instance()"
)
def test_line_oriented_goal() -> None:
class OutputtingGoalOptions(LineOriented, GoalSubsystem):
name = "dummy"
Expand All @@ -29,11 +22,13 @@ def output_rule(console: Console, options: OutputtingGoalOptions) -> OutputtingG
print_stdout("line oriented")
return OutputtingGoal(0)

mock_console = MockConsole()
# TODO: how should we mock `GoalSubsystem`s passed to `run_rule`?
mock_options = Mock()
mock_options.output = OutputtingGoalOptions.output
mock_options.line_oriented = OutputtingGoalOptions.line_oriented
result: OutputtingGoal = run_rule(output_rule, rule_args=[mock_console, mock_options])
console = MockConsole()
result: OutputtingGoal = run_rule(
output_rule,
rule_args=[
console,
create_goal_subsystem(OutputtingGoalOptions, sep="\\n", output_file=None),
],
)
assert result.exit_code == 0
assert mock_console.stdout.getvalue() == "output...line oriented"
assert console.stdout.getvalue() == "output...line oriented\n"
19 changes: 10 additions & 9 deletions src/python/pants/rules/core/fmt_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@
TargetAdaptorWithOrigin,
)
from pants.engine.rules import UnionMembership
from pants.rules.core.fmt import Fmt, FmtResult, LanguageFmtResults, LanguageFormatters, fmt
from pants.testutil.engine.util import MockConsole, MockGet, run_rule
from pants.rules.core.fmt import (
Fmt,
FmtOptions,
FmtResult,
LanguageFmtResults,
LanguageFormatters,
fmt,
)
from pants.testutil.engine.util import MockConsole, MockGet, create_goal_subsystem, run_rule
from pants.testutil.test_base import TestBase
from pants.util.ordered_set import OrderedSet


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)


class MockLanguageFormatters(LanguageFormatters, metaclass=ABCMeta):
@staticmethod
@abstractmethod
Expand Down Expand Up @@ -132,7 +133,7 @@ def run_fmt_rule(
rule_args=[
console,
HydratedTargetsWithOrigins(targets),
MockOptions(per_target_caching=per_target_caching),
create_goal_subsystem(FmtOptions, per_target_caching=per_target_caching),
Workspace(self.scheduler),
union_membership,
],
Expand Down
13 changes: 3 additions & 10 deletions src/python/pants/rules/core/lint_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,18 @@

from abc import ABCMeta, abstractmethod
from typing import Iterable, List, Tuple, Type
from unittest.mock import Mock

from pants.build_graph.address import Address
from pants.engine.legacy.graph import HydratedTargetsWithOrigins, HydratedTargetWithOrigin
from pants.engine.legacy.structs import TargetAdaptorWithOrigin
from pants.engine.rules import UnionMembership
from pants.rules.core.fmt_test import FmtTest
from pants.rules.core.lint import Lint, Linter, LintResult, lint
from pants.testutil.engine.util import MockConsole, MockGet, run_rule
from pants.rules.core.lint import Lint, Linter, LintOptions, LintResult, lint
from pants.testutil.engine.util import MockConsole, MockGet, create_goal_subsystem, run_rule
from pants.testutil.test_base import TestBase
from pants.util.ordered_set import OrderedSet


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)


class MockLinter(Linter, metaclass=ABCMeta):
@staticmethod
def is_valid_target(_: TargetAdaptorWithOrigin) -> bool:
Expand Down Expand Up @@ -107,7 +100,7 @@ def run_lint_rule(
rule_args=[
console,
HydratedTargetsWithOrigins(targets),
MockOptions(per_target_caching=per_target_caching),
create_goal_subsystem(LintOptions, per_target_caching=per_target_caching),
union_membership,
],
mock_gets=[
Expand Down
18 changes: 7 additions & 11 deletions src/python/pants/rules/core/list_backends_test.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from contextlib import contextmanager
from textwrap import dedent

from pants.engine.fs import EMPTY_SNAPSHOT, Digest, FileContent, FilesContent, PathGlobs, Snapshot
from pants.option.global_options import GlobalOptions
from pants.rules.core.list_backends import hackily_get_module_docstring, list_backends
from pants.rules.core.list_backends import (
BackendsOptions,
hackily_get_module_docstring,
list_backends,
)
from pants.source.source_root import SourceRootConfig
from pants.testutil.engine.util import MockConsole, MockGet, run_rule
from pants.testutil.engine.util import MockConsole, MockGet, create_goal_subsystem, run_rule
from pants.testutil.subsystem.util import global_subsystem_instance


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
@contextmanager
def line_oriented(self, console: MockConsole):
yield lambda msg: console.print_stdout(msg)


def test_hackily_get_module_docstring() -> None:
assert (
hackily_get_module_docstring(
Expand Down Expand Up @@ -156,7 +152,7 @@ def rules():
run_rule(
list_backends,
rule_args=[
MockOptions(),
create_goal_subsystem(BackendsOptions, sep="\\n", output_file=None),
global_subsystem_instance(SourceRootConfig),
global_subsystem_instance(GlobalOptions),
console,
Expand Down
28 changes: 12 additions & 16 deletions src/python/pants/rules/core/list_target_types_test.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from contextlib import contextmanager
from enum import Enum
from textwrap import dedent
from typing import Optional, cast
from unittest.mock import Mock

from pants.engine.rules import UnionMembership
from pants.engine.target import BoolField, IntField, RegisteredTargetTypes, StringField, Target
from pants.rules.core.list_target_types import list_target_types
from pants.testutil.engine.util import MockConsole, run_rule
from pants.option.global_options import GlobalOptions
from pants.rules.core.list_target_types import TargetTypesOptions, list_target_types
from pants.testutil.engine.util import (
MockConsole,
create_goal_subsystem,
create_subsystem,
run_rule,
)
from pants.util.ordered_set import OrderedSet


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)

@contextmanager
def line_oriented(self, console: MockConsole):
yield lambda msg: console.print_stdout(msg)


# Note no docstring.
class FortranVersion(StringField):
alias = "fortran_version"
Expand Down Expand Up @@ -90,8 +84,10 @@ def run_goal(
rule_args=[
RegisteredTargetTypes.create([FortranBinary, FortranLibrary, FortranTests]),
union_membership or UnionMembership({}),
MockOptions(details=details_target),
Mock(),
create_goal_subsystem(
TargetTypesOptions, sep="\\n", output_file=None, details=details_target
),
create_subsystem(GlobalOptions, v1=False),
console,
],
)
Expand Down
22 changes: 6 additions & 16 deletions src/python/pants/rules/core/list_targets_test.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from contextlib import contextmanager
from textwrap import dedent
from typing import List, Optional, Tuple, cast
from unittest.mock import Mock

from pants.backend.jvm.artifact import Artifact
from pants.backend.jvm.repository import Repository
from pants.build_graph.address import Address
from pants.engine.addressable import Addresses
from pants.engine.target import DescriptionField, ProvidesField, Target, Targets
from pants.rules.core.list_targets import list_targets
from pants.testutil.engine.util import MockConsole, MockGet, run_rule


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)
self.name = "list"

@contextmanager
def line_oriented(self, console: MockConsole):
yield lambda msg: console.print_stdout(msg)
from pants.rules.core.list_targets import ListOptions, list_targets
from pants.testutil.engine.util import MockConsole, MockGet, create_goal_subsystem, run_rule


class MockTarget(Target):
Expand All @@ -43,7 +30,10 @@ def run_goal(
list_targets,
rule_args=[
Addresses(tgt.address for tgt in targets),
MockOptions(
create_goal_subsystem(
ListOptions,
sep="\\n",
output_file=None,
documented=show_documented,
provides=show_provides,
provides_columns=provides_columns or "address,artifact_id",
Expand Down
21 changes: 10 additions & 11 deletions src/python/pants/rules/core/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from typing import cast
from unittest.mock import Mock

from pants.base.build_root import BuildRoot
from pants.build_graph.address import Address
Expand All @@ -11,17 +10,17 @@
from pants.engine.interactive_runner import InteractiveProcessRequest, InteractiveRunner
from pants.option.global_options import GlobalOptions
from pants.rules.core.binary import CreatedBinary
from pants.rules.core.run import Run, run
from pants.testutil.engine.util import MockConsole, MockGet, run_rule
from pants.rules.core.run import Run, RunOptions, run
from pants.testutil.engine.util import (
MockConsole,
MockGet,
create_goal_subsystem,
create_subsystem,
run_rule,
)
from pants.testutil.test_base import TestBase


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)


class RunTest(TestBase):
def create_mock_binary(self, program_text: bytes) -> CreatedBinary:
input_files_content = InputFilesContent(
Expand All @@ -44,8 +43,8 @@ def single_target_run(
interactive_runner,
BuildRoot(),
Addresses([Address.parse(address_spec)]),
MockOptions(args=[]),
GlobalOptions.global_instance(),
create_goal_subsystem(RunOptions, args=[]),
create_subsystem(GlobalOptions, pants_workdir=self.pants_workdir),
],
mock_gets=[
MockGet(
Expand Down
12 changes: 3 additions & 9 deletions src/python/pants/rules/core/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from pathlib import PurePath
from textwrap import dedent
from typing import List, Optional, Tuple, Type, cast
from unittest.mock import Mock

import pytest

Expand Down Expand Up @@ -40,21 +39,16 @@
Test,
TestConfiguration,
TestDebugRequest,
TestOptions,
TestResult,
WrappedTestConfiguration,
run_tests,
)
from pants.testutil.engine.util import MockConsole, MockGet, run_rule
from pants.testutil.engine.util import MockConsole, MockGet, create_goal_subsystem, run_rule
from pants.testutil.test_base import TestBase
from pants.util.ordered_set import OrderedSet


# TODO(#9141): replace this with a proper util to create `GoalSubsystem`s
class MockOptions:
def __init__(self, **values):
self.values = Mock(**values)


class MockTarget(Target):
alias = "mock_target"
core_fields = (Sources,)
Expand Down Expand Up @@ -157,7 +151,7 @@ def run_test_rule(
include_sources: bool = True,
) -> Tuple[int, str]:
console = MockConsole(use_colors=False)
options = MockOptions(debug=debug, run_coverage=False)
options = create_goal_subsystem(TestOptions, debug=debug, run_coverage=False)
interactive_runner = InteractiveRunner(self.scheduler)
workspace = Workspace(self.scheduler)
union_membership = UnionMembership({TestConfiguration: OrderedSet([config])})
Expand Down
Loading

0 comments on commit 4779d3a

Please sign in to comment.