From 2f8406800a3140d17fc6c24f9867a77da67da077 Mon Sep 17 00:00:00 2001 From: Mara Nikola Kiefer <8320933+mnkiefer@users.noreply.github.com> Date: Fri, 13 Nov 2026 02:07:00 +0100 Subject: [PATCH] Extract operator config parsing with debug logging Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- server/cmd/cao-dashboard/canvas.go | 7 ++++++ server/cmd/cao-dashboard/canvas_test.go | 33 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/server/cmd/cao-dashboard/canvas.go b/server/cmd/cao-dashboard/canvas.go index 7a6952c565..922642312b 100644 --- a/server/cmd/cao-dashboard/canvas.go +++ b/server/cmd/cao-dashboard/canvas.go @@ -33,15 +33,22 @@ func parseCanvasConfig(content []byte) (*server.LocalCanvasConfig, error) { func readOperatorConfig(path string) (*server.LocalOperatorConfig, error) { if path == "" { + commandLog.Printf("native operator integration disabled: reason=no_config_path") return nil, nil //nolint:nilnil // An omitted adapter configuration disables native maintenance. } content, err := os.ReadFile(path) // #nosec G304 -- explicitly selected private native adapter configuration. if err != nil { return nil, errors.New("read native operator configuration") } + return parseOperatorConfig(content) +} + +// parseOperatorConfig decodes a native operator configuration document. +func parseOperatorConfig(content []byte) (*server.LocalOperatorConfig, error) { var config server.LocalOperatorConfig if err := json.Unmarshal(content, &config); err != nil { return nil, errors.New("invalid native operator configuration") } + commandLog.Printf("loaded native operator configuration") return &config, nil } diff --git a/server/cmd/cao-dashboard/canvas_test.go b/server/cmd/cao-dashboard/canvas_test.go index 300cfab3a3..fbc01f4773 100644 --- a/server/cmd/cao-dashboard/canvas_test.go +++ b/server/cmd/cao-dashboard/canvas_test.go @@ -46,3 +46,36 @@ func TestParseCanvasConfig(t *testing.T) { } } } + +func TestReadOperatorConfigOmittedPathDisablesMaintenance(t *testing.T) { + config, err := readOperatorConfig("") + if err != nil || config != nil { + t.Fatalf("got %v, %v; want nil, nil", config, err) + } +} + +func TestReadOperatorConfigFromFile(t *testing.T) { + path := filepath.Join(t.TempDir(), "operator.json") + if err := os.WriteFile(path, []byte(`{"adapterUrl":"http://127.0.0.1:1"}`), 0o600); err != nil { + t.Fatal(err) + } + config, err := readOperatorConfig(path) + if err != nil || config.AdapterURL != "http://127.0.0.1:1" || config.OperatorActions != nil { + t.Fatalf("got %+v, %v", config, err) + } +} + +func TestReadOperatorConfigMissingFile(t *testing.T) { + _, err := readOperatorConfig(filepath.Join(t.TempDir(), "absent.json")) + if err == nil || err.Error() != "read native operator configuration" { + t.Fatalf("got %v", err) + } +} + +func TestParseOperatorConfigRejectsInvalidDocuments(t *testing.T) { + for _, bad := range []string{"", "not json", `{"adapterUrl":1}`} { + if _, err := parseOperatorConfig([]byte(bad)); err == nil || err.Error() != "invalid native operator configuration" { + t.Errorf("%q: got %v", bad, err) + } + } +}