Skip to content

test(lib): move matcher Docker fixture to a provider version OpenTofu accepts - #429

Merged
so0k merged 1 commit into
open-constructs:mainfrom
jsteinich:test/matcher-docker-opentofu
Sep 13, 2026
Merged

so0k merged 1 commit into
open-constructs:mainfrom
jsteinich:test/matcher-docker-opentofu

Conversation

@jsteinich

Copy link
Copy Markdown
Contributor

Related issue

Fixes #301

Description

toBeValidTerraform and toPlanSuccessfully shell out to the Terraform-compatible CLI, so the matcher tests cannot run under OpenTofu today — tofu init refuses the Docker provider the fixture pins:

Error while installing kreuzwerker/docker v2.25.0: the provider is not signed with a
valid signing key; please contact the provider author (authentication signature from
unknown issuer)

Terraform installs the same provider as self-signed, which is why this has never shown up in CI.

This is a provider-version problem, not an OpenTofu support gap. Confirmed by running tofu init against minimal HCL, with no CDK involved:

constraint resolves to OpenTofu 1.12.6
~> 2.0 2.25.0 fails — unsigned
~> 3.0 3.9.0 installs
~> 4.0 4.x installs

So the DockerProvider test fixture moves to ~> 3.0.

Why ~> 3.0 rather than ~> 4.0: v3 is the first signed major, and the repo's other Docker fixtures already sit on 3.0.x (@cdktn/provider-schema pins =3.0.2, @cdktn/hcl2cdk pins =3.0.1), so this keeps a single Docker major across the test suite and preserves the floating constraint the fixture already used.

There is no schema fallout: the fixture only touches provider ssh_opts/host and docker_image.name, all unchanged between v2 and v3. No snapshots moved.

The other ~> 2.0 constraint in the same file belongs to the synthetic TestProvider, which declares no terraformProviderSource and never contacts a registry. It is deliberately untouched — it is also the source of the ~300 "~> 2.0" occurrences in packages/cdktn/test/__snapshots__/, which are unrelated to this change.

Testing

Run from packages/cdktn, selecting the CLI with TERRAFORM_BINARY_NAME:

CLI matchers.test.ts full cdktn suite
Terraform 1.14.3 21/21 pass 43 suites, 519 pass / 23 skip, 299 snapshots
Terraform 1.5.7 (oldest in tested) 21/21 pass —
OpenTofu 1.12.6 21/21 pass 43 suites, 519 pass / 23 skip, 299 snapshots

toPlanSuccessfully really does run plan, so these were run with a live Docker daemon.

Scope: this closes the unit matchers only

The language integration matchers are still broken under OpenTofu and are deliberately out of scope. test/{typescript,go,java,csharp,python}/testing-matchers/cdktf.json all pin kreuzwerker/docker@~> 2.0 and hit the identical signing error.

They cannot simply be bumped: every one of those fixtures uses the latest attribute on docker_image, which v3 removed. Fixing them means rewriting fixtures in five languages plus regenerating bindings and assertions — a separate and much larger change, and one that could not be verified without the full integration harness.

Follow-up worth considering

Nothing in CI runs any of this under OpenTofu — every workflow matrix sets TERRAFORM_BINARY_NAME: terraform<version>. So this fix can silently regress. The CI image ships tofu1.12.6, so an OpenTofu leg on the unit matrix would keep #301 closed. That is a different axis from the integration-matrix pinning added in #405.

🤖 Generated with Claude Code

… accepts

The `toBeValidTerraform` and `toPlanSuccessfully` matcher tests shell out to
the Terraform-compatible CLI selected by `TERRAFORM_BINARY_NAME`. Under
OpenTofu they failed at `init`:

  Error while installing kreuzwerker/docker v2.25.0: the provider is not
  signed with a valid signing key (authentication signature from unknown
  issuer)

Terraform installs the same artifact as self-signed, so the tests only broke
once a run used OpenTofu. Confirmed locally with minimal `required_providers`
fixtures: `~> 2.0` resolves to 2.25.0 and fails under OpenTofu 1.12.6 while
`~> 3.0` (3.9.0) and `~> 4.0` install cleanly, and both majors succeed under
Terraform.

Picked `~> 3.0` because the repo's other kreuzwerker/docker fixtures
(provider-schema, hcl2cdk) already sit on 3.0.x, so this keeps a single
Docker provider major across the test suite, and it keeps the floating
constraint style the fixture already used.

No schema fallout: the fixture only uses provider `ssh_opts`/`host` and
`docker_image.name`, all unchanged between v2 and v3, so `validate` and
`plan` pass unmodified and no snapshots move. The `~> 2.0` pins on the
synthetic `test` provider are a different provider and are left alone.

The language integration fixtures under `test/*/testing-matchers` still pin
`kreuzwerker/docker@~> 2.0` and hit the same signing error under OpenTofu,
but they use `docker_image.latest`, removed in v3, so bumping them needs
fixture rewrites in five languages plus regenerated bindings. Tracked
separately rather than folded in here.

Refs open-constructs#301

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jsteinich
jsteinich marked this pull request as ready for review September 12, 2026 16:34
@jsteinich
jsteinich requested a review from a team as a code owner September 12, 2026 16:34
@so0k
so0k merged commit 7b0da12 into open-constructs:main Sep 13, 2026
261 checks passed
so0k pushed a commit that referenced this pull request Sep 17, 2026
….0 (#440)

### Related issue

Last remaining `kreuzwerker/docker` 2.x pin in the test suite, after
#429 and #436. Same root cause as #301.

### Description

`test/python/providers/cdktf.json` pinned `kreuzwerker/docker@= 2.16.0`,
which OpenTofu rejects:

```
Error while installing kreuzwerker/docker v2.16.0: the provider is not signed with a
valid signing key
```

Pinned **exactly** rather than floating, because the snapshot embeds the
resolved version — a `~> 3.0` pin here would make the snapshot drift
whenever a new 3.x ships. 3.9.0 is the latest 3.x, so this agrees with
what the `~> 3.0` pins elsewhere in the suite resolve to.

### The signing boundary is mid-3.x, not at the major

Worth recording, because #429 and #436 both say "v3 is the first signed
major" and **that is wrong**. Verified against OpenTofu 1.12.6:

| version | result |
| --- | --- |
| 3.0.1, 3.0.2, 3.2.0, 3.3.0, 3.5.0, 3.6.0 | rejected — not signed with
a valid signing key |
| 3.7.0, 3.8.0, 3.9.0 | `Installed … (signed, key ID 0DCE698927DAF8EC)`
|

So an exact pin anywhere below 3.7.0 would not have fixed anything. This
matters for #436 in particular: it is correct in practice only because
`~> 3.0` floats up to a signed release, not because v3 is signed.

It also means the `=3.0.2` pin in `@cdktn/provider-schema` and `=3.0.1`
in `@cdktn/hcl2cdk` are both unsigned versions. Neither breaks the
OpenTofu unit axis in #439 — `provider-schema`'s `read` suite is
`describe.skip`'d, and `hcl2cdk` is not tagged `unit-test:terraform` —
but they are latent.

### No code change needed

Every attribute the fixture uses survives the major, checked against
both schemas rather than assumed:

- `docker_image` keeps `repo_digest` and `keep_locally`
- `docker_container` keeps `privileged`
- `capabilities` and `ports` are unchanged in nesting mode (`set` max 1,
`list`), cardinality and attribute types — so the
`tolist(...capabilities[0].add)` rendering in the snapshot still holds

The only snapshot change is the version string, in its HCL and JSON
forms.

### Testing

Not run locally — this is an integration test needing `pnpm package` and
`pipenv`, which is unavailable on this machine. CI is the verification.

Verified locally: both provider schemas compared attribute-by-attribute
for everything the fixture touches, and the signing table above against
a real OpenTofu 1.12.6 binary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
jsteinich added a commit to jsteinich/cdk-terrain that referenced this pull request Sep 17, 2026
open-constructs#301 was a unit-level failure - the matcher fixture pinned a Docker provider
version OpenTofu rejects - and open-constructs#429 fixed it, but nothing in CI exercises
those tests under tofu, so it can regress silently. This closes that.

One matrix entry, because the job is already scoped: `affected_terraform`
runs `nx affected -t test --exclude='*,!tag:unit-test:terraform'`, so it only
touches the four projects tagged as terraform-dependent - cdktn,
@cdktn/cli-core, @cdktn/provider-generator and @cdktn/provider-schema. The
packages that never invoke a CLI are already excluded, so the OpenTofu entry
costs one job rather than a full duplicate of the unit suite.

The provider schema cache is keyed by binary rather than version, since tofu
and terraform fetch schemas from different registries.

Deliberately not extended to release.yml's unit fan-outs: those are a
package x version cross-product with no tag filter, so an OpenTofu entry
there would also run hcl2cdk, hcl2json and cdktn-cli under tofu, none of
which touch a CLI. Scoping that properly is a larger change than it is worth
before this entry has proven itself on PRs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jsteinich added a commit to jsteinich/cdk-terrain that referenced this pull request Sep 17, 2026
open-constructs#301 was a unit-level failure - the matcher fixture pinned a Docker provider
version OpenTofu rejects - and open-constructs#429 fixed it, but nothing in CI exercises
those tests under tofu, so it can regress silently. This closes that.

One matrix entry, because the job is already scoped: `affected_terraform`
runs `nx affected -t test --exclude='*,!tag:unit-test:terraform'`, so it only
touches the four projects tagged as terraform-dependent - cdktn,
@cdktn/cli-core, @cdktn/provider-generator and @cdktn/provider-schema. The
packages that never invoke a CLI are already excluded, so the OpenTofu entry
costs one job rather than a full duplicate of the unit suite.

The provider schema cache is keyed by binary rather than version, since tofu
and terraform fetch schemas from different registries.

Deliberately not extended to release.yml's unit fan-outs: those are a
package x version cross-product with no tag filter, so an OpenTofu entry
there would also run hcl2cdk, hcl2json and cdktn-cli under tofu, none of
which touch a CLI. Scoping that properly is a larger change than it is worth
before this entry has proven itself on PRs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jsteinich added a commit that referenced this pull request Sep 17, 2026
#436)

### Related issue

Follow-up to #429 / #301, which moved the `cdktn` unit matcher fixture
off Docker provider 2.x. The five language integration matchers were
left out of that PR; this does them.

### Description

`test/{typescript,go,java,csharp,python}/testing-matchers/cdktf.json`
pinned `kreuzwerker/docker@~> 2.0`, which resolves to 2.25.0 and fails
under OpenTofu:

```
Error while installing kreuzwerker/docker v2.25.0: the provider is not signed with a
valid signing key; please contact the provider author (authentication signature from
unknown issuer)
```

`~> 3.0` floats to the latest 3.x, which is signed, and v3 is what the
rest of the suite already uses — `@cdktn/provider-schema` pins `=3.0.2`,
`@cdktn/hcl2cdk` pins `=3.0.1`, and #429 moved the unit fixture to `~>
3.0`.

Only Go needed a code change: `docker_image.latest` was removed in v3,
and Go was the only fixture using it. `dockerImage.Latest()` becomes
`dockerImage.Name()`, which is what the Python, Java and C# fixtures
already pass for the container image. TypeScript passes a literal string
and is unchanged. (The `"nginx:latest"` strings elsewhere are image
tags, not that attribute.)

Confirmed against the real v3 schema rather than release notes:

```
docker_image attributes (v3): force_remove, id, image_id, keep_locally, name,
                              platform, pull_triggers, repo_digest, triggers
has latest? false
```

There are no snapshots under `test/*/testing-matchers/`, and the harness
asserts only that the language-side run reports `PASS`, so there is no
expected-output churn.

### Testing

Not run locally — these need `pnpm package` plus the go, dotnet, java
and python toolchains and a live Docker daemon. CI is the verification.

Verified locally: the v3 schema above, that Go was the only fixture
using the removed attribute, and that no `docker@~> 2` pin remains under
`test/*/testing-matchers/`.

### Out of scope

`test/python/providers/cdktf.json` pins `kreuzwerker/docker@= 2.16.0`
and has the same problem — separate PR.

`@cdktn/hcl2cdk`'s `~>2.15.0` and inline `2.14.0` HCL in
`convertProject.test.ts` stay as they are: those are v2-era HCL
**inputs**, and converting legacy HCL is the point of that test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


### Correction: the signing boundary is mid-3.x

While doing the same bump for `test/python/providers` (#440) it turned
out that "v3 is the first signed major" — which #429 also states — is
wrong. Against OpenTofu 1.12.6: 3.0.1, 3.0.2, 3.2.0, 3.3.0, 3.5.0 and
3.6.0 are all rejected as unsigned; 3.7.0, 3.8.0 and 3.9.0 install
signed with key `0DCE698927DAF8EC`.

This PR is still correct, but for a narrower reason than stated: `~>
3.0` resolves to the newest 3.x, which is signed. A pin below 3.7.0
would not have worked.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
jsteinich added a commit that referenced this pull request Sep 17, 2026
### Related issue

Closes the CI gap left by #429 / #301. **Stacked on #438** — merge that
first; this branch contains its commit.

### Description

#301 was a unit-level failure: the matcher fixture pinned a Docker
provider version OpenTofu rejects as unsigned. #429 fixed it — but
nothing in CI runs those tests under `tofu`, so it can regress silently
and we would not know.

One matrix entry on `affected_terraform`:

```yaml
- terraform_version: "1.12.6"
  terraform_binary: tofu1.12.6
```

**That is already scoped, which is why it costs one job rather than a
second copy of the unit suite.** The job runs:

```
nx affected -t test --exclude='*,!tag:unit-test:terraform'
```

so it only touches the four projects tagged terraform-dependent —
`cdktn`, `@cdktn/cli-core`, `@cdktn/provider-generator`,
`@cdktn/provider-schema`. Those are exactly the packages whose tests
shell out to a CLI; `cdktn-cli`, `hcl2cdk` and `hcl2json` invoke none
and are already excluded.

The provider schema cache moves from being keyed by version to by binary
— tofu and terraform fetch schemas from different registries and must
not share an entry.

### Cost

One extra job on `depot-ubuntu-24.04-16`, only when a terraform-tagged
project is affected. For comparison, a full OpenTofu leg on the
integration matrix would be +77 jobs and roughly +115 runner-minutes.

### Deliberately not extended to `release.yml`

Its two `unit.yml` fan-outs are a package × version cross-product with
**no tag filter**, so an OpenTofu entry there would also run `hcl2cdk`,
`hcl2json` and `cdktn-cli` under tofu — none of which touch a CLI.
Scoping that properly is a larger change, and worth doing only once this
entry has proven itself on PRs.

### Testing

CI on this PR is the verification, and it is the interesting part: this
is the first time the `cdktn` unit tests — including the #429 matcher
fixture — run against OpenTofu in CI. If #429 were wrong, this job is
what would say so.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
jsteinich added a commit to jsteinich/cdk-terrain that referenced this pull request Oct 3, 2026
…versions

Sweep for the last pins OpenTofu rejects, after open-constructs#429, open-constructs#436 and open-constructs#440. Every
kreuzwerker/docker reference in the repo is now on a signed version; a check
of every other pinned provider in these fixtures - hashicorp aws, null,
google, azuread, local, kubernetes, external, alexkappa/auth0,
DataDog/datadog - found all of them already fine, so docker was the only
affected provider.

Active fixture:

- @cdktn/hcl2cdk's globalSetup.ts and helpers/convert.ts generate bindings
  from =3.0.1. These run today; hcl2cdk simply is not tagged unit-test:
  terraform, so nothing exercises them under tofu yet.

Skipped fixtures, fixed so they are not a trap for whoever re-enables them:

- @cdktn/provider-schema's read.test.ts pinned =3.0.2. Its cache-key string
  embeds the version and has been moved in step, or the enabled-cache test
  would have looked up a key that no longer matches its constraint.
- @cdktn/hcl2cdk's convertProject.test.ts needed more than a bump. Its
  fixture HCL reads docker_image.ubuntu.latest, and `latest` was removed in
  provider v3, so the input itself had to change to `.name` - the same
  substitution open-constructs#436 made in the Go matcher fixture. Worth a look during
  review: it slightly reduces how "legacy" that legacy-HCL fixture is.

Not verified locally: anything touching hcl2cdk. Its globalSetup shells out
to `cdktn init --dist`, which needs `pnpm package`, and rsync is unavailable
on this machine. provider-schema passes (6 suites, 58 tests, 10 snapshots).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
so0k pushed a commit that referenced this pull request Oct 7, 2026
…versions (#459)

### Related issue

Final sweep of the `kreuzwerker/docker` pins OpenTofu rejects, after
#429, #436 and #440.

### Description

Every `kreuzwerker/docker` reference in the repo is now on a signed
version. I also checked every *other* pinned provider in these fixtures
under OpenTofu 1.12.6 — `hashicorp/aws 5.11.0`, `null 3.2.1`, `google
4.55.0`, `azuread 2.36.0`, `local 2.3.0`, `kubernetes 2.18.0`, `external
2.3.1`, `alexkappa/auth0 0.26.2`, `DataDog/datadog 3.21.0` — all install
cleanly, so docker was the only affected provider.

**Active fixture**

`@cdktn/hcl2cdk`'s `globalSetup.ts` and `helpers/convert.ts` generated
bindings from `=3.0.1`. These run today — `hcl2cdk` simply is not tagged
`unit-test:terraform`, so nothing exercises them under tofu yet.

**Skipped fixtures**, fixed so they are not a trap for whoever
re-enables them:

- `@cdktn/provider-schema`'s `read.test.ts` pinned `=3.0.2`. Its
**cache-key string embeds the version**
(`kreuzwerker%2Fdocker@%3D3.0.2`) and moves in step — otherwise the
enabled-cache test would look up a key that no longer matches its
constraint.
- `@cdktn/hcl2cdk`'s `convertProject.test.ts` needed more than a bump.
Its fixture HCL reads `docker_image.ubuntu.latest`, and `latest` was
**removed in provider v3**, so the input itself had to change to `.name`
— the same substitution #436 made in the Go matcher fixture.

### Worth a look during review

The `convertProject` change edits the HCL being converted, not just a
version. That fixture exists to exercise conversion of older
configurations, so swapping a v2-only attribute out makes it slightly
less "legacy". It is `describe.skip`'d today, so nothing depends on the
current behaviour — but if the legacy shape is the point, the
alternative is leaving it pinned to an unsigned version and accepting
that it can never run under OpenTofu.

### Testing

`@cdktn/provider-schema`: 6 suites / 58 tests / 10 snapshots pass.

**Not verified locally:** anything touching `hcl2cdk`. Its `globalSetup`
shells out to `cdktn init --dist`, which requires `pnpm package`, and
`rsync` is unavailable on this machine. CI covers it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

I'm going to lock this pull request because it has been closed for 30 days. This helps our maintainers find and focus on the active issues. If you've found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Oct 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(tofu): Track OpenTofu provider signing support in matcher tests

2 participants