Files
MyGoNavi/internal/jvm/diagnostic_config_test.go
tianqijiuyun-latiao 5fc29a6fd3 feat(i18n): 推进多语言剩余切片闭环
- 补齐 DataGrid、DataViewer、DefinitionViewer、JVM 等模块多语言文案与回归测试
- 收口 JVM 前后端展示、诊断、监控和资源呈现相关多语言路径
- 更新六语言共享词典并保留 raw 边界
2026-06-16 12:40:33 +08:00

231 lines
6.9 KiB
Go

package jvm
import (
"errors"
"reflect"
"strings"
"testing"
"GoNavi-Wails/internal/connection"
)
func TestNormalizeDiagnosticConfigDefaultsToDisabledObserveOnly(t *testing.T) {
cfg, err := NormalizeDiagnosticConfig(connection.ConnectionConfig{
Type: "jvm",
Host: "orders.internal",
JVM: connection.JVMConfig{},
})
if err != nil {
t.Fatalf("NormalizeDiagnosticConfig returned error: %v", err)
}
if cfg.Enabled {
t.Fatalf("expected diagnostic mode disabled by default")
}
if cfg.Transport != DiagnosticTransportAgentBridge {
t.Fatalf("expected default transport %q, got %q", DiagnosticTransportAgentBridge, cfg.Transport)
}
if cfg.TimeoutSeconds != 15 {
t.Fatalf("expected default timeout 15 seconds, got %d", cfg.TimeoutSeconds)
}
if !cfg.AllowObserveCommands || cfg.AllowTraceCommands || cfg.AllowMutatingCommands {
t.Fatalf("unexpected default command policy: %#v", cfg)
}
}
func TestValidateDiagnosticCommandPolicyRejectsMultilineCommand(t *testing.T) {
cfg, err := NormalizeDiagnosticConfig(connection.ConnectionConfig{
Type: "jvm",
Host: "orders.internal",
JVM: connection.JVMConfig{
Diagnostic: connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
BaseURL: "http://127.0.0.1:19091/gonavi/diag",
AllowObserveCommands: true,
AllowTraceCommands: true,
AllowMutatingCommands: true,
},
},
})
if err != nil {
t.Fatalf("NormalizeDiagnosticConfig returned error: %v", err)
}
for _, command := range []string{
"thread -n 1\nognl '@java.lang.System@setProperty(\"x\",\"y\")'",
"thread -n 1\rwatch com.foo.OrderService submitOrder '{params}'",
} {
if _, err := ValidateDiagnosticCommandPolicy(cfg, command); err == nil {
t.Fatalf("expected multiline command to be rejected: %q", command)
}
}
}
func TestClassifyDiagnosticCommandRejectsMutatingCommandWhenDisabled(t *testing.T) {
cfg, err := NormalizeDiagnosticConfig(connection.ConnectionConfig{
Type: "jvm",
Host: "orders.internal",
JVM: connection.JVMConfig{
Diagnostic: connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
BaseURL: "http://127.0.0.1:19091/gonavi/diag",
AllowObserveCommands: true,
},
},
})
if err != nil {
t.Fatalf("NormalizeDiagnosticConfig returned error: %v", err)
}
_, err = ValidateDiagnosticCommandPolicy(cfg, "ognl '@java.lang.System@exit(0)'")
if err == nil {
t.Fatalf("expected mutating command to be rejected")
}
}
func TestDiagnosticConfigPolicyErrorsReturnLocalizedKeys(t *testing.T) {
enabledAll := connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
AllowObserveCommands: true,
AllowTraceCommands: true,
AllowMutatingCommands: true,
}
tests := []struct {
name string
run func() error
wantKey string
wantParams map[string]any
}{
{
name: "unsupported transport keeps raw transport parameter",
run: func() error {
_, err := NormalizeDiagnosticConfig(connection.ConnectionConfig{
Type: "jvm",
JVM: connection.JVMConfig{
Diagnostic: connection.JVMDiagnosticConfig{
Transport: " websocket ",
},
},
})
return err
},
wantKey: "jvm.backend.diagnostic.error.transport_unsupported",
wantParams: map[string]any{"transport": " websocket "},
},
{
name: "disabled diagnostic mode",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(connection.JVMDiagnosticConfig{}, "thread")
return err
},
wantKey: "jvm.backend.diagnostic.error.disabled",
},
{
name: "empty command",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(enabledAll, " ")
return err
},
wantKey: "jvm.backend.diagnostic.error.command_required",
},
{
name: "multiline command",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(enabledAll, "thread\nwatch demo.Service call '{params}'")
return err
},
wantKey: "jvm.backend.diagnostic.policy.multiline_not_supported",
},
{
name: "observe command not allowed keeps normalized command parameter",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
}, " thread -n 1 ")
return err
},
wantKey: "jvm.backend.diagnostic.policy.observe_not_allowed",
wantParams: map[string]any{"command": "thread -n 1"},
},
{
name: "trace command not allowed keeps normalized command parameter",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
AllowObserveCommands: true,
}, "watch demo.Service call '{params}'")
return err
},
wantKey: "jvm.backend.diagnostic.policy.trace_not_allowed",
wantParams: map[string]any{"command": "watch demo.Service call '{params}'"},
},
{
name: "mutating command not allowed keeps normalized command parameter",
run: func() error {
_, err := ValidateDiagnosticCommandPolicy(connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
AllowObserveCommands: true,
}, "ognl '@java.lang.System@exit(0)'")
return err
},
wantKey: "jvm.backend.diagnostic.policy.mutating_not_allowed",
wantParams: map[string]any{"command": "ognl '@java.lang.System@exit(0)'"},
},
{
name: "read only rejects non observe command",
run: func() error {
readOnly := true
_, err := ValidateDiagnosticExecutionPolicy(connection.ConnectionConfig{
Type: "jvm",
JVM: connection.JVMConfig{
ReadOnly: &readOnly,
Diagnostic: connection.JVMDiagnosticConfig{
Enabled: true,
Transport: DiagnosticTransportAgentBridge,
AllowObserveCommands: true,
AllowTraceCommands: true,
},
},
}, "trace demo.Service call")
return err
},
wantKey: "jvm.backend.diagnostic.policy.read_only_observe_only",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.run()
if err == nil {
t.Fatalf("expected localized error")
}
var localized *LocalizedError
if !errors.As(err, &localized) {
t.Fatalf("expected LocalizedError, got %T: %v", err, err)
}
if localized.Key != tt.wantKey {
t.Fatalf("localized key=%q, want %q", localized.Key, tt.wantKey)
}
if !reflect.DeepEqual(localized.Params, tt.wantParams) {
t.Fatalf("localized params=%#v, want %#v", localized.Params, tt.wantParams)
}
if containsCJK(err.Error()) {
t.Fatalf("error still exposes legacy Chinese text: %q", err.Error())
}
})
}
}
func containsCJK(value string) bool {
return strings.ContainsFunc(value, func(r rune) bool {
return r >= '\u4e00' && r <= '\u9fff'
})
}