Skip to content

test(vpn): add default render helm unit tests - #4347

Merged
IvanHunters merged 1 commit into
cozystack:mainfrom
magic-peach:test/vpn-helm-unittest
Sep 22, 2026
Merged

IvanHunters merged 1 commit into
cozystack:mainfrom
magic-peach:test/vpn-helm-unittest

Conversation

@magic-peach

@magic-peach Akanksha Trehun (magic-peach) commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

vpn was one of the eight user-facing apps in packages/apps/ called out in #3631 as shipping with zero helm-unittest coverage. This adds a tests/ suite pinning the default render and wires the standard test: helm unittest . target the sibling charts already use, following the same pattern as #4081, #4074 and #4093.

Ran helm unittest . locally against the chart, it passes. make show needs a live cluster connection through cozyhr, which was not available in this environment, so I relied on helm unittest for local verification, same as the referenced sibling PRs.

Screenshots

Not applicable, test-only change.

Downstream repositories

Walked the trigger map in docs/agents/contributing.md against the diff: this only adds a test file and a Makefile target inside an existing package, it does not add, rename or remove a package, and it does not touch values.yaml, values.schema.json, Chart.yaml or README.md, so none of the listed triggers apply.

Release note

test(vpn): add Helm unit test coverage for the default render

Summary by CodeRabbit

  • Tests

    • Added automated validation for the VPN deployment’s default configuration, including replica count, container image, service port, and generated resource naming.
  • Chores

    • Added a convenient command for running the VPN chart’s automated tests.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@github-actions github-actions Bot added size/M This PR changes 30-99 lines, ignoring generated files area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) labels Sep 19, 2026
@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration

Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 379293bd-955e-41d2-8acd-88f62f712c42

📥 Commits

Reviewing files that changed from the base of the PR and between 2bcaddf and 422b6f6.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: e4d79271-f1f8-4b16-ab94-9e50f99e93c1

📥 Commits

Reviewing files that changed from the base of the PR and between 8799a4e and 2bcaddf.

📒 Files selected for processing (2)
  • packages/apps/vpn/Makefile
  • packages/apps/vpn/tests/vpn_test.yaml

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The VPN chart now includes a Helm unit test suite. The Makefile adds a test target that runs the suite. The test validates the rendered Deployment’s identity, replica count, image, and container port.

Changes

VPN Helm chart tests

Layer / File(s) Summary
Helm test execution and rendering assertions
packages/apps/vpn/tests/vpn_test.yaml, packages/apps/vpn/Makefile
The test loads the Deployment and Secret templates and validates the default VPN Deployment rendering. The Makefile adds a phony test target that runs helm unittest ..

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Other

Suggested reviewers: kvaps

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding default-render Helm unit tests for the VPN chart.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Akanksha Trehun (@magic-peach) LGTM. The tests can go red: I broke the chart once per assertion, and each of the six assertions failed alone, the one I had predicted before the run.

Business context: vpn is one of the eight tenant-facing apps #3631 lists without helm-unittest coverage. This PR pins its default Deployment render and adds the test: target the CI sweep looks for.

The mutations were a second copy of the Deployment document (only hasDocuments fails), then the kind, name, replicas, image and containerPort. Each one failed only its own assertion.

The comment at the top of the suite is correct. Without templates/secret.yaml in templates:, the render errors at the checksum/config include on templates/deployment.yaml:19. Without the _namespace.host value, templates/secret.yaml:1 errors on a nil pointer. So both are needed.

CI will reach the suite. The Unit & controller tests job runs make unit-tests, which calls hack/helm-unit-tests.sh. That script runs every package where make -n test succeeds. At head the probe prints helm unittest ., and make -C packages/apps/vpn test prints the Test Suites: 1 passed line the script checks for. Against current main (41ef4a6) the branch merges cleanly, main has no test target for vpn, and the suite passes on the merged tree.

The image pin that blocked #4074 is not a problem here. quay.io/outline/shadowbox:stable is hardcoded at templates/deployment.yaml:45, outside every file the release tooling rewrites, and the test file has no rc version.

CI has not run the suite yet: Pre-Commit Checks and Pull Request wait for a maintainer to approve the fork run. I ran it locally with helm v4.3.0 and helm-unittest 1.1.1.

Two non-blocking notes:

  1. The description says the suite pins "the default render", but it asserts only the Deployment. The PR body becomes the merge commit message here, so "the default Deployment render" would be exact. The CodeRabbit summary in the same body also calls the pinned containerPort a "service port".
  2. Nothing pins the password carry-over in templates/secret.yaml. On upgrade it reads the existing <release>-vpn Secret and keeps each user's password, so their clients keep working. Deleting line 10 leaves this suite green. A case with users: {alice: {}} and a kubernetesProvider fixture holding an existing shadowbox_config.json fails on exactly that; I tried it locally.

vpn was one of the remaining user-facing apps with no
helm-unittest coverage.

Signed-off-by: Akanksha Trehun <[email protected]>

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

LGTM with non-blocking notes: every asserted value is live and the target really runs in CI. The coverage is narrower than the title claims, though. Two of the chart's six templates get rendered, one gets asserted.

Findings

  • [MINOR] packages/apps/vpn/tests/vpn_test.yaml:6, the suite-level templates: list scopes rendering, not just assertions
  • [MINOR] packages/apps/vpn/tests/vpn_test.yaml:20, the four assertions all read the Deployment's own fields, so the chart's cross-file couplings stay uncovered

Claim mismatches

[PARTIAL] "Helm unit test coverage for the default render": one of six templates is asserted, two of six are rendered.

Caveats

  • I broke each asserted value in turn: the replicas default 2 to 3, the image tag, containerPort, the Deployment name. Each one reddened the suite, so nothing here is theatre. The header comment about secret.yaml is accurate too: drop it from the list and deployment.yaml:19 fails on its include.
  • Rendered output is unchanged against the merge base on the four corners I ran. The only difference comes from tls.yaml calling genCA / genSignedCert, which already differs between two renders of one revision.
  • The sweep does pick the new target up. The Unit & controller tests job on this head logs Running tests in packages/apps/vpn and then PASS vpn default render.

Follow-ups

  • #4081, #4074 and #4093 ship the same single-suite shape, so whatever is decided here applies to all four.
  • Something this suite could grow into, pre-existing and uncovered today: users map keys carry no constraint in values.schema.json (additionalProperties, no key pattern), and a key holding a double quote breaks the render outright. A tenant reaches that through the aggregated API. Worth a schema constraint plus a negative case here.
$ helm template vpn-test . --namespace tenant-test --set _namespace.host=example.com --set 'users.alice.password=hackme' | grep '"name"'
          "name": "alice",
$ helm template vpn-test . --namespace tenant-test --set _namespace.host=example.com --set 'users.bad\"key.password=hackme'
Error: YAML parse error on vpn/templates/secret.yaml: error converting YAML to JSON: yaml: line 6: did not find expected key

# Both templates are loaded so the Deployment's checksum/config annotation can
# resolve its include of secret.yaml; template: pins assertions to the
# Deployment document alone.
templates:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MINOR] the suite-level templates: list scopes rendering, not just assertions

Only deployment.yaml and secret.yaml are listed, and helm-unittest does not render what is absent from that list. A render-breaking edit to service.yaml, tls.yaml, workloadmonitor.yaml or dashboard-resourcemap.yaml therefore passes. vpn has no bats or chainsaw suite, and the repo runs no chart-wide helm template / helm lint gate, so those four templates still have no automated render coverage after this PR.

# templates/service.yaml: internalTrafficPolicy: Cluster
#                      -> internalTrafficPolicy: {{ .Values.doesNotExist.field }}
$ cd packages/apps/vpn && helm unittest .
 PASS  vpn default render	tests/vpn_test.yaml
Charts:      1 passed, 1 total

Listing all six templates fixes it, and I ran that: the suite stays green on the clean tree and the same edit then reddens.

$ cd packages/apps/vpn && helm unittest .    # six templates listed, service.yaml broken
 FAIL  vpn default render	tests/vpn_test.yaml
		Error: template: vpn/templates/service.yaml:35:35: executing "vpn/templates/service.yaml" at <.Values.doesNotExist.field>: nil pointer evaluating interface {}.field
Charts:      1 failed, 0 passed, 1 total
Error: plugin "unittest" exited with error


tests:
- it: renders a Deployment with the default replicas and image
template: templates/deployment.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MINOR] the four assertions all read the Deployment's own fields, so the chart's cross-file couplings stay uncovered

Widening templates: fixes the render blindness above, it does not fix this. Two values in this chart have to agree across files, and both are the kind of drift a tenant notices before CI does.

Port 40000 is written in templates/deployment.yaml:48 (containerPort, asserted), templates/service.yaml:27-32 (port and targetPort, TCP and UDP) and templates/secret.yaml:34 (portForNewAccessKeys, which also lands in the ss:// URL on line 64). Move the Service off it and traffic arrives where shadowbox is not listening, while the suite says nothing:

# templates/service.yaml:28,32: targetPort: 40000 -> targetPort: 40001
$ cd packages/apps/vpn && helm unittest .
 PASS  vpn default render	tests/vpn_test.yaml
Charts:      1 passed, 1 total

Same shape for the Secret keys the Deployment mounts by name (templates/deployment.yaml:39-42 items: against templates/secret.yaml:37). Rename one and the pod cannot mount its config at runtime:

# templates/secret.yaml:37: shadowbox_config.json -> shadowbox_cfg.json
$ cd packages/apps/vpn && helm unittest .
 PASS  vpn default render	tests/vpn_test.yaml
Charts:      1 passed, 1 total

That second run is also the one case where checksum/config (templates/deployment.yaml:19) should have moved: the Secret's content changed, the annotation changed with it, and nothing asserted it. Pinning the annotation is what makes listing secret.yaml earn its place in the suite.

@IvanHunters
IvanHunters merged commit ff0b851 into cozystack:main Sep 22, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants