test: make tests hermetic against CI runner env vars #2101

Closed
core-be wants to merge 2 commits from fix/staging-test-hermetic-env into staging
8 changed files with 40 additions and 9 deletions
@@ -407,15 +407,6 @@ func validateCallerToken(ctx context.Context, c *gin.Context, callerID string) e
// matching (the wsauth errors are typed for the invalid case).
var errInvalidCallerToken = errors.New("missing caller auth token")
// canvasUserMessage holds the extracted user message extracted from an
// A2A canvas request body for broadcasting to other sessions.
type canvasUserMessage struct {
Message string `json:"message,omitempty"`
Parts []map[string]interface{} `json:"parts,omitempty"`
MessageID string `json:"messageId,omitempty"`
Attachments []map[string]interface{} `json:"attachments,omitempty"`
}
// extractCanvasUserMessage parses an A2A JSON-RPC request body and extracts
// the user-authored text and attachments from a canvas-initiated message/send.
// Returns nil when the body is not a canvas user message (empty, malformed,
@@ -39,6 +39,7 @@ func TestAdminTestToken_EnabledViaFlagEvenInProd(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ENV", "production")
t.Setenv("MOLECULE_ENABLE_TEST_TOKENS", "1")
t.Setenv("ADMIN_TOKEN", "")
mock.ExpectQuery("SELECT id FROM workspaces WHERE id =").
WithArgs("ws-1").
@@ -58,6 +59,7 @@ func TestAdminTestToken_EnabledViaFlagEvenInProd(t *testing.T) {
func TestAdminTestToken_WorkspaceNotFound(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ENV", "development")
t.Setenv("ADMIN_TOKEN", "")
mock.ExpectQuery("SELECT id FROM workspaces WHERE id =").
WithArgs("missing").
@@ -75,6 +77,7 @@ func TestAdminTestToken_WorkspaceNotFound(t *testing.T) {
func TestAdminTestToken_HappyPath_TokenValidates(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ENV", "development")
t.Setenv("ADMIN_TOKEN", "")
mock.ExpectQuery("SELECT id FROM workspaces WHERE id =").
WithArgs("ws-1").
@@ -1040,6 +1040,7 @@ func TestIsSafeURL_Blocks169_254_Metadata(t *testing.T) {
}
func TestIsSafeURL_Blocks10xPrivate(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
err := isSafeURL("http://10.0.0.1/agent")
if err == nil {
t.Errorf("isSafeURL: expected 10.x.x.x to be blocked, got nil")
@@ -1047,6 +1048,7 @@ func TestIsSafeURL_Blocks10xPrivate(t *testing.T) {
}
func TestIsSafeURL_Blocks172Private(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
err := isSafeURL("http://172.16.0.1/agent")
if err == nil {
t.Errorf("isSafeURL: expected 172.16.0.0/12 to be blocked, got nil")
@@ -1054,6 +1056,7 @@ func TestIsSafeURL_Blocks172Private(t *testing.T) {
}
func TestIsSafeURL_Blocks192_168Private(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
err := isSafeURL("http://192.168.1.100/agent")
if err == nil {
t.Errorf("isSafeURL: expected 192.168.x.x to be blocked, got nil")
@@ -1077,6 +1080,7 @@ func TestIsSafeURL_BlocksInvalidURL(t *testing.T) {
// ==================== SSRF Defence — isPrivateOrMetadataIP ====================
func TestIsPrivateOrMetadataIP_10Range(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
tests := []string{"10.0.0.0", "10.255.255.255", "10.1.2.3"}
for _, ip := range tests {
if !isPrivateOrMetadataIP(net.ParseIP(ip)) {
@@ -1086,6 +1090,7 @@ func TestIsPrivateOrMetadataIP_10Range(t *testing.T) {
}
func TestIsPrivateOrMetadataIP_172Range(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
tests := []string{"172.16.0.0", "172.31.255.255", "172.20.1.1"}
for _, ip := range tests {
if !isPrivateOrMetadataIP(net.ParseIP(ip)) {
@@ -1095,6 +1100,7 @@ func TestIsPrivateOrMetadataIP_172Range(t *testing.T) {
}
func TestIsPrivateOrMetadataIP_192_168Range(t *testing.T) {
t.Setenv("MOLECULE_ORG_ID", "")
tests := []string{"192.168.0.0", "192.168.255.255", "192.168.1.1"}
for _, ip := range tests {
if !isPrivateOrMetadataIP(net.ParseIP(ip)) {
@@ -712,6 +712,10 @@ func TestHeartbeat_SkipsRemovedRows(t *testing.T) {
// ------------------------------------------------------------
func TestValidateAgentURL(t *testing.T) {
// Ensure strict mode — MOLECULE_ORG_ID in the runner env would flip
// saasMode() on and allow RFC-1918, breaking the blocked-range checks.
t.Setenv("MOLECULE_ORG_ID", "")
t.Setenv("MOLECULE_DEPLOY_MODE", "")
cases := []struct {
name string
url string
@@ -95,6 +95,7 @@ func TestSecurity_GetTemplates_NoAuth_Returns401(t *testing.T) {
func TestSecurity_GetTemplates_FreshInstall_FailsOpen(t *testing.T) {
setupTestDB(t)
setupTestRedis(t)
t.Setenv("ADMIN_TOKEN", "")
authDB, authMock := newFreshInstallAuthDB(t)
tmpDir := t.TempDir()
@@ -152,6 +153,7 @@ func TestSecurity_GetOrgTemplates_NoAuth_Returns401(t *testing.T) {
func TestSecurity_GetOrgTemplates_FreshInstall_FailsOpen(t *testing.T) {
setupTestDB(t)
setupTestRedis(t)
t.Setenv("ADMIN_TOKEN", "")
authDB, authMock := newFreshInstallAuthDB(t)
tmpDir := t.TempDir()
@@ -787,6 +787,7 @@ func TestBuildProvisionerConfig_WorkspacePathFromEnv(t *testing.T) {
// into cfg.ConfigFiles[".auth_token"].
func TestIssueAndInjectToken_HappyPath(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ORG_ID", "")
broadcaster := newTestBroadcaster()
handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", t.TempDir())
@@ -824,6 +825,7 @@ func TestIssueAndInjectToken_HappyPath(t *testing.T) {
// issuing a fresh one so we never accumulate stale live tokens in the DB.
func TestIssueAndInjectToken_RotatesExistingToken(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ORG_ID", "")
broadcaster := newTestBroadcaster()
handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", t.TempDir())
@@ -890,6 +892,7 @@ func TestIssueAndInjectToken_RevokeFailSkipsInjection(t *testing.T) {
// IssueToken also skips injection without panicking.
func TestIssueAndInjectToken_IssueFailSkipsInjection(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ORG_ID", "")
broadcaster := newTestBroadcaster()
handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", t.TempDir())
@@ -916,6 +919,7 @@ func TestIssueAndInjectToken_IssueFailSkipsInjection(t *testing.T) {
// ConfigFiles map is allocated before the token is written.
func TestIssueAndInjectToken_NilConfigFilesAllocated(t *testing.T) {
mock := setupTestDB(t)
t.Setenv("MOLECULE_ORG_ID", "")
broadcaster := newTestBroadcaster()
handler := NewWorkspaceHandler(broadcaster, nil, "http://localhost:8080", t.TempDir())
@@ -256,6 +256,10 @@ func TestWorkspaceAuth_WrongWorkspace_Returns401(t *testing.T) {
// live tokens anywhere) the middleware must let the request through so existing
// deployments keep working during the Phase-30 rollout.
func TestAdminAuth_FailOpen_NoTokensGlobally(t *testing.T) {
// Clear any ADMIN_TOKEN from the runner env so the no-tokens tier-1
// fail-open branch actually fires.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock.New: %v", err)
@@ -375,6 +379,9 @@ func TestAdminAuth_C11_DeleteNoBearer_Returns401(t *testing.T) {
// TestAdminAuth_ValidBearer_Passes — a valid bearer token (from any workspace)
// must be accepted for admin routes.
func TestAdminAuth_ValidBearer_Passes(t *testing.T) {
// Force tier-3 fallback (ValidateAnyToken) by unsetting ADMIN_TOKEN.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock.New: %v", err)
@@ -418,6 +425,9 @@ func TestAdminAuth_ValidBearer_Passes(t *testing.T) {
// TestAdminAuth_InvalidBearer_Returns401 — wrong token must not grant admin access.
func TestAdminAuth_InvalidBearer_Returns401(t *testing.T) {
// Unset ADMIN_TOKEN so the tier-3 ValidateAnyToken fallback is exercised.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock.New: %v", err)
@@ -700,6 +710,9 @@ func TestAdminAuth_Issue180_ApprovalsListing_NoBearer_Returns401(t *testing.T) {
// fail-open contract: on a fresh install (no tokens anywhere), the middleware
// must not block the canvas from polling /approvals/pending.
func TestAdminAuth_Issue180_ApprovalsListing_FailOpen_NoTokens(t *testing.T) {
// Clear ADMIN_TOKEN so the no-tokens fail-open path works.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock.New: %v", err)
@@ -1098,6 +1111,9 @@ func TestCanvasOrBearer_TokensExist_CanvasOrigin_Passes(t *testing.T) {
// issuing workspace has status='removed' must not grant admin access.
// The JOIN in ValidateAnyToken filters the row out, resulting in ErrNoRows.
func TestAdminAuth_RemovedWorkspaceToken_Returns401(t *testing.T) {
// Unset ADMIN_TOKEN so the tier-3 ValidateAnyToken path is exercised.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock.New: %v", err)
@@ -1251,6 +1267,9 @@ func TestAdminAuth_623_ForgedCORSOrigin_Returns401(t *testing.T) {
// TestAdminAuth_623_ValidBearer_WithOrigin_Passes — bearer + matching Origin
// should still work (the Origin is irrelevant once the bearer validates).
func TestAdminAuth_623_ValidBearer_WithOrigin_Passes(t *testing.T) {
// Unset ADMIN_TOKEN so tier-3 ValidateAnyToken fallback is exercised.
t.Setenv("ADMIN_TOKEN", "")
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("sqlmock: %v", err)
@@ -81,6 +81,8 @@ func TestTestTokenRoute_RequiresAdminAuth_WhenTokensExist(t *testing.T) {
// bootstrap path still works before the first workspace has registered.
func TestTestTokenRoute_FailOpenOnFreshInstall(t *testing.T) {
t.Setenv("MOLECULE_ENV", "development")
// Clear ADMIN_TOKEN so AdminAuth's no-tokens tier-1 fail-open fires.
t.Setenv("ADMIN_TOKEN", "")
mock := setupRouterTestDB(t)
// HasAnyLiveTokenGlobal: no tokens yet — fresh install.