Skip to content

Commit

Permalink
Merge fb46975 into b173bcb
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric-Arellano committed Aug 31, 2020
2 parents b173bcb + fb46975 commit e1b872a
Show file tree
Hide file tree
Showing 40 changed files with 4,181 additions and 3,990 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
PythonAwsLambdaHandler,
PythonAwsLambdaRuntime,
)
from pants.backend.python.rules import pex, pex_from_targets, python_sources
from pants.backend.python.rules import pex_from_targets
from pants.backend.python.rules.pex import (
Pex,
PexInterpreterConstraints,
Expand All @@ -26,7 +26,6 @@
PexFromTargetsRequest,
TwoStepPexFromTargetsRequest,
)
from pants.core.util_rules import stripped_source_files
from pants.engine.fs import Digest, MergeDigests
from pants.engine.process import ProcessResult
from pants.engine.rules import Get, collect_rules, rule
Expand Down Expand Up @@ -125,8 +124,5 @@ def rules():
return [
*collect_rules(),
UnionRule(AWSLambdaFieldSet, PythonAwsLambdaFieldSet),
*python_sources.rules(),
*pex.rules(),
*pex_from_targets.rules(),
*stripped_source_files.rules(),
]
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from typing import Tuple
from zipfile import ZipFile

import pytest

from pants.backend.awslambda.common.awslambda_common_rules import CreatedAWSLambda
from pants.backend.awslambda.python.awslambda_python_rules import PythonAwsLambdaFieldSet
from pants.backend.awslambda.python.awslambda_python_rules import rules as awslambda_python_rules
Expand All @@ -16,75 +18,74 @@
from pants.engine.rules import QueryRule
from pants.engine.target import WrappedTarget
from pants.option.options_bootstrapper import OptionsBootstrapper
from pants.testutil.external_tool_test_base import ExternalToolTestBase
from pants.testutil.option_util import create_options_bootstrapper
from pants.testutil.rule_runner import RuleRunner


class TestPythonAWSLambdaCreation(ExternalToolTestBase):
@classmethod
def rules(cls):
return (
*super().rules(),
@pytest.fixture
def rule_runner() -> RuleRunner:
return RuleRunner(
rules=[
*awslambda_python_rules(),
QueryRule(CreatedAWSLambda, (PythonAwsLambdaFieldSet, OptionsBootstrapper)),
)
],
target_types=[PythonAWSLambda, PythonLibrary],
)


@classmethod
def target_types(cls):
return [PythonAWSLambda, PythonLibrary]
def create_python_awslambda(rule_runner: RuleRunner, addr: str) -> Tuple[str, bytes]:
bootstrapper = create_options_bootstrapper(
args=[
"--backend-packages=pants.backend.awslambda.python",
"--source-root-patterns=src/python",
]
)
target = rule_runner.request_product(WrappedTarget, [Address.parse(addr), bootstrapper]).target
created_awslambda = rule_runner.request_product(
CreatedAWSLambda, [PythonAwsLambdaFieldSet.create(target), bootstrapper]
)
created_awslambda_digest_contents = rule_runner.request_product(
DigestContents, [created_awslambda.digest]
)
assert len(created_awslambda_digest_contents) == 1
return created_awslambda.zip_file_relpath, created_awslambda_digest_contents[0].content

def create_python_awslambda(self, addr: str) -> Tuple[str, bytes]:
bootstrapper = create_options_bootstrapper(
args=[
"--backend-packages=pants.backend.awslambda.python",
"--source-root-patterns=src/python",
]
)
target = self.request_product(WrappedTarget, [Address.parse(addr), bootstrapper]).target
created_awslambda = self.request_product(
CreatedAWSLambda, [PythonAwsLambdaFieldSet.create(target), bootstrapper]
)
created_awslambda_digest_contents = self.request_product(
DigestContents, [created_awslambda.digest]
)
assert len(created_awslambda_digest_contents) == 1
return created_awslambda.zip_file_relpath, created_awslambda_digest_contents[0].content

def test_create_hello_world_lambda(self) -> None:
self.create_file(
"src/python/foo/bar/hello_world.py",
textwrap.dedent(
"""
def handler(event, context):
print('Hello, World!')
"""
),
)
def test_create_hello_world_lambda(rule_runner: RuleRunner) -> None:
rule_runner.create_file(
"src/python/foo/bar/hello_world.py",
textwrap.dedent(
"""
def handler(event, context):
print('Hello, World!')
"""
),
)

self.create_file(
"src/python/foo/bar/BUILD",
textwrap.dedent(
"""
python_library(
name='hello_world',
sources=['hello_world.py']
)
rule_runner.add_to_build_file(
"src/python/foo/bar",
textwrap.dedent(
"""
python_library(
name='hello_world',
sources=['hello_world.py']
)
python_awslambda(
name='hello_world_lambda',
dependencies=[':hello_world'],
handler='foo.bar.hello_world',
runtime='python3.7'
)
"""
),
)
python_awslambda(
name='hello_world_lambda',
dependencies=[':hello_world'],
handler='foo.bar.hello_world',
runtime='python3.7'
)
"""
),
)

zip_file_relpath, content = self.create_python_awslambda(
"src/python/foo/bar:hello_world_lambda"
)
assert "hello_world_lambda.zip" == zip_file_relpath
zipfile = ZipFile(BytesIO(content))
names = set(zipfile.namelist())
assert "lambdex_handler.py" in names
assert "foo/bar/hello_world.py" in names
zip_file_relpath, content = create_python_awslambda(
rule_runner, "src/python/foo/bar:hello_world_lambda"
)
assert "hello_world_lambda.zip" == zip_file_relpath
zipfile = ZipFile(BytesIO(content))
names = set(zipfile.namelist())
assert "lambdex_handler.py" in names
assert "foo/bar/hello_world.py" in names
140 changes: 72 additions & 68 deletions src/python/pants/backend/project_info/cloc_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import pytest

from pants.backend.project_info import cloc
from pants.backend.project_info.cloc import CountLinesOfCode
from pants.backend.python.target_types import PythonLibrary
from pants.core.util_rules import archive, external_tool
from pants.core.util_rules import external_tool
from pants.engine.target import Sources, Target
from pants.testutil.test_base import GoalRuleResult, TestBase
from pants.testutil.rule_runner import GoalRuleResult, RuleRunner


class ElixirSources(Sources):
Expand All @@ -18,6 +20,13 @@ class ElixirTarget(Target):
core_fields = (ElixirSources,)


@pytest.fixture
def rule_runner() -> RuleRunner:
return RuleRunner(
rules=[*cloc.rules(), *external_tool.rules()], target_types=[PythonLibrary, ElixirTarget]
)


def assert_counts(
stdout: str, lang: str, *, num_files: int = 1, blank: int = 0, comment: int = 0, code: int = 0
) -> None:
Expand All @@ -37,69 +46,64 @@ def assert_counts(
assert code == int(fields[4])


class ClocTest(TestBase):
@classmethod
def target_types(cls):
return [PythonLibrary, ElixirTarget]

@classmethod
def rules(cls):
return [*super().rules(), *cloc.rules(), *archive.rules(), *external_tool.rules()]

def test_cloc(self) -> None:
py_dir = "src/py/foo"
self.create_file(
f"{py_dir}/foo.py", '# A comment.\n\nprint("some code")\n# Another comment.'
)
self.create_file(f"{py_dir}/bar.py", '# A comment.\n\nprint("some more code")')
self.add_to_build_file(py_dir, "python_library()")

elixir_dir = "src/elixir/foo"
self.create_file(f"{elixir_dir}/foo.ex", 'IO.puts("Some elixir")\n# A comment')
self.create_file(
f"{elixir_dir}/ignored.ex", "# We do not expect this file to appear in counts."
)
self.add_to_build_file(elixir_dir, "elixir(sources=['foo.ex'])")

result = self.run_goal_rule(CountLinesOfCode, args=[py_dir, elixir_dir])
assert result.exit_code == 0
assert_counts(result.stdout, "Python", num_files=2, blank=2, comment=3, code=2)
assert_counts(result.stdout, "Elixir", comment=1, code=1)

def test_ignored(self) -> None:
py_dir = "src/py/foo"
self.create_file(f"{py_dir}/foo.py", "print('some code')")
self.create_file(f"{py_dir}/empty.py", "")
self.add_to_build_file(py_dir, "python_library()")

result = self.run_goal_rule(CountLinesOfCode, args=[py_dir, "--cloc-ignored"])
assert result.exit_code == 0
assert "Ignored the following files:" in result.stderr
assert "empty.py: zero sized file" in result.stderr

def test_filesystem_specs_with_owners(self) -> None:
"""Even if a file belongs to a target which has multiple sources, we should only run over
the specified file."""
py_dir = "src/py/foo"
self.create_file(f"{py_dir}/foo.py", "print('some code')")
self.create_file(f"{py_dir}/bar.py", "print('some code')\nprint('more code')")
self.add_to_build_file(py_dir, "python_library()")
result = self.run_goal_rule(CountLinesOfCode, args=[f"{py_dir}/foo.py"])
assert result.exit_code == 0
assert_counts(result.stdout, "Python", num_files=1, code=1)

def test_filesystem_specs_without_owners(self) -> None:
"""Unlike most goals, cloc works on any readable file in the build root, regardless of
whether it's declared in a BUILD file."""
self.create_file("test/foo.ex", 'IO.puts("im a free thinker!")')
self.create_file("test/foo.hs", 'main = putStrLn "Whats Pants, precious?"')
result = self.run_goal_rule(CountLinesOfCode, args=["test/foo.*"])
assert result.exit_code == 0
assert_counts(result.stdout, "Elixir", code=1)
assert_counts(result.stdout, "Haskell", code=1)

def test_no_sources_exits_gracefully(self) -> None:
py_dir = "src/py/foo"
self.add_to_build_file(py_dir, "python_library(sources=[])")
result = self.run_goal_rule(CountLinesOfCode, args=[py_dir])
assert result == GoalRuleResult.noop()
def test_cloc(rule_runner: RuleRunner) -> None:
py_dir = "src/py/foo"
rule_runner.create_file(
f"{py_dir}/foo.py", '# A comment.\n\nprint("some code")\n# Another comment.'
)
rule_runner.create_file(f"{py_dir}/bar.py", '# A comment.\n\nprint("some more code")')
rule_runner.add_to_build_file(py_dir, "python_library()")

elixir_dir = "src/elixir/foo"
rule_runner.create_file(f"{elixir_dir}/foo.ex", 'IO.puts("Some elixir")\n# A comment')
rule_runner.create_file(
f"{elixir_dir}/ignored.ex", "# We do not expect this file to appear in counts."
)
rule_runner.add_to_build_file(elixir_dir, "elixir(sources=['foo.ex'])")

result = rule_runner.run_goal_rule(CountLinesOfCode, args=[py_dir, elixir_dir])
assert result.exit_code == 0
assert_counts(result.stdout, "Python", num_files=2, blank=2, comment=3, code=2)
assert_counts(result.stdout, "Elixir", comment=1, code=1)


def test_ignored(rule_runner: RuleRunner) -> None:
py_dir = "src/py/foo"
rule_runner.create_file(f"{py_dir}/foo.py", "print('some code')")
rule_runner.create_file(f"{py_dir}/empty.py", "")
rule_runner.add_to_build_file(py_dir, "python_library()")

result = rule_runner.run_goal_rule(CountLinesOfCode, args=[py_dir, "--cloc-ignored"])
assert result.exit_code == 0
assert "Ignored the following files:" in result.stderr
assert "empty.py: zero sized file" in result.stderr


def test_filesystem_specs_with_owners(rule_runner: RuleRunner) -> None:
"""Even if a file belongs to a target which has multiple sources, we should only run over the
specified file."""
py_dir = "src/py/foo"
rule_runner.create_file(f"{py_dir}/foo.py", "print('some code')")
rule_runner.create_file(f"{py_dir}/bar.py", "print('some code')\nprint('more code')")
rule_runner.add_to_build_file(py_dir, "python_library()")
result = rule_runner.run_goal_rule(CountLinesOfCode, args=[f"{py_dir}/foo.py"])
assert result.exit_code == 0
assert_counts(result.stdout, "Python", num_files=1, code=1)


def test_filesystem_specs_without_owners(rule_runner: RuleRunner) -> None:
"""Unlike most goals, cloc works on any readable file in the build root, regardless of whether
it's declared in a BUILD file."""
rule_runner.create_file("test/foo.ex", 'IO.puts("im a free thinker!")')
rule_runner.create_file("test/foo.hs", 'main = putStrLn "Whats Pants, precious?"')
result = rule_runner.run_goal_rule(CountLinesOfCode, args=["test/foo.*"])
assert result.exit_code == 0
assert_counts(result.stdout, "Elixir", code=1)
assert_counts(result.stdout, "Haskell", code=1)


def test_no_sources_exits_gracefully(rule_runner: RuleRunner) -> None:
py_dir = "src/py/foo"
rule_runner.add_to_build_file(py_dir, "python_library(sources=[])")
result = rule_runner.run_goal_rule(CountLinesOfCode, args=[py_dir])
assert result == GoalRuleResult.noop()

0 comments on commit e1b872a

Please sign in to comment.