Skip to content

Commit 66c94e9

Browse files
Merge branch 'develop'
2 parents bbbaa8f + 9cc29a8 commit 66c94e9

File tree

11 files changed

+215
-50
lines changed

11 files changed

+215
-50
lines changed

CODEOWNERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
22

3-
* @aws/serverless-application-experience-sbt
43
* @aws/aws-lambda-tooling

aws_lambda_builders/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
# Changing version will trigger a new release!
66
# Please make the version change as the last step of your development.
77

8-
__version__ = "1.54.0"
8+
__version__ = "1.55.0"
99
RPC_PROTOCOL_VERSION = "0.3"

aws_lambda_builders/workflows/nodejs_npm/actions.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import logging
6+
import os
67
from typing import Optional
78

89
from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
@@ -321,3 +322,32 @@ def execute(self):
321322

322323
except OSError as ex:
323324
raise ActionFailedError(str(ex))
325+
326+
327+
class NodejsNpmTestAction(NodejsNpmInstallOrUpdateBaseAction):
328+
"""
329+
A Lambda Builder Action that runs tests in NPM project
330+
"""
331+
332+
NAME = "NpmTest"
333+
DESCRIPTION = "Running tests from NPM"
334+
335+
def execute(self):
336+
"""
337+
Runs the action if environment variable `SAM_NPM_RUN_TEST_WITH_BUILD` is `true`.
338+
339+
:raises lambda_builders.actions.ActionFailedError: when NPM execution fails
340+
"""
341+
try:
342+
is_run_test_with_build = os.getenv("SAM_NPM_RUN_TEST_WITH_BUILD", "False")
343+
if is_run_test_with_build == "true":
344+
LOG.debug("NODEJS running tests in: %s", self.install_dir)
345+
346+
command = ["test", "--if-present"]
347+
self.subprocess_npm.run(command, cwd=self.install_dir)
348+
else:
349+
LOG.debug("NODEJS skipping tests")
350+
LOG.debug("Add env variable 'SAM_NPM_RUN_TEST_WITH_BUILD=true' to run tests with build")
351+
352+
except NpmExecutionError as ex:
353+
raise ActionFailedError(str(ex))

aws_lambda_builders/workflows/nodejs_npm/workflow.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
NodejsNpmPackAction,
2323
NodejsNpmrcAndLockfileCopyAction,
2424
NodejsNpmrcCleanUpAction,
25+
NodejsNpmTestAction,
2526
NodejsNpmUpdateAction,
2627
)
2728
from aws_lambda_builders.workflows.nodejs_npm.npm import SubprocessNpm
@@ -123,6 +124,13 @@ def __init__(self, source_dir, artifacts_dir, scratch_dir, manifest_path, runtim
123124
)
124125
)
125126

127+
self.actions.append(
128+
NodejsNpmTestAction(
129+
install_dir=self.manifest_dir if is_building_in_source and is_external_manifest else self.build_dir,
130+
subprocess_npm=subprocess_npm,
131+
)
132+
)
133+
126134
if is_building_in_source and is_external_manifest:
127135
# Since we run `npm install` in the manifest directory, so we need to link the node_modules directory in
128136
# the source directory.

aws_lambda_builders/workflows/python_pip/packager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ class DependencyBuilder(object):
206206
"cp39": (2, 26),
207207
"cp310": (2, 26),
208208
"cp311": (2, 26),
209-
"cp312": (2, 26),
209+
"cp312": (2, 34),
210+
"cp313": (2, 34),
210211
}
211212
# Fallback version if we're on an unknown python version
212213
# not in _RUNTIME_GLIBC.

requirements/dev.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
coverage==7.7.0; python_version>="3.9"
1+
coverage==7.8.2; python_version>="3.9"
22
coverage==7.6.1; python_version<"3.9"
33
flake8==3.8.4
4-
pytest-cov==6.0.0; python_version>="3.9"
4+
pytest-cov==6.1.1; python_version>="3.9"
55
pytest-cov==5.0.0; python_version<"3.9"
66

77
# Test requirements
@@ -12,4 +12,4 @@ pyelftools~=0.32 # Used to verify the generated Go binary architecture in integr
1212
# formatter
1313
black==25.1.0; python_version>="3.9"
1414
black==24.8.0; python_version<"3.9"
15-
ruff==0.11.0
15+
ruff==0.11.13

tests/integration/workflows/nodejs_npm/test_nodejs_npm.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,52 @@ def test_builds_project_with_manifest_outside_root_and_local_dependencies_with_d
779779
# expected dependencies in source directory
780780
source_modules = set(os.listdir(os.path.join(source_dir, "node_modules")))
781781
self.assertTrue(all(expected_module in source_modules for expected_module in expected_modules))
782+
783+
@parameterized.expand([("nodejs16.x",), ("nodejs18.x",), ("nodejs20.x",)])
784+
@mock.patch.dict("os.environ", {"SAM_NPM_RUN_TEST_WITH_BUILD": "true"})
785+
def test_runs_test_script_if_specified(self, runtime):
786+
source_dir = os.path.join(self.TEST_DATA_FOLDER, "test-script-to-create-file")
787+
788+
self.builder.build(
789+
source_dir,
790+
self.artifacts_dir,
791+
self.scratch_dir,
792+
os.path.join(source_dir, "package.json"),
793+
runtime=runtime,
794+
)
795+
796+
expected_files = {"package.json", "created.js"}
797+
output_files = set(os.listdir(self.artifacts_dir))
798+
self.assertEqual(expected_files, output_files)
799+
800+
@parameterized.expand([("nodejs16.x",), ("nodejs18.x",), ("nodejs20.x",)])
801+
def test_does_not_run_test_script_if_env_var_not_specified(self, runtime):
802+
source_dir = os.path.join(self.TEST_DATA_FOLDER, "test-script-to-create-file")
803+
804+
self.builder.build(
805+
source_dir,
806+
self.artifacts_dir,
807+
self.scratch_dir,
808+
os.path.join(source_dir, "package.json"),
809+
runtime=runtime,
810+
)
811+
812+
expected_files = {"package.json"}
813+
output_files = set(os.listdir(self.artifacts_dir))
814+
self.assertEqual(expected_files, output_files)
815+
816+
@parameterized.expand([("nodejs16.x",), ("nodejs18.x",), ("nodejs20.x",)])
817+
def test_does_not_raise_error_if_empty_test_script(self, runtime):
818+
source_dir = os.path.join(self.TEST_DATA_FOLDER, "empty-test-script")
819+
820+
self.builder.build(
821+
source_dir,
822+
self.artifacts_dir,
823+
self.scratch_dir,
824+
os.path.join(source_dir, "package.json"),
825+
runtime=runtime,
826+
)
827+
828+
expected_files = {"package.json"}
829+
output_files = set(os.listdir(self.artifacts_dir))
830+
self.assertEqual(expected_files, output_files)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "testscript",
3+
"version": "1.0.0",
4+
"description": "",
5+
"scripts": {
6+
"test": ""
7+
},
8+
"keywords": [],
9+
"author": "",
10+
"license": "APACHE2.0"
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "testscript",
3+
"version": "1.0.0",
4+
"description": "",
5+
"scripts": {
6+
"test": "touch created.js"
7+
},
8+
"keywords": [],
9+
"author": "",
10+
"license": "APACHE2.0"
11+
}

tests/unit/workflows/nodejs_npm/test_actions.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
NodejsNpmrcCleanUpAction,
1212
NodejsNpmLockFileCleanUpAction,
1313
NodejsNpmCIAction,
14+
NodejsNpmTestAction,
1415
)
1516
from aws_lambda_builders.workflows.nodejs_npm.npm import NpmExecutionError
1617

@@ -219,3 +220,43 @@ def test_raises_action_failed_when_removing_fails(self, OSUtilMock):
219220

220221
with self.assertRaises(ActionFailedError):
221222
action.execute()
223+
224+
225+
class TestNodejsNpmTestAction(TestCase):
226+
@patch("aws_lambda_builders.workflows.nodejs_npm.npm.SubprocessNpm")
227+
@patch.dict("os.environ", {"SAM_NPM_RUN_TEST_WITH_BUILD": "true"}, clear=True)
228+
def test_runs_npm_test_for_npm_project_if_env_var_true(self, SubprocessNpmMock):
229+
subprocess_npm = SubprocessNpmMock.return_value
230+
231+
action = NodejsNpmTestAction(install_dir="tests", subprocess_npm=subprocess_npm)
232+
233+
action.execute()
234+
235+
expected_args = ["test", "--if-present"]
236+
237+
subprocess_npm.run.assert_called_with(expected_args, cwd="tests")
238+
239+
@patch("aws_lambda_builders.workflows.nodejs_npm.npm.SubprocessNpm")
240+
def test_does_not_run_npm_test_for_npm_project_if_no_env_var(self, SubprocessNpmMock):
241+
subprocess_npm = SubprocessNpmMock.return_value
242+
243+
action = NodejsNpmTestAction(install_dir="tests", subprocess_npm=subprocess_npm)
244+
245+
action.execute()
246+
247+
assert not subprocess_npm.run.called
248+
249+
@patch("aws_lambda_builders.workflows.nodejs_npm.npm.SubprocessNpm")
250+
@patch.dict("os.environ", {"SAM_NPM_RUN_TEST_WITH_BUILD": "true"}, clear=True)
251+
def test_raises_action_failed_when_npm_test_fails(self, SubprocessNpmMock):
252+
subprocess_npm = SubprocessNpmMock.return_value
253+
254+
builder_instance = SubprocessNpmMock.return_value
255+
builder_instance.run.side_effect = NpmExecutionError(message="boom!")
256+
257+
action = NodejsNpmTestAction("artifacts", subprocess_npm=subprocess_npm)
258+
259+
with self.assertRaises(ActionFailedError) as raised:
260+
action.execute()
261+
262+
self.assertEqual(raised.exception.args[0], "NPM Failed: boom!")

0 commit comments

Comments
 (0)