Skip to content

Run every root-module package's unit tests on Windows - #2297

Open
schnie wants to merge 5 commits into
v2from
ci-windows-unit-tests
Open

schnie wants to merge 5 commits into
v2from
ci-windows-unit-tests

Conversation

@schnie

@schnie schnie commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Why

The test-windows job's "Run unit tests" step ran under the default pwsh shell. PowerShell splits a native argument at a dot, so -test.v reached go as -test .v. go test treats the unknown -test as the end of the package list (see cmd/go/internal/test/testflag.go): it reads .v as that flag's value and passes ./... to the test binary. That left only the current directory to test, which is the root package. Its one test file is //go:build !windows, so no test binary ran, and the step exited 0.

In the log of run 38066008856, the whole step is one line, github.com/astronomer/astro-cli coverage: 0.0% of statements, after 34s. The same misparse is easy to see on Linux: go test -cover -test .v ./... there builds only the root package and hands .v ./... to its binary. So cmd/, cmd/local and internal/... had never run on Windows.

What

CI

  • The step now runs under bash, like the steps beside it, without -test.v.
  • A check then compares the set of packages go list ./... names with the set that reported a result line (ok, FAIL, "no test files" or a bare coverage line). It fails the step and names any package that is missing.
  • Run against the log of the broken run, that check reports 86 missing packages.

Code bugs found by the first real Windows run

  • openapi.ResolveLocalPath:
    • It turned file:///C:/spec.json into /C:/spec.json, which filepath.Abs then put under the current drive. It now drops the slash before a drive letter. This is a no-op off Windows, because filepath.VolumeName is always empty there.
    • It now percent-decodes the path (%20).
    • It now expands ~\ as well as ~/ on Windows.
  • readSSHKeyFile now normalizes CRLF to LF, so a key saved on Windows reaches git-sync in the form OpenSSH reads.

Tests that assumed Unix

  • otto:
    • otto.exe and the .exe.zip download.
    • The launcher, which Windows copies rather than symlinks. The test now skips if Windows refuses its symlink fixture for lack of the privilege.
    • A cwd helper that expanded the 8.3 short name (RUNNER~1) that DetectAirflow compares against.
  • fileutil:
    • The separator in the home dir.
    • The OS error text; the tests now use ErrorIs(os.ErrNotExist).
    • Tar entry names, which the test expected with backslashes. Tar correctly writes them with slashes.
  • apc deploy: the Dockerfile path in an error message.
  • project: a directory named ..., which Windows strips to an empty name. The test keeps ... elsewhere and uses _._ on Windows.

Fixtures: cmd/apc/testfiles/** is pinned to LF in .gitattributes.

Skipped on Windows: two tests that rely on POSIX mode bits (chmod 000, and a 0600 check). Each skip states the reason.

Follow-up

The go test flags are now spelled three times: the Makefile's test target, the Linux test job and this Windows step. One script that all three call, like scripts/test-submodules.sh already is for the sub-modules, would keep them from drifting. Keeping that script's arguments out of pwsh would also prevent this bug from coming back.

Gates: make test, make lint, make lint-goos, make deadcode, plus GOOS=windows go vet ./... and GOOS=windows go build ./....

The test-windows job's unit-test step ran under the default pwsh shell,
which splits a native argument at a dot: -test.v reached go as -test .v.
go test took the unknown -test as the end of the package list, so it
tested only the root package, which has no Windows test files, and
passed. Every other root-module package went untested on Windows.

Run it under bash like the neighbouring steps, drop -test.v, and fail
the step unless every package go list names reported a result line.

Co-Authored-By: Claude <noreply@anthropic.com>
@coveralls-official

coveralls-official Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 38068524885

Coverage remained the same at 57.675%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 4 uncovered changes across 1 file (10 of 14 lines covered, 71.43%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
pkg/openapi/cache.go 13 9 69.23%
Total (2 files) 14 10 71.43%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 69468
Covered Lines: 40066
Line Coverage: 57.68%
Coverage Strength: 231.93 hits per line

💛 - Coveralls

schnie and others added 4 commits October 10, 2026 12:19
…URLs

The first Windows run of these packages found one code bug and a set of
tests that assumed Unix.

Code: ResolveLocalPath turned file:///C:/spec.json into /C:/spec.json,
which filepath.Abs then put under the current drive. It now drops the
slash before a drive letter.

Tests: paths and error text spelled the Unix way (separators, otto.exe,
the .exe.zip download, "no such file or directory"), tar entry names
built with filepath.Join though Tar writes them slash-separated, a
directory named "..." that Windows strips to nothing, a launcher test
that read a symlink where Windows makes a copy, and a cwd helper that
expanded the 8.3 short name DetectAirflow compares against. The git-sync
fixtures under cmd/apc/testfiles are pinned to LF, and the two tests that
rely on POSIX mode bits skip on Windows.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Compare the set of packages go list names against the set with a result
line, not their counts, and print the missing ones in the error. The
pattern now matches the module path exactly, followed by / or
whitespace, and an empty match reaches the error instead of ending the
step under pipefail.

Co-Authored-By: Claude <noreply@anthropic.com>
…ndows tests

- readSSHKeyFile turns CRLF into LF, so a key saved on Windows reaches
  git-sync in the form OpenSSH reads. A test writes its own CRLF key
  instead of relying on how the checkout ends lines.
- ResolveLocalPath percent-decodes a file:// path before it strips the
  slash in front of a drive letter, and expands ~\ as well as ~/ on
  Windows. Off Windows, file:///C:/spec.json stays /C:/spec.json.
- The ReadFileToString test chooses its branch on the expected error
  alone and requires that an error came back.
- The hostname-fallback test keeps "..." off Windows and uses "_._" only
  on Windows, which strips trailing dots.
- The launcher test skips when Windows refuses the symlink for want of
  the privilege, rather than failing.

Co-Authored-By: Claude <noreply@anthropic.com>
@schnie
schnie marked this pull request as ready for review October 10, 2026 16:45
@schnie
schnie requested a review from a team as a code owner October 10, 2026 16:45

This branch has not been deployed

No deployments
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.

1 participant