Skip to content

Commit

Permalink
add tests for pants-plugins/api_spec generate
Browse files Browse the repository at this point in the history
  • Loading branch information
cognifloyd committed Jan 4, 2023
1 parent bce029b commit 651ab71
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 12 deletions.
29 changes: 17 additions & 12 deletions pants-plugins/api_spec/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@
from api_spec.target_types import APISpecSourceField


GENERATE_SCRIPT = "generate_api_spec"
VALIDATE_SCRIPT = "validate_api_spec"
# these constants are also used in the tests
CMD_SOURCE_ROOT = "st2common"
CMD_DIR = "st2common/st2common/cmd"
CMD_MODULE = "st2common.cmd"
GENERATE_CMD = "generate_api_spec"
VALIDATE_CMD = "validate_api_spec"

SPEC_HEADER = b"""\
# NOTE: This file is auto-generated - DO NOT EDIT MANUALLY
Expand All @@ -65,12 +69,12 @@ class APISpecFieldSet(FieldSet):

class GenerateAPISpecViaFmtTargetsRequest(FmtTargetsRequest):
field_set_type = APISpecFieldSet
name = GENERATE_SCRIPT
name = GENERATE_CMD


class ValidateAPISpecRequest(LintTargetsRequest):
field_set_type = APISpecFieldSet
name = VALIDATE_SCRIPT
name = VALIDATE_CMD


@rule(
Expand Down Expand Up @@ -115,14 +119,14 @@ async def generate_api_spec_via_fmt(
PexFromTargetsRequest(
[
Address(
"st2common/st2common/cmd",
CMD_DIR,
target_name="cmd",
relative_file_path=f"{GENERATE_SCRIPT}.py",
relative_file_path=f"{GENERATE_CMD}.py",
),
],
output_filename=f"{GENERATE_SCRIPT}.pex",
output_filename=f"{GENERATE_CMD}.pex",
internal_only=True,
main=EntryPoint.parse(f"st2common.cmd.{GENERATE_SCRIPT}:main"),
main=EntryPoint.parse(f"{CMD_MODULE}.{GENERATE_CMD}:main"),
),
)

Expand Down Expand Up @@ -165,6 +169,7 @@ async def generate_api_spec_via_fmt(

output_digest = await Get(Digest, CreateDigest(contents))
output_snapshot = await Get(Snapshot, Digest, output_digest)
# TODO: Drop result.stdout since we already wrote it to a file?
return FmtResult.create(request, result, output_snapshot, strip_chroot_path=True)


Expand Down Expand Up @@ -210,14 +215,14 @@ async def validate_api_spec(
PexFromTargetsRequest(
[
Address(
"st2common/st2common/cmd",
CMD_DIR,
target_name="cmd",
relative_file_path=f"{VALIDATE_SCRIPT}.py",
relative_file_path=f"{VALIDATE_CMD}.py",
),
],
output_filename=f"{VALIDATE_SCRIPT}.pex",
output_filename=f"{VALIDATE_CMD}.pex",
internal_only=True,
main=EntryPoint.parse(f"st2common.cmd.{VALIDATE_SCRIPT}:main"),
main=EntryPoint.parse(f"{CMD_MODULE}.{VALIDATE_CMD}:main"),
),
)

Expand Down
162 changes: 162 additions & 0 deletions pants-plugins/api_spec/rules_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Copyright 2022 The StackStorm Authors.
#
# 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.
from __future__ import annotations

import os

import pytest

from pants.backend.python import target_types_rules
from pants.backend.python.target_types import PythonSourcesGeneratorTarget

from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest
from pants.engine.addresses import Address
from pants.engine.fs import CreateDigest, Digest, FileContent, Snapshot
from pants.engine.target import Target
from pants.core.goals.fmt import FmtResult
from pants.testutil.rule_runner import QueryRule, RuleRunner

from .rules import (
CMD_DIR,
CMD_SOURCE_ROOT,
GENERATE_CMD,
APISpecFieldSet,
GenerateAPISpecViaFmtTargetsRequest,
rules as api_spec_rules,
)
from .target_types import APISpec


@pytest.fixture
def rule_runner() -> RuleRunner:
return RuleRunner(
rules=[
*api_spec_rules(),
*target_types_rules.rules(),
QueryRule(FmtResult, (GenerateAPISpecViaFmtTargetsRequest,)),
QueryRule(SourceFiles, (SourceFilesRequest,)),
],
target_types=[APISpec, PythonSourcesGeneratorTarget],
)


def run_st2_generate_api_spec(
rule_runner: RuleRunner,
targets: list[Target],
*,
extra_args: list[str] | None = None,
) -> FmtResult:
rule_runner.set_options(
[
"--backend-packages=api_spec",
f"--source-root-patterns=/{CMD_SOURCE_ROOT}",
*(extra_args or ()),
],
env_inherit={"PATH", "PYENV_ROOT", "HOME"},
)
field_sets = [APISpecFieldSet.create(tgt) for tgt in targets]
input_sources = rule_runner.request(
SourceFiles,
[
SourceFilesRequest(field_set.sources for field_set in field_sets),
],
)
fmt_result = rule_runner.request(
FmtResult,
[
GenerateAPISpecViaFmtTargetsRequest(
field_sets, snapshot=input_sources.snapshot
),
],
)
return fmt_result


# copied from pantsbuild/pants.git/src/python/pants/backend/python/lint/black/rules_integration_test.py
def get_snapshot(rule_runner: RuleRunner, source_files: dict[str, str]) -> Snapshot:
files = [
FileContent(path, content.encode()) for path, content in source_files.items()
]
digest = rule_runner.request(Digest, [CreateDigest(files)])
return rule_runner.request(Snapshot, [digest])


# add dummy script at st2common/st2common/cmd/generate_api_spec.py that the test can load.
GENERATE_API_SPEC_PY = """
import os
def main():
api_spec_text = "{api_spec_text}"
print(api_spec_text)
"""


def write_generate_files(
api_spec_dir: str, api_spec_file: str, before: str, after: str, rule_runner: RuleRunner
) -> None:
files = {
f"{api_spec_dir}/{api_spec_file}": before,
f"{api_spec_dir}/BUILD": "api_spec(name='t')",
# add in the target that's hard-coded in the generate_api_spec_via_fmt rue
f"{CMD_DIR}/{GENERATE_CMD}.py": GENERATE_API_SPEC_PY.format(
api_spec_dir=api_spec_dir, api_spec_text=after
),
f"{CMD_DIR}/BUILD": "python_sources()",
}

module = CMD_DIR
while module != CMD_SOURCE_ROOT:
files[f"{module}/__init__.py"] = ""
module = os.path.dirname(module)

rule_runner.write_files(files)


def test_generate_changed(rule_runner: RuleRunner) -> None:
write_generate_files(
api_spec_dir="my_dir",
api_spec_file="dummy.yaml",
before="BEFORE",
after="AFTER",
rule_runner=rule_runner,
)

tgt = rule_runner.get_target(
Address("my_dir", target_name="t", relative_file_path="dummy.yaml")
)
fmt_result = run_st2_generate_api_spec(rule_runner, [tgt])
assert fmt_result.output == get_snapshot(
rule_runner, {"my_dir/dummy.yaml": "AFTER"}
)
assert fmt_result.did_change is True


def test_generate_unchanged(rule_runner: RuleRunner) -> None:
write_generate_files(
api_spec_dir="my_dir",
api_spec_file="dummy.yaml",
before="AFTER",
after="AFTER",
rule_runner=rule_runner,
)

tgt = rule_runner.get_target(
Address("my_dir", target_name="t", relative_file_path="dummy.yaml")
)
fmt_result = run_st2_generate_api_spec(rule_runner, [tgt])
assert fmt_result.output == get_snapshot(
rule_runner, {"my_dir/dummy.yaml": "AFTER"}
)
assert fmt_result.did_change is False

0 comments on commit 651ab71

Please sign in to comment.