From f9fdd167a356b762e929240bf06f0062b90c7c4a Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Tue, 3 Nov 2026 10:20:59 +0000 Subject: [PATCH] test(studio): keep add-on names out of the network text Fail when a file that builds the text of the command network, the built-in bash or the host-exec setting writes the name of an add-on. Assisted-by: Claude Code:claude-sonnet-5-5 Signed-off-by: Ettore Di Giacinto --- core/services/studio/nonetworkaddon_test.go | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 core/services/studio/nonetworkaddon_test.go diff --git a/core/services/studio/nonetworkaddon_test.go b/core/services/studio/nonetworkaddon_test.go new file mode 100644 index 0000000000..4a32af13b8 --- /dev/null +++ b/core/services/studio/nonetworkaddon_test.go @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +package studio_test + +import ( + "go/ast" + "go/parser" + "go/token" + "os" + "path/filepath" + "strconv" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +// The network of the commands an add-on runs is named from what the add-on +// declares (capabilities.network, or the title of its commands tool). These +// specs fail when a file that builds that text or sets those rules writes the +// name of one add-on again. Tests, comments, documentation and the add-on's +// own data are the places that may. +var _ = Describe("the network code of the host", func() { + // stringsOf returns the string literals of the given Go files of dir, + // leaving out import paths. + stringsOf := func(dir string, files ...string) map[string][]string { + out := map[string][]string{} + for _, name := range files { + path := filepath.Join(dir, name) + _, err := os.Stat(path) + Expect(err).NotTo(HaveOccurred(), "the guard lists a file that is gone: %s", path) + file, err := parser.ParseFile(token.NewFileSet(), path, nil, 0) + Expect(err).NotTo(HaveOccurred()) + ast.Inspect(file, func(n ast.Node) bool { + switch n := n.(type) { + case *ast.ImportSpec: + return false + case *ast.BasicLit: + if n.Kind == token.STRING { + v, err := strconv.Unquote(n.Value) + Expect(err).NotTo(HaveOccurred()) + out[path] = append(out[path], v) + } + } + return true + }) + } + return out + } + + It("writes no add-on name in the text of the network, the built-in bash or the host-exec setting", func() { + groups := map[string][]string{ + ".": {"egress.go", "egressapi.go", "egresscards.go", "egresscheck.go", "egressjson.go", "hostbash.go"}, + "egress": {"egress.go"}, + "hostexec": {"hostexec.go"}, + "../../config": {"chats_egress.go"}, + "../../../pkg/egresspolicy": {"policy.go"}, + "../../http/endpoints/studio": {"studio.go"}, + } + for dir, files := range groups { + for path, values := range stringsOf(dir, files...) { + for _, v := range values { + Expect(strings.ToLower(v)).NotTo(ContainSubstring("sandbox"), "%s writes an add-on name into a string; take it from the manifest", path) + } + } + } + }) +})