package services import ( "bytes" "io" "strings" "testing" "k8s.io/apimachinery/pkg/util/yaml" ) // 复现平台 install 时的 YAML 解析,定位非法 token func TestPromtailManifestParses(t *testing.T) { cases := []struct { name string labels string ns []string src string inc []string }{ {"空labels+空ns+空来源", "", nil, "", nil}, {"正常labels", `{"cluster":"pre-k8s"}`, []string{"astralx", "log"}, "k8s.kuboard.cn/name", []string{"cex-spot-api"}}, {"空labels但带ns", "", []string{"astralx"}, "controller_name", []string{"a", "b"}}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { out := PromtailDaemonsetYAML("log", "http://loki.log.svc.cluster.local:3100", "pre-k8s", c.labels, c.ns, c.src, c.inc) // 1) 扫控制字符 for i, line := range strings.Split(out, "\n") { if strings.ContainsRune(line, '\t') { t.Errorf("line %d contains TAB: %q", i+1, line) } } // 2) 用平台同一套 decoder 解析 dec := yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(out)), 4096) n := 0 for { var raw map[string]interface{} if err := dec.Decode(&raw); err == io.EOF { break } else if err != nil { lines := strings.Split(out, "\n") // 打印报错行附近 var from, to int if len(lines) > 30 { from, to = 1, 30 } else { from, to = 1, len(lines) } for i := from - 1; i < to && i < len(lines); i++ { t.Logf("%3d| %q", i+1, lines[i]) } t.Fatalf("YAML decode failed: %v", err) } n++ } t.Logf("解析出 %d 个对象", n) if n < 4 { t.Errorf("期望 >=4 个对象(SA/ClusterRole/CRB/ConfigMap/DaemonSet),实际 %d", n) } }) } }