Skip to content

Commit 6c0905d

Browse files
devversionalxhub
authored andcommitted
build: wire up integration test rule from shared dev-infra package (angular#44238)
Wires up the integration test rule from the shared dev-infra package, while also deleting the old integration test rule. The readme is updated to reflect the changes that are being made to run with the new integration rule. Overall one major difference is that we will declare the integration test targets within each test directory, making those actual bazel packages. This is more idiomatic within Bazel and also reduces the computation within Skyframe as less globs need to be evaluated for example. PR Close angular#44238
1 parent 6add6a0 commit 6c0905d

File tree

9 files changed

+234
-722
lines changed

9 files changed

+234
-722
lines changed

.pullapprove.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,6 @@ groups:
12391239
'tools/gulp-tasks/**',
12401240
'tools/legacy-saucelabs/**',
12411241
'tools/npm/**',
1242-
'tools/npm_integration_test/**',
12431242
'tools/rxjs/**',
12441243
'tools/saucelabs/**',
12451244
'tools/size-tracking/**',

WORKSPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ node_repositories(
3636
package_json = ["//:package.json"],
3737
)
3838

39-
load("//integration:angular_integration_test.bzl", "npm_package_archives")
39+
load("//integration:npm_package_archives.bzl", "npm_package_archives")
4040

4141
yarn_install(
4242
name = "npm",

integration/BUILD.bazel

Lines changed: 0 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +0,0 @@
1-
load(":angular_integration_test.bzl", "angular_integration_test")
2-
3-
# Some integration ports must be managed manually to be unique and in other
4-
# cases the tests are able to select a random free port.
5-
#
6-
# Where `ng e2e` is used we pass `ng e2e --port 0` which prompts the cli
7-
# to select a random free port for the e2e test. The protractor.conf is
8-
# automatically updated to use this port.
9-
#
10-
# Karma automatically finds a free port so no effort is needed there.
11-
#
12-
# The manually configured ports are as follows:
13-
#
14-
# TEST PORT CONFIGURATION
15-
# ==== ==== =============
16-
# dynamic-compiler 4201 /e2e/browser.config.json: "port": 4201
17-
# hello_world__closure 4202 /e2e/browser.config.json: "port": 4202
18-
# i18n 4204 /e2e/browser.config.json: "port": 4204
19-
# ng_elements 4205 /e2e/browser.config.json: "port": 4205
20-
# platform-server 4206 /src/server.ts: app.listen(4206,...
21-
22-
# Map of integration tests to tags.
23-
# A subset of these tests fail or are not meant to be run with ivy bundles. These are tagged
24-
# "view-engine-only".
25-
INTEGRATION_TESTS = {
26-
"bazel": {
27-
"tags": [
28-
# Bazel-in-bazel tests are resource intensive and should not be over-parallized
29-
# as they will compete for the resources of other parallel tests slowing
30-
# everything down. Ask Bazel to allocate multiple CPUs for these tests with "cpu:n" tag.
31-
"cpu:3",
32-
],
33-
},
34-
"cli-elements-universal": {},
35-
"cli-hello-world": {
36-
"commands": "payload_size_tracking",
37-
},
38-
"cli-hello-world-ivy-compat": {
39-
"commands": "payload_size_tracking",
40-
},
41-
"cli-hello-world-ivy-i18n": {
42-
"commands": "payload_size_tracking",
43-
},
44-
"cli-hello-world-ivy-minimal": {
45-
"commands": "payload_size_tracking",
46-
},
47-
"cli-hello-world-lazy": {
48-
"commands": "payload_size_tracking",
49-
},
50-
"dynamic-compiler": {},
51-
"forms": {
52-
"commands": "payload_size_tracking",
53-
},
54-
"hello_world__closure": {
55-
# TODO: Re-enable the payload_size_tracking command:
56-
# We should define ngDevMode to false in Closure, but --define only works in the global scope.
57-
# With ngDevMode not being set to false, this size tracking test provides little value but a lot of
58-
# headache to continue updating the size.
59-
},
60-
"i18n": {},
61-
"injectable-def": {
62-
# This test relies on ESM for running the app in SSR. RxJS added ESM resolution
63-
# support with RXJS v7. We allow the version to be pinned to v7.
64-
# TODO: Remove this and update the test once the project uses RxJS v7, or if rxjs v6 has ESM support.
65-
"pinned_npm_packages": ["rxjs"],
66-
},
67-
"ivy-i18n": {},
68-
"trusted-types": {},
69-
"ng-add-localize": {},
70-
"ng_elements": {},
71-
"ng_update": {},
72-
"ng_update_migrations": {},
73-
"ngcc": {
74-
"use_view_engine_packages": [
75-
"@angular/animations",
76-
"@angular/common",
77-
"@angular/core",
78-
"@angular/forms",
79-
"@angular/platform-browser",
80-
"@angular/platform-browser-dynamic",
81-
"@angular/platform-server",
82-
"@angular/router",
83-
],
84-
},
85-
"platform-server": {},
86-
"service-worker-schema": {},
87-
# The `side-effects` test is currently disabled as it does not run the
88-
# Angular linker plugin and therefore partial declarations are retained
89-
# as side-effects. To make this test helpful again, we need to run the linker.
90-
# TODO(devversion): replace this with a solution we maintain that runs the Babel linker plugin.
91-
"side-effects": {"tags": ["manual"]},
92-
"terser": {},
93-
"typings_test_rxjs7": {
94-
# The project root uses an older version than the one we want to test here.
95-
"pinned_npm_packages": ["rxjs"],
96-
},
97-
"typings_test_ts44": {
98-
# Special case for `typings_test_ts44` test as we want to pin
99-
# `typescript` at version 4.4.x for that test and not link to the
100-
# root @npm//typescript package.
101-
"pinned_npm_packages": ["typescript"],
102-
},
103-
"typings_test_ts45": {
104-
# Special case for `typings_test_ts45` test as we want to pin
105-
# `typescript` at version 4.5.x for that test and not link to the
106-
# root @npm//typescript package.
107-
"pinned_npm_packages": ["typescript"],
108-
},
109-
}
110-
111-
[
112-
angular_integration_test(
113-
name = test_folder,
114-
commands = INTEGRATION_TESTS[test_folder].get("commands", "default"),
115-
pinned_npm_packages = INTEGRATION_TESTS[test_folder].get("pinned_npm_packages", []),
116-
tags = INTEGRATION_TESTS[test_folder].get("tags", []),
117-
use_view_engine_packages = INTEGRATION_TESTS[test_folder].get("use_view_engine_packages", []),
118-
)
119-
for test_folder in INTEGRATION_TESTS
120-
]

integration/README.md

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,48 @@ The downside of this is that this will apply to all tests and not just the resou
9090
Two of the integration tests that run Bazel-in-Bazel are particularly resource intensive and are tagged "manual" and "exclusive". To run these tests use,
9191

9292
```
93-
yarn bazel test //integration:bazel_test
94-
yarn bazel test //integration:bazel-schematics_test
93+
yarn bazel test //integration/bazel:test
94+
yarn bazel test //integration/cli-hello-world-ivy-minimal:test
9595
```
9696

9797
## Adding a new integration test
9898

9999
When adding a new integration test, follow the steps below to add a bazel test target for the new test.
100100

101-
1. Add new test to `INTEGRATION_TESTS` object in `/integration/BUILD.bazel` (and tag as `"view-engine-only"` if not meant to be run against ivy bundles).
102-
2. If test requires ports and does not support ethereal ports then make sure the port is unique and add it to the "manually configured ports" comment to document which port it is using
101+
1. Add a build file using the `ng_integration_test` rule from `//integration:index.bzl`.
102+
2. If test requires ports and does not support ethereal ports then make sure the port is unique and add it to the "manually configured ports" section to document which port it is using
103103
3. Add at least the following two entries `.bazelignore` (as they may contain BUILD files)
104104
1. `integration/new_test/node_modules`
105105
2. `integration/new_test/.yarn_local_cache`
106106
4. Add any other untracked folders to `.bazelignore` that may contain `BUILD` files
107-
5. If there are tracked BUILD files in the integration test folder (`integration/bazel` has these for example) add those folders to the `build --deleted_packages` and `query --deleted_packages` lines in `.bazelrc`
107+
5. If there are BUILD files in the integration test folder (except for the top-level one defining the test), add those folders to the `--deleted_packages` in the `.bazelrc`. An example is the `bazel` integration test.
108+
109+
## Manually configured ports
110+
111+
Some integration ports must be managed manually to be unique and in other
112+
cases the tests are able to select a random free port.
113+
114+
Where `ng e2e` is used we pass `ng e2e --port 0` which prompts the cli
115+
to select a random free port for the e2e test. The protractor.conf is
116+
automatically updated to use this port.
117+
118+
Karma automatically finds a free port so no effort is needed there.
119+
120+
The manually configured ports are as follows:
121+
122+
| TEST | PORT | CONFIGURATION |
123+
| ---------------------------- | ---------------- | -------------------------------------- |
124+
| dynamic-compiler | 4201 | /e2e/browser.config.json: "port": 4201 |
125+
| hello_world__closure | 4202 | /e2e/browser.config.json: "port": 4202 |
126+
| i18n | 4204 | /e2e/browser.config.json: "port": 4204 |
127+
| ng_elements | 4205 | /e2e/browser.config.json: "port": 4205 |
128+
| platform-server | 4206 | /src/server.ts: app.listen(4206,... |
129+
130+
**Note**: This will become obsolete soon once we start running integration tests with RBE and within a sandbox environment.
108131

109132
## Browser tests
110133

111-
For integration tests we use the puppeteer provisioned version of Chrome. For both Karma and Protractor tests we set a number of browser testing flags. To avoid duplication, they will be listed and explained here and the code will reference this file for more information.
134+
For integration tests we use the Bazel-managed versions of `chromium`. For both Karma and Protractor tests we set a number of browser testing flags. To avoid duplication, they will be listed and explained here and the code will reference this file for more information.
112135

113136
### No Sandbox: --no-sandbox
114137

@@ -144,9 +167,10 @@ See: https://stackoverflow.com/questions/50642308/webdriverexception-unknown-err
144167

145168
If size regression occurs, one way to debug is to get a build which shows the code before and after. Here are the steps to do that.
146169

147-
1. Check out both the `master` branch as well as the your change (let's refer to it as `change` branch) into two different working locations. (A suggested way to do this is using `git worktree`.)
170+
1. Check out both the `master` branch as well as your change (let's refer to it as `change` branch) into two different working locations. (A suggested way to do this is using `git worktree`.)
148171
2. In both `master` and `change` locations update the failing tests `package.json` with `NG_BUILD_DEBUG_OPTIMIZE=minify` environment variable so that the resulting build would contain a human readable but optimized output. As an example:
149172
- Open `integration/cli-hello-world/package.json` and prefix `NG_BUILD_DEBUG_OPTIMIZE=minify` into the `build` rule. Resulting in something like: `"build": "NG_BUILD_DEBUG_OPTIMIZE=minify ng build --prod",`
150-
- Run `bazel run //integration:cli-hello-world_test.debug` to build the output. (optionally just run `yarn build` in the directory if you want to do a quick rebuild which will only pick up changes to the test application (not framework).)
173+
- Run `bazel test //integration/cli-hello-world:test --test_output=streamed --cache_test_results=no` to run the test.
174+
- Open the test temporary directory as printed out by Bazel.
151175
- Diff the `master` vs `change` to see the differences. `myDiffTool change/integration/cli-hello-world/dist/main-es2015.*.js master/integration/cli-hello-world/dist/main-es2015.*.js`
152176
- The above should give you a better understanding as to what has changed and what is causing the regression.

integration/index.bzl

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Copyright Google LLC All Rights Reserved.
2+
#
3+
# Use of this source code is governed by an MIT-style license that can be
4+
# found in the LICENSE file at https://angular.io/license
5+
"""Angular integration testing
6+
"""
7+
8+
load("//integration:npm_package_archives.bzl", "NPM_PACKAGE_ARCHIVES", "npm_package_archive_label")
9+
load("@npm//@angular/dev-infra-private/bazel/integration:index.bzl", "integration_test")
10+
11+
# The generated npm packages should ALWAYS be replaced in integration tests
12+
# so we pass them to the `check_npm_packages` attribute of npm_integration_test
13+
FRAMEWORK_PACKAGES = [
14+
"@angular/animations",
15+
"@angular/bazel",
16+
"@angular/benchpress",
17+
"@angular/common",
18+
"@angular/compiler",
19+
"@angular/compiler-cli",
20+
"@angular/core",
21+
"@angular/elements",
22+
"@angular/forms",
23+
"@angular/language-service",
24+
"@angular/localize",
25+
"@angular/platform-browser",
26+
"@angular/platform-browser-dynamic",
27+
"@angular/platform-server",
28+
"@angular/router",
29+
"@angular/service-worker",
30+
"@angular/upgrade",
31+
"zone.js",
32+
]
33+
34+
def _ng_integration_test(name, setup_chromium = False, **kwargs):
35+
"Set defaults for the npm_integration_test common to the angular repo"
36+
payload_size_tracking = kwargs.pop("payload_size_tracking", [])
37+
pinned_npm_packages = kwargs.pop("pinned_npm_packages", [])
38+
use_view_engine_packages = kwargs.pop("use_view_engine_packages", [])
39+
toolchains = kwargs.pop("toolchains", [])
40+
environment = kwargs.pop("environment", {})
41+
data = kwargs.pop("data", [])
42+
43+
data += [
44+
# The Yarn files also need to be part of the integration test as runfiles
45+
# because the `yarn_bin` target is not a self-contained standalone binary.
46+
"@nodejs//:yarn_files",
47+
]
48+
49+
if setup_chromium:
50+
data += ["@npm//@angular/dev-infra-private/bazel/browsers/chromium"]
51+
toolchains += ["@npm//@angular/dev-infra-private/bazel/browsers/chromium:toolchain_alias"]
52+
environment.update({
53+
"CHROMEDRIVER_BIN": "$(CHROMEDRIVER)",
54+
"CHROME_BIN": "$(CHROMIUM)",
55+
})
56+
57+
# By default run `yarn install` followed by `yarn test` using the tools linked
58+
# into the integration tests (using the `tool_mappings` attribute).
59+
commands = [
60+
"yarn install --cache-folder ./.yarn_local_cache",
61+
"yarn test",
62+
]
63+
64+
command_type = kwargs.pop("commands", "default")
65+
66+
if command_type == "payload_size_tracking":
67+
commands += [
68+
"yarn build",
69+
# TODO: Replace the track payload-size script with a RBE and Windows-compatible script.
70+
"$(rootpath //:scripts/ci/track-payload-size.sh) %s dist/*.js true $${RUNFILES}/angular/$(rootpath //goldens:size-tracking/integration-payloads.json)" % name,
71+
]
72+
data += [
73+
"//goldens:size-tracking/integration-payloads.json",
74+
"//:scripts/ci/track-payload-size.sh",
75+
"//:scripts/ci/payload-size.sh",
76+
"//:scripts/ci/payload-size.js",
77+
]
78+
79+
# Complete list of npm packages to override in the test's package.json file mapped to
80+
# tgz archive to use for the replacement. This is the full list for all integration
81+
# tests. Any given integration does not need to use all of these packages.
82+
npm_packages = {}
83+
for pkg in NPM_PACKAGE_ARCHIVES:
84+
if pkg not in pinned_npm_packages:
85+
npm_packages["@npm//:" + npm_package_archive_label(pkg)] = pkg
86+
for pkg in FRAMEWORK_PACKAGES:
87+
# If the generated Angular framework package is listed in the `use_view_engine_packages`
88+
# list, we will not use the local-built NPM package, but instead map to the
89+
# corresponding View Engine v12.x package from the `@npm//` workspace.
90+
if pkg in use_view_engine_packages:
91+
npm_packages["@npm//:" + npm_package_archive_label("%s-12" % pkg)] = pkg
92+
else:
93+
last_segment_name = pkg.split("/")[-1]
94+
npm_packages["//packages/%s:npm_package_archive" % last_segment_name] = pkg
95+
96+
integration_test(
97+
name = name,
98+
commands = commands,
99+
npm_packages = npm_packages,
100+
tags = kwargs.pop("tags", []) + [
101+
# `integration` tag is used for filtering out these tests from the normal
102+
# developer workflow
103+
"integration",
104+
# Integration tests do not work inside of a sandbox as they may run host applications such
105+
# as chrome (which is run by ng) that require access to files outside of the sandbox.
106+
"no-sandbox",
107+
# Remote doesn't work as it needs network access right now
108+
"no-remote-exec",
109+
],
110+
data = data,
111+
environment = environment,
112+
toolchains = toolchains,
113+
tool_mappings = {
114+
"@nodejs//:yarn_bin": "yarn",
115+
"@nodejs//:node_bin": "node",
116+
},
117+
# 15-minute timeout
118+
timeout = "long",
119+
# Tells bazel that this test should be allocated a large amount of memory.
120+
# See https://docs.bazel.build/versions/2.0.0/be/common-definitions.html#common-attributes-tests.
121+
size = "enormous",
122+
**kwargs
123+
)
124+
125+
def ng_integration_test(name, **kwargs):
126+
"Sets up the integration test target based on the test folder name"
127+
128+
native.filegroup(
129+
name = "_%s_sources" % name,
130+
srcs = native.glob(
131+
include = ["**/*"],
132+
exclude = [
133+
"node_modules/**",
134+
".yarn_local_cache/**",
135+
],
136+
),
137+
)
138+
_ng_integration_test(
139+
name = name,
140+
srcs = kwargs.pop("srcs", ["_%s_sources" % name]),
141+
**kwargs
142+
)

0 commit comments

Comments
 (0)