sdk: make render() previews match the data plane's single substitution - #1467
sdk: make render() previews match the data plane's single substitution#1467dwin-gharibi wants to merge 1 commit into
Conversation
Signed-off-by: Dwin Gharibi <dwin.gharibi@email.kntu.ac.ir>
| @@ -0,0 +1,16 @@ | |||
| from cubesandbox._policy import Inject | |||
There was a problem hiding this comment.
Minor nit: every other file under sdk/python/tests/ (test_policy.py, test_sandbox.py, conftest.py) carries the Apache-2.0 SPDX header. Add it here for consistency:
# Copyright (c) 2026 Tencent Inc.
# SPDX-License-Identifier: Apache-2.0
Review: sdk: make render() previews match the data plane's single substitution (#1467)Verdict: Approve. The change is correct, well-scoped, and thoroughly tested. It aligns the two divergent SDK preview helpers with the server's actual substitution behavior. This review is AI-generated. What I verified against the base tree
Test qualityThe table-driven Go test and parametrized Python test cover the six meaningful cases from the issue (default format, repeated/three placeholders, Non-blocking nit
Design note (non-blocking)This is a deliberate, documented behavior change to a public SDK preview helper (single vs. all substitution). The rationale is sound: two of the four implementations already did single substitution, and the server's explicit |
Closes #1466.
Motivation
Inject.render()exists to show the operator the header value that will actually be sent. The Go andPython implementations substituted every
${SECRET}occurrence, but CubeEgress substitutes only thefirst (
access_phase.lua:171passes1asgsub's count limit). For a format likeBasic ${SECRET}:${SECRET}the preview saidBasic tok:tokwhile the upstream receivedBasic tok:${SECRET}.What this changes
Aligns the two outliers with the server:
sdk/go/policy.go—strings.ReplaceAll(...)→strings.Replace(..., 1)sdk/python/cubesandbox/_policy.py—fmt.replace(...)→fmt.replace(..., 1)The Node SDK already matches (JS
String.replacewith a string pattern replaces only the first), and theserver is unchanged.
No comment changes.
Why change the SDKs rather than the server
Two of the four implementations already do single substitution, and the server's explicit
1limit plusits "format has no ${SECRET} placeholder" warning read as a deliberate single-substitution contract.
More importantly, changing the server would alter the header value emitted for any existing policy that
repeats the placeholder — a live data-plane change. Changing a preview helper cannot break traffic.
If the maintainers would rather the contract be "replace all", the change is dropping the
1inaccess_phase.lua:171and reverting these two lines; the tests here document the contract either way sothe decision is visible.
Testing
New:
sdk/go/policy_render_test.go—TestInjectRenderMatchesServerSubstitution, table-driven over the sixcases from the issue including the default (empty) format, a
%-containing secret, and a format withno placeholder.
sdk/python/tests/test_policy_render.py— the same table.Red/green, per SDK:
CI gates checked locally:
gofmt -l .insdk/go— clean (fmt-check).go build ./...insdk/go— clean.sdk-test-checkcovers the SDK suites; both new tests sit in the existing test locations.Risk / rollout
None to the data plane. The only behaviour change is that
render()now returns the same string theserver produces. Anyone who was relying on
render()to expand a repeated placeholder was getting avalue the server never emitted.