Skip to content

acc: run cmd/workspace/apps/run-local-node locally - #6172

Draft
radakam wants to merge 5 commits into
acc-run-apps-run-local-locallyfrom
acc-run-apps-run-local-node-locally
Draft

acc: run cmd/workspace/apps/run-local-node locally#6172
radakam wants to merge 5 commits into
acc-run-apps-run-local-locallyfrom
acc-run-apps-run-local-node-locally

Conversation

@radakam

@radakam radakam commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Stacked on #6169.

Changes

Re-enable acceptance/cmd/workspace/apps/run-local-node, disabled since #4875 for needing NPM registry access. The app fixture is now a node:http server started directly with node, so nothing is installed at test time and express, --prepare-environment and the 2m/10m timeouts are gone. Ports come from free_port.py, /shutdown ends the connection so the app exits on its own and wait $PID can assert the CLI's exit code, and a failing run reaps both by port.

--debug stays: node debugging is only NODE_OPTIONS=--inspect, so the test asserts the port the CLI reports and that node listens on it — the --debug-port coverage the python sibling drops.

Why

Only the fixture ever needed the registry. npm is out of it too: the rejecting proxy catches npm run contacting registry.npmjs.org for its update notifier, which npm skips when CI is set, so keeping npm would have failed locally only.

radakam added 5 commits August 5, 2026 09:18
The test was disabled in #4765 for using fixed ports and being slow, so
apps run-local has had no coverage on PRs since. Both problems come from the
fixture rather than the command: the ports were hardcoded, and the test asked
for --prepare-environment, which installs the seventeen default app libraries
via uv. That install can no longer work at all, because acceptance tests now
run with UV_OFFLINE and only a handful of vendored wheels.

Ports are now allocated per run from a new acceptance/bin/free_port.py, and the
app is a standard-library HTTP server started directly instead of Flask under a
freshly built venv, so the run needs no package index. The test covers the same
ground otherwise: valueFrom rejection, --entry-point, app.yml env vars, and the
proxy's identity headers.

The --debug variant is dropped because debugpy is only reachable from PyPI. The
debugpy invocation it exercised is asserted in libs/apps/runlocal unit tests.
The fixture answered /shutdown and then called os._exit(0) from inside the
handler, so the response reached the client only because the kernel drained the
socket buffer on exit. An abortive close would surface as a curl failure, and
the script no longer tolerates one: unlike the version this test was modelled
on, it has neither "|| true" on the shutdown request nor on the final wait.
Stopping the serve loop from a second thread closes the connection cleanly and
lets the process exit on its own, which also makes "wait $PID" assert that the
CLI exited zero.

The two ports now go through add_repl.py, so the output tells the proxy port
and the app port apart instead of rendering both as $(port); that makes the
generic 127.0.0.1 replacement dead, so it goes. With a stable placeholder for
the proxy port the test can assert the "To access your app go to" line, which
the previous version only waited for. Both run-local invocations are traced so
each LOG file records the command that produced it.
The trap killed $PID, which is not the CLI: backgrounding "trace" forks a
subshell, so the CLI and the Python app it starts are grandchildren and survive
the script. A failure anywhere after the app comes up left both processes
running, reparented to init, holding the two ports and an open handle on
LOG.run. Windows reaches the same state by another route, because kill
terminates the CLI outright instead of giving it the chance to stop the app, and
there a leaked handle also blocks the temp directory cleanup.

Cleanup now falls back to kill_port.py, which is what this script used before
and what run-local-node still does. It runs only when the script failed: on
success both processes have exited through /shutdown already, and the ports are
free and may have been handed to another test by the time the trap fires.
The trap explained that $PID is a subshell whose CLI and app survive being
killed, then killed $PID anyway. Reaping by port already covers both, so the
kill goes and the comment says why the port is the handle we have.

Also reach the server through self.server in the fixture rather than the
module global declared below the handler.
The test has been disabled since #4875, which took NPM registry access away from
the runners. It needed the registry only for the app fixture: express, and the
--prepare-environment run that installs it.

The fixture is now a standard-library HTTP server started directly with node, so
nothing is installed at test time. /shutdown answers with Connection: close so
server.close() can complete and the app exits on its own, which lets wait $PID
assert that the CLI exited zero. Ports come from free_port.py, a failed run reaps
the app and the CLI by port, and the Timeout overrides go away because the run
takes well under a second rather than 2m.

--debug stays, unlike in the python sibling where it needs debugpy from PyPI:
node debugging is only NODE_OPTIONS=--inspect. The test asserts both the port the
CLI reports and that node listens on it, so --debug-port keeps its coverage.

npm is out of the fixture too. The rejecting proxy catches npm run contacting
registry.npmjs.org for its update notifier, which npm skips when CI is set, so
keeping npm would have failed locally only and needed a config workaround.
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 13a315f

Run: 31004947064

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 291 1095 11:16
🔄​ aws windows 10 4 4 283 1093 17:07
💚​ azure linux 4 4 290 1095 13:24
🔄​ azure windows 2 4 4 290 1093 15:40
💚​ gcp linux 1 5 291 1095 10:51
🔄​ gcp windows 2 1 5 291 1093 12:52
22 interesting tests: 14 flaky, 4 RECOVERED, 4 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestDashboardAssumptions_WorkspaceImport ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestBundleInitHelpers ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAlertsCreateErrWhenNoArguments ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestClustersList ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFsCatDoesNotSupportOutputModeJson ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFsCatForDbfsInvalidScheme ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFsCompletion ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestFsCpFileToDirForWindowsPaths 🙈​s 🔄​f 🙈​s ✅​p 🙈​s ✅​p
🔄​ TestSyncFullFileSync ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p
🔄​ TestSyncIncrementalFileOverwritesFolder ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestSyncIncrementalSyncFileToPythonNotebook ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestSyncIncrementalSyncPythonNotebookToFile ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🔄​ TestSyncNestedFolderSync ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🔄​ TestSyncNestedSpacePlusAndHashAreEscapedSync ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R
Top 33 slowest tests (at least 2 minutes):
duration env testname
6:03 gcp windows TestAccept
6:01 aws windows TestAccept
5:51 azure windows TestAccept
5:19 gcp windows TestFilerWorkspaceFilesExtensionsDelete
4:55 aws windows TestFilerReadWrite/workspace_files
4:08 azure windows TestFilerWorkspaceFilesExtensionsDelete
3:50 aws windows TestImportDir
3:28 azure linux TestImportDirWithOverwriteFlag
3:21 azure linux TestFilerWorkspaceFilesExtensionsDelete
3:08 aws windows TestFilerWorkspaceFilesExtensionsReadDir
3:05 gcp linux TestFilerWorkspaceFilesExtensionsReadDir
3:01 gcp windows TestFilerWorkspaceFilesExtensionsStat
2:59 gcp linux TestAccept
2:59 aws windows TestImportDirDoesNotOverwrite
2:54 azure linux TestAccept
2:51 azure windows TestFilerRecursiveDelete/workspace_files
2:50 aws linux TestAccept
2:49 aws windows TestFilerWorkspaceFilesExtensionsStat
2:47 aws windows TestLock
2:43 gcp linux TestFilerWorkspaceFilesExtensionsDelete
2:38 azure windows TestFilerWorkspaceFilesExtensionsReadDir
2:35 gcp windows TestFilerRecursiveDelete/workspace_files_extensions
2:35 azure windows TestFilerReadWrite/workspace_files_extensions
2:32 gcp windows TestFilerReadWrite/workspace_files_extensions
2:19 aws linux TestFilerRecursiveDelete/workspace_files_extensions
2:13 azure windows TestFilerWorkspaceNotebook/pyNb.py
2:12 aws linux TestFilerWorkspaceNotebook/sqlJupyterNotebook.ipynb
2:12 azure windows TestFilerReadWrite/workspace_files
2:11 gcp windows TestImportDirWithOverwriteFlag
2:04 azure linux TestFilerWorkspaceFilesExtensionsRead
2:04 azure linux TestFilerRecursiveDelete/workspace_files
2:03 azure linux TestFilerWorkspaceNotebook/scalaJupyterNb.ipynb
2:01 azure linux TestImportDirDoesNotOverwrite

@radakam
radakam force-pushed the acc-run-apps-run-local-locally branch from 7da0161 to e1cf319 Compare August 5, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants