🐛 fix(test): 修复后端测试环境与跨平台隔离

This commit is contained in:
mango
2026-07-27 19:05:06 +08:00
parent 0e06c74b54
commit 5a16c2b201
18 changed files with 209 additions and 49 deletions

View File

@@ -676,12 +676,11 @@ func assertClaudeCLIRuntimeErrorIsEnglish(t *testing.T, message string) {
}
func TestClaudeCLIProvider_ChatStreamAllowsDelayedMeaningfulResponse(t *testing.T) {
fakeClaude := writeFakeClaudeScript(t, "#!/bin/sh\necho '{\"type\":\"system\",\"subtype\":\"init\"}'\nsleep 0.2\necho '{\"type\":\"assistant\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"OK\"}]}}'\necho '{\"type\":\"result\",\"subtype\":\"success\",\"is_error\":false,\"result\":\"OK\"}'\n")
restore := overrideClaudeCLIForTest(t, fakeClaude)
restore := overrideClaudeCLIWithTestProcess(t, "delayed-stream-success")
defer restore()
originalRequestTimeout := claudeCLIRequestTimeout
claudeCLIRequestTimeout = 1 * time.Second
claudeCLIRequestTimeout = 5 * time.Second
defer func() {
claudeCLIRequestTimeout = originalRequestTimeout
}()
@@ -960,6 +959,12 @@ func TestClaudeCLIHelperProcess(t *testing.T) {
case "model-success":
_, _ = os.Stdout.WriteString(`{"type":"result","subtype":"success","is_error":false,"result":"model request should not run"}`)
os.Exit(0)
case "delayed-stream-success":
_, _ = os.Stdout.WriteString("{\"type\":\"system\",\"subtype\":\"init\"}\n")
time.Sleep(200 * time.Millisecond)
_, _ = os.Stdout.WriteString("{\"type\":\"assistant\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"OK\"}]}}\n")
_, _ = os.Stdout.WriteString("{\"type\":\"result\",\"subtype\":\"success\",\"is_error\":false,\"result\":\"OK\"}\n")
os.Exit(0)
case "sleep":
time.Sleep(5 * time.Second)
os.Exit(0)

View File

@@ -503,6 +503,9 @@ func readClaudeCodeMCPServerConfig(configPath string, serverID string, textFuncs
func upsertClaudeCodeMCPServerConfig(configPath string, serverID string, serverConfig claudeCodeMCPServerConfig, textFuncs ...mcpClientInstallTextFunc) error {
text := firstMCPClientInstallText(textFuncs)
if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.claude_code.config_dir_create_failed", map[string]any{"detail": err.Error()}))
}
root, err := readClaudeCodeConfig(configPath, text)
if err != nil {
return err
@@ -526,9 +529,6 @@ func upsertClaudeCodeMCPServerConfig(configPath string, serverID string, serverC
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.claude_code.config_serialize_failed", map[string]any{"detail": err.Error()}))
}
if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.claude_code.config_dir_create_failed", map[string]any{"detail": err.Error()}))
}
if err := os.WriteFile(configPath, append(data, '\n'), 0o644); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.claude_code.config_write_failed", map[string]any{"detail": err.Error()}))
}
@@ -593,15 +593,15 @@ func readCodexMCPServerConfig(configPath string, serverID string, textFuncs ...m
func upsertCodexMCPServerConfig(configPath string, serverID string, serverConfig codexMCPServerConfig, textFuncs ...mcpClientInstallTextFunc) error {
text := firstMCPClientInstallText(textFuncs)
if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.codex.config_dir_create_failed", map[string]any{"detail": err.Error()}))
}
data, err := os.ReadFile(configPath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.codex.config_read_failed", map[string]any{"detail": err.Error()}))
}
updated := replaceOrAppendCodexMCPServerBlock(string(data), strings.TrimSpace(serverID), renderCodexMCPServerBlock(serverID, serverConfig))
if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.codex.config_dir_create_failed", map[string]any{"detail": err.Error()}))
}
if err := os.WriteFile(configPath, []byte(updated), 0o644); err != nil {
return fmt.Errorf("%s", mcpClientInstallText(text, "ai.service.mcp_client.codex.config_write_failed", map[string]any{"detail": err.Error()}))
}

View File

@@ -2056,7 +2056,17 @@ func (s *Service) loadSessionFile(sessionID string) (sessionFileData, error) {
return sessionData, nil
}
func (s *Service) ensureSessionsDir() error {
if err := os.MkdirAll(s.sessionsDir(), 0o755); err != nil {
return s.serviceError("ai_service.backend.error.sessions_dir_create_failed", nil, err)
}
return nil
}
func (s *Service) loadOrCreateSessionFile(sessionID string) (sessionFileData, error) {
if err := s.ensureSessionsDir(); err != nil {
return sessionFileData{}, err
}
sessionData, err := s.loadSessionFile(sessionID)
if err == nil {
return sessionData, nil
@@ -2073,9 +2083,8 @@ func (s *Service) loadOrCreateSessionFile(sessionID string) (sessionFileData, er
}
func (s *Service) saveSessionFile(sessionID string, sessionData sessionFileData) error {
dir := s.sessionsDir()
if err := os.MkdirAll(dir, 0o755); err != nil {
return s.serviceError("ai_service.backend.error.sessions_dir_create_failed", nil, err)
if err := s.ensureSessionsDir(); err != nil {
return err
}
if strings.TrimSpace(sessionData.ID) == "" {
sessionData.ID = sessionID

View File

@@ -133,6 +133,7 @@ func TestDirectDBQueryCannotBypassWriteAuditWhenBatchStartsWithRead(t *testing.T
}
func TestDirectDBQueryCannotBypassAuditWithNestedWriteSyntax(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalVerifyDriverAgentRevisionFunc := verifyDriverAgentRevisionFunc
t.Cleanup(func() {

View File

@@ -196,6 +196,9 @@ func TestMethodsDBConnectionValidationAndReleaseUseEnglishMessages(t *testing.T)
func TestMethodsDBConnectUsesCurrentLanguageForDriverRuntimeReason(t *testing.T) {
tmpDir := t.TempDir()
db.SetExternalDriverDownloadDirectory(tmpDir)
t.Cleanup(func() {
db.SetExternalDriverDownloadDirectory("")
})
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = tmpDir

View File

@@ -232,6 +232,7 @@ func TestDBGetIndexesUsesSearchPathForPostgresPureTableMetadata(t *testing.T) {
}
func TestDBGetColumnsKeepsCurrentDatabaseForKingbaseQualifiedTableMetadata(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalResolveDialConfigWithProxyFunc := resolveDialConfigWithProxyFunc
t.Cleanup(func() {
@@ -270,6 +271,7 @@ func TestDBGetColumnsKeepsCurrentDatabaseForKingbaseQualifiedTableMetadata(t *te
}
func TestDBGetIndexesKeepsCurrentDatabaseForKingbaseQualifiedTableMetadata(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalResolveDialConfigWithProxyFunc := resolveDialConfigWithProxyFunc
t.Cleanup(func() {
@@ -342,6 +344,7 @@ func TestDBGetColumnsKeepsDatabaseForMySQLMetadata(t *testing.T) {
}
func TestDBGetColumnsInfersOceanBaseOracleFieldsWhenAgentMetadataIsEmpty(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalResolveDialConfigWithProxyFunc := resolveDialConfigWithProxyFunc
t.Cleanup(func() {
@@ -422,6 +425,7 @@ func TestDBGetColumnsInfersOceanBaseOracleFieldsWhenAgentMetadataIsEmpty(t *test
}
func TestDBGetColumnsFallsBackToEmptySelectWhenOceanBaseOracleDictionaryIsEmpty(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalResolveDialConfigWithProxyFunc := resolveDialConfigWithProxyFunc
t.Cleanup(func() {

View File

@@ -796,6 +796,7 @@ var _ db.QueryMessageExecer = (*fakeBatchWriteDB)(nil)
var _ db.StatementQueryMessageExecer = (*fakeBatchWriteSession)(nil)
func TestDBQueryWithCancelReturnsResultSetForExecStoredProcedure(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -907,6 +908,7 @@ func TestDBQueryWithCancelRoutesMilvusSelectPreviewToQuery(t *testing.T) {
}
func TestDBQueryWithCancelReturnsMessagesForSQLServerQuery(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -942,6 +944,7 @@ func TestDBQueryWithCancelReturnsMessagesForSQLServerQuery(t *testing.T) {
}
func TestDBQueryWithCancel_DuckDBQueriesDoNotInheritConnectTimeout(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalVerifyDriverAgentRevisionFunc := verifyDriverAgentRevisionFunc
t.Cleanup(func() {
@@ -1113,6 +1116,7 @@ func TestDBQueryMultiTransactionalKeepsDMLTransactionOpenUntilCommit(t *testing.
}
func TestDBQueryMultiTransactionalKeepsSQLServerBeginEndBlockOpenUntilRollback(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -1492,6 +1496,7 @@ func TestDBQueryMultiTransactionalOraclePrefersTransactionProviderForFinish(t *t
}
func TestDBQueryMultiTransactionalUsesOracleImplicitSessionForOceanBaseOracleProtocol(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
originalVerifyDriverAgentRevisionFunc := verifyDriverAgentRevisionFunc
t.Cleanup(func() {
@@ -1865,6 +1870,7 @@ func TestDBQueryMultiTransactionalSkipsManagedTransactionForExplicitTransactionS
}
func TestDBQueryMultiPrefersResultSetForExecStoredProcedure(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -1909,6 +1915,7 @@ func TestDBQueryMultiPrefersResultSetForExecStoredProcedure(t *testing.T) {
}
func TestDBQueryMultiDoesNotBatchExecStoredProcedureAsWriteStatement(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -1953,6 +1960,7 @@ func TestDBQueryMultiDoesNotBatchExecStoredProcedureAsWriteStatement(t *testing.
}
func TestDBQueryMultiRunsSQLServerStatisticsBatchNatively(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2019,6 +2027,7 @@ func TestDBQueryMultiRunsSQLServerStatisticsBatchNatively(t *testing.T) {
}
func TestDBQueryMultiFallsBackWhenNativeReadOnlyBatchReturnsEmptyResults(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2248,6 +2257,7 @@ func TestDBQueryMultiFallsBackToPlainQueryWhenSequentialMultiStillReturnsBlankRe
}
func TestDBQueryMultiPrefersPlainQueryForKingbaseReadResults(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2370,6 +2380,7 @@ func TestDBQueryMultiPrefersPlainQueryForDamengReadResults(t *testing.T) {
}
func TestDBQueryMultiPrefersPlainQueryForOceanBaseOracleReadResults(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2437,6 +2448,7 @@ func TestDBQueryMultiPrefersPlainQueryForOceanBaseOracleReadResults(t *testing.T
}
func TestDBQueryMultiUsesPinnedSessionForSequentialFallback(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2498,6 +2510,7 @@ func TestDBQueryMultiUsesPinnedSessionForSequentialFallback(t *testing.T) {
}
func TestDBQueryMultiKeepsAllResultSetsFromSingleSQLServerStatement(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2552,6 +2565,7 @@ func TestDBQueryMultiKeepsAllResultSetsFromSingleSQLServerStatement(t *testing.T
}
func TestDBQueryMultiNormalizesSingleSQLServerSelectAffectedRowsStatementIndex(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2597,6 +2611,7 @@ func TestDBQueryMultiNormalizesSingleSQLServerSelectAffectedRowsStatementIndex(t
}
func TestDBQueryMultiNormalizesSQLServerSelectAffectedRowsPairsByStatement(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2672,6 +2687,7 @@ func TestNormalizeNativeResultStatementIndexesKeepsAmbiguousSQLServerResultsUnas
}
func TestDBQueryMultiTreatsBareSQLServerProcedureCallAsQueryFirst(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2767,6 +2783,7 @@ func TestDBQueryMultiTreatsReturningWriteAsQueryFirst(t *testing.T) {
}
func TestDBQueryMultiTreatsSQLServerOutputWriteAsQueryFirst(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
@@ -2814,6 +2831,7 @@ func TestDBQueryMultiTreatsSQLServerOutputWriteAsQueryFirst(t *testing.T) {
}
func TestDBQueryMultiTreatsWrappedMessageBlocksAsQueryFirst(t *testing.T) {
installFakeOptionalDriverRuntime(t)
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc

View File

@@ -132,7 +132,7 @@ func TestMethodsDriverReleaseHelpersUseLocalizedText(t *testing.T) {
"driver_manager.backend.error.driver_version_list_parse_failed",
},
},
"func fetchDriverBundleAssetSizeIndex": {
"func fetchDriverBundleAssetIndex": {
rawMessages: []string{
`fmt.Errorf("release 为空")`,
`fmt.Errorf("未找到驱动总包索引资产")`,

View File

@@ -4,6 +4,8 @@ import (
"os"
"strings"
"testing"
"GoNavi-Wails/internal/connection"
)
func methodsDriverSource(t *testing.T) string {
@@ -24,6 +26,19 @@ func methodsDriverSource(t *testing.T) string {
return strings.Join(parts, "\n\n")
}
func installFakeOptionalDriverRuntime(t *testing.T) {
t.Helper()
originalDriverRuntimeSupportStatusFunc := driverRuntimeSupportStatusFunc
originalVerifyDriverAgentRevisionFunc := verifyDriverAgentRevisionFunc
driverRuntimeSupportStatusFunc = func(string) (bool, string) { return true, "" }
verifyDriverAgentRevisionFunc = func(connection.ConnectionConfig) error { return nil }
t.Cleanup(func() {
driverRuntimeSupportStatusFunc = originalDriverRuntimeSupportStatusFunc
verifyDriverAgentRevisionFunc = originalVerifyDriverAgentRevisionFunc
})
}
func disableGlobalProxyForTest(t *testing.T) {
t.Helper()

View File

@@ -294,6 +294,8 @@ func TestDriverReleaseDownloadCoordinates(t *testing.T) {
}
func TestFetchDriverReleaseIndexByURLBuildsMirrorAssets(t *testing.T) {
disableGlobalProxyForTest(t)
for _, name := range []string{
"HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY",
"http_proxy", "https_proxy", "all_proxy",

View File

@@ -103,6 +103,14 @@ func expectedAuditAppendError(t *testing.T, auditRoot string) string {
return err.Error()
}
func setJVMTestLanguage(t *testing.T, app *App, language string) {
t.Helper()
app.SetLanguage(language)
t.Cleanup(func() {
app.SetLanguage("zh-CN")
})
}
func assertEnglishJVMConfirmationMessage(t *testing.T, got string, want string) {
t.Helper()
@@ -118,7 +126,7 @@ func assertEnglishJVMConfirmationMessage(t *testing.T, got string, want string)
func TestTestJVMConnectionUsesPreferredProvider(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
var gotMode string
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
gotMode = mode
@@ -172,6 +180,7 @@ func TestTestJVMConnectionReturnsProviderError(t *testing.T) {
func TestTestJVMConnectionTranslatesJMXBusinessPortError(t *testing.T) {
app := NewAppWithSecretStore(nil)
setJVMTestLanguage(t, app, "zh-CN")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{testErr: errors.New("jmx test connection failed: jmx helper ping failed for localhost:18080: JMX command ping failed for localhost:18080: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]; details={\"exception\":\"java.lang.IllegalStateException\"}")}, nil
})
@@ -203,10 +212,7 @@ func TestTestJVMConnectionTranslatesJMXBusinessPortError(t *testing.T) {
func TestTestJVMConnectionLocalizesJMXBusinessPortErrorInEnglish(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
t.Cleanup(func() {
app.SetLanguage("zh-CN")
})
setJVMTestLanguage(t, app, "en-US")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{testErr: errors.New("jmx test connection failed: jmx helper ping failed for localhost:18080: JMX command ping failed for localhost:18080: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]; details={\"exception\":\"java.lang.IllegalStateException\"}")}, nil
@@ -239,6 +245,7 @@ func TestTestJVMConnectionLocalizesJMXBusinessPortErrorInEnglish(t *testing.T) {
func TestTestJVMConnectionTranslatesAgentConnectionRefused(t *testing.T) {
app := NewAppWithSecretStore(nil)
setJVMTestLanguage(t, app, "zh-CN")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{testErr: errors.New("agent probe request failed: Get \"http://127.0.0.1:19090/gonavi/agent/jvm\": dial tcp 127.0.0.1:19090: connect: connection refused")}, nil
})
@@ -266,10 +273,7 @@ func TestTestJVMConnectionTranslatesAgentConnectionRefused(t *testing.T) {
func TestTestJVMConnectionLocalizesAgentConnectionRefusedInEnglish(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
t.Cleanup(func() {
app.SetLanguage("zh-CN")
})
setJVMTestLanguage(t, app, "en-US")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{testErr: errors.New("agent probe request failed: Get \"http://127.0.0.1:19090/gonavi/agent/jvm\": dial tcp 127.0.0.1:19090: connect: connection refused")}, nil
@@ -301,7 +305,7 @@ func TestTestJVMConnectionLocalizesAgentConnectionRefusedInEnglish(t *testing.T)
func TestTestJVMConnectionLocalizesEndpointErrorInEnglish(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{testErr: errors.New(`endpoint baseurl is invalid: parse ":bad-url": missing protocol scheme`)}, nil
@@ -414,7 +418,7 @@ func TestJVMProbeCapabilitiesIncludesReasonWhenProbeFails(t *testing.T) {
func TestJVMProbeCapabilitiesLocalizesBuiltInReadOnlyReasons(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
restore := swapJVMProviderFactory(jvm.NewProvider)
defer restore()
@@ -464,7 +468,7 @@ func TestJVMProbeCapabilitiesLocalizesBuiltInReadOnlyReasons(t *testing.T) {
func TestJVMProbeCapabilitiesKeepsProviderReasonThatLooksLikeCatalogKeyRaw(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
providerReason := "jvm.backend.error.change_blocked_read_only"
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{
@@ -503,6 +507,7 @@ func TestJVMProbeCapabilitiesKeepsProviderReasonThatLooksLikeCatalogKeyRaw(t *te
func TestJVMProbeCapabilitiesTranslatesJMXProbeErrorUsingCurrentMode(t *testing.T) {
app := NewAppWithSecretStore(nil)
setJVMTestLanguage(t, app, "zh-CN")
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
return fakeJVMProvider{
probeErr: errors.New("jmx test connection failed: jmx helper ping failed for localhost:18080: JMX command ping failed for localhost:18080: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]; details={\"exception\":\"java.lang.IllegalStateException\"}"),
@@ -565,6 +570,7 @@ func TestJVMProbeCapabilitiesIncludesReasonWhenProviderFactoryFails(t *testing.T
func TestJVMProbeCapabilitiesUsesReadableLabelForAgentValidationError(t *testing.T) {
app := NewAppWithSecretStore(nil)
setJVMTestLanguage(t, app, "zh-CN")
restore := swapJVMProviderFactory(jvm.NewProvider)
defer restore()
@@ -594,6 +600,7 @@ func TestJVMProbeCapabilitiesUsesReadableLabelForAgentValidationError(t *testing
func TestJVMProbeCapabilitiesUsesReadableLabelForEndpointValidationError(t *testing.T) {
app := NewAppWithSecretStore(nil)
setJVMTestLanguage(t, app, "zh-CN")
restore := swapJVMProviderFactory(jvm.NewProvider)
defer restore()
@@ -704,7 +711,7 @@ func TestJVMGetValueReturnsProviderPayload(t *testing.T) {
func TestJVMApplyChangeRequiresConfirmationTokenForHighRiskPreview(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := false
var applyReq jvm.ChangeRequest
@@ -826,7 +833,7 @@ func TestJVMApplyChangeReturnsProviderPayload(t *testing.T) {
func TestJVMApplyChangeUsesEnglishGuardFallbackWhenBlockingReasonEmpty(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := false
var applyReq jvm.ChangeRequest
@@ -878,7 +885,7 @@ func TestJVMApplyChangeUsesEnglishGuardFallbackWhenBlockingReasonEmpty(t *testin
func TestJVMProviderBlockingReasonThatLooksLikeCatalogKeyStaysRaw(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := false
providerReason := "jvm.backend.error.change_blocked_read_only"
@@ -941,7 +948,7 @@ func TestJVMProviderBlockingReasonThatLooksLikeCatalogKeyStaysRaw(t *testing.T)
func TestJVMPreviewChange(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
readOnly := true
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
@@ -986,7 +993,7 @@ func TestJVMPreviewChange(t *testing.T) {
func TestJVMApplyChange(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := true
var applyReq jvm.ChangeRequest
@@ -1131,7 +1138,7 @@ func TestJVMApplyChangePreviewTokenAllowsConfirmedApply(t *testing.T) {
func TestIssueJVMPreviewConfirmationTokenLocalizesPayloadHashError(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
readOnly := false
_, err := app.issueJVMPreviewConfirmationToken(connection.ConnectionConfig{
@@ -1175,7 +1182,7 @@ func TestIssueJVMPreviewConfirmationTokenLocalizesPayloadHashError(t *testing.T)
func TestJVMPreviewChangeLocalizesConfirmationTokenFailure(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
readOnly := false
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
@@ -1225,7 +1232,7 @@ func TestJVMPreviewChangeLocalizesConfirmationTokenFailure(t *testing.T) {
func TestJVMApplyChangeLocalizesConfirmationTokenFailure(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
readOnly := false
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
@@ -1275,7 +1282,7 @@ func TestJVMApplyChangeLocalizesConfirmationTokenFailure(t *testing.T) {
func TestJVMApplyChangeRejectsUnissuedDeterministicConfirmationToken(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := false
var applyReq jvm.ChangeRequest
@@ -1348,7 +1355,7 @@ func TestJVMApplyChangeRejectsUnissuedDeterministicConfirmationToken(t *testing.
func TestJVMApplyChangeRejectsMismatchedPreviewConfirmationContext(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
readOnly := false
applyCalls := 0
@@ -1497,7 +1504,7 @@ func TestJVMApplyChangeRejectsReplayedPreviewConfirmationToken(t *testing.T) {
func TestJVMApplyChangeRejectsExpiredPreviewConfirmationToken(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
app.configDir = t.TempDir()
app.jvmPreviewTokenTTL = time.Nanosecond
readOnly := false
@@ -1727,7 +1734,7 @@ func TestJVMApplyChangeNormalizesRequestBeforeProviderAndAudit(t *testing.T) {
func TestJVMPreviewChangeRejectsDisallowedProviderMode(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
cfg := connection.ConnectionConfig{
Type: "jvm",
@@ -1799,7 +1806,7 @@ func TestJVMListAuditRecordsReturnsLatestRecords(t *testing.T) {
func TestJVMApplyChangeFailsClosedWhenInitialAuditWriteFails(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
blockerPath := filepath.Join(tempDir, "audit-blocker")
if err := os.WriteFile(blockerPath, []byte("blocker"), 0o600); err != nil {
@@ -1916,7 +1923,7 @@ func TestJVMApplyChangeLatestAuditRecordIsTerminal(t *testing.T) {
func TestJVMApplyChangeApplySuccessKeepsSuccessWhenTerminalAuditFails(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -1982,7 +1989,7 @@ func TestJVMApplyChangeApplySuccessKeepsSuccessWhenTerminalAuditFails(t *testing
func TestJVMApplyChangeApplyFailureReportsFailedAuditWriteError(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -2085,7 +2092,7 @@ func TestJVMApplyChangeApplyFailureKeepsProviderErrorWhenFailedAuditSucceeds(t *
func TestJVMApplyChangeUsesProviderErrorWhenFailedAuditAlsoFails(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -2140,7 +2147,7 @@ func TestJVMApplyChangeUsesProviderErrorWhenFailedAuditAlsoFails(t *testing.T) {
func TestJVMApplyChangeTerminalAuditWarningAppendsToExistingResultMessage(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -2192,7 +2199,7 @@ func TestJVMApplyChangeTerminalAuditWarningAppendsToExistingResultMessage(t *tes
func TestJVMApplyChangeTerminalAuditWarningUsesStandaloneMessageWhenResultMessageEmpty(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -2244,7 +2251,7 @@ func TestJVMApplyChangeTerminalAuditWarningUsesStandaloneMessageWhenResultMessag
func TestJVMApplyChangeFailedAuditFailureMessageIncludesUnderlyingError(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {
@@ -2287,7 +2294,7 @@ func TestJVMApplyChangeFailedAuditFailureMessageIncludesUnderlyingError(t *testi
func TestJVMApplyChangeFailureMessageSeparatorUsesLocalizedEnglishSeparator(t *testing.T) {
app := NewAppWithSecretStore(nil)
app.SetLanguage("en-US")
setJVMTestLanguage(t, app, "en-US")
tempDir := t.TempDir()
auditDir := filepath.Join(tempDir, "audit")
if err := os.MkdirAll(auditDir, 0o755); err != nil {

View File

@@ -499,8 +499,8 @@ func TestOptionalDriverAgentUnresponsiveProcessIsReapedAfterTimeout(t *testing.T
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("expected context deadline error, got %v", err)
}
if cmd.ProcessState == nil || !cmd.ProcessState.Exited() {
t.Fatalf("timed-out driver-agent process was not reaped: %#v", cmd.ProcessState)
if cmd.ProcessState == nil {
t.Fatal("timed-out driver-agent process was not reaped")
}
}

View File

@@ -232,6 +232,9 @@ func startAgentFixture(t *testing.T) agentFixtureProcess {
}
classesDir := filepath.Join(t.TempDir(), "agent-fixture-classes")
if err := os.MkdirAll(classesDir, 0o755); err != nil {
t.Fatalf("create agent fixture classes directory failed: %v", err)
}
sourceRoot := filepath.Join(testRepoRoot(t), "internal", "jvm", "testdata", "agentfixture", "src")
javaFiles, err := filepath.Glob(filepath.Join(sourceRoot, "com", "gonavi", "fixture", "*.java"))
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
"net"
"net/http"
"net/http/httptest"
"os"
"os/exec"
"path/filepath"
"strings"
@@ -521,6 +522,9 @@ func startEndpointFixture(t *testing.T) endpointFixtureProcess {
}
classesDir := filepath.Join(t.TempDir(), "endpoint-fixture-classes")
if err := os.MkdirAll(classesDir, 0o755); err != nil {
t.Fatalf("create endpoint fixture classes directory failed: %v", err)
}
sourceRoot := filepath.Join(testRepoRoot(t), "internal", "jvm", "testdata", "endpointfixture", "src")
javaFiles, err := filepath.Glob(filepath.Join(sourceRoot, "com", "gonavi", "fixture", "*.java"))
if err != nil {

View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
"runtime"
@@ -775,6 +776,9 @@ func startJMXFixture(t *testing.T) jmxFixtureProcess {
}
classesDir := filepath.Join(t.TempDir(), "fixture-classes")
if err := os.MkdirAll(classesDir, 0o755); err != nil {
t.Fatalf("create JMX fixture classes directory failed: %v", err)
}
sourceRoot := filepath.Join(testRepoRoot(t), "internal", "jvm", "testdata", "jmxfixture", "src")
javaFiles, err := filepath.Glob(filepath.Join(sourceRoot, "com", "gonavi", "fixture", "*.java"))
if err != nil {

View File

@@ -5,6 +5,7 @@ import com.sun.net.httpserver.HttpServer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.instrument.Instrumentation;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
@@ -350,7 +351,11 @@ public final class GoNaviTestAgent {
}
private static String decode(String value) {
return URLDecoder.decode(value, StandardCharsets.UTF_8);
try {
return URLDecoder.decode(value, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException err) {
throw new IllegalStateException("UTF-8 is unavailable", err);
}
}
private static AgentArgs parseArgs(String rawArgs) {

View File

@@ -5,6 +5,7 @@ import com.sun.net.httpserver.HttpServer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@@ -331,7 +332,11 @@ public final class EndpointTestServer {
}
private static String decode(String value) {
return URLDecoder.decode(value, StandardCharsets.UTF_8);
try {
return URLDecoder.decode(value, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException err) {
throw new IllegalStateException("UTF-8 is unavailable", err);
}
}
private static Map<String, Object> requiredObject(Object value, String field) {