aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/codesearch/codesearch_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2025-11-17 11:17:23 +0100
committerDmitry Vyukov <dvyukov@google.com>2025-11-20 10:10:05 +0000
commit280ea308c321115445df610f1a75b05bbadca5f3 (patch)
treec195c76723c4a08986d74edbfc9e15a4f07fa6c1 /pkg/codesearch/codesearch_test.go
parent94d1e3f8b1838e8a04074464a957e979a5c5e36b (diff)
pkg/codesearch: add skeleton for code searching tool
Add a clang tool that is used for code indexing (tools/clang/codesearch/). It follows conventions and build procedure of the declextract tool. Add pkg/codesearch package that aggregates the info exposed by the clang tools, and allows doing simple queries: - show source code of an entity (function, struct, etc) - show entity comment - show all entities defined in a source file Add tools/syz-codesearch wrapper tool that allows to create index for a kernel build, and then run code queries on it.
Diffstat (limited to 'pkg/codesearch/codesearch_test.go')
-rw-r--r--pkg/codesearch/codesearch_test.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/pkg/codesearch/codesearch_test.go b/pkg/codesearch/codesearch_test.go
new file mode 100644
index 000000000..7af509294
--- /dev/null
+++ b/pkg/codesearch/codesearch_test.go
@@ -0,0 +1,61 @@
+// Copyright 2025 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package codesearch
+
+import (
+ "bytes"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/google/syzkaller/pkg/clangtool/tooltest"
+ "github.com/google/syzkaller/pkg/osutil"
+)
+
+func TestClangTool(t *testing.T) {
+ tooltest.TestClangTool[Database](t)
+}
+
+func TestCommands(t *testing.T) {
+ db := tooltest.LoadOutput[Database](t)
+ index := &Index{db, []string{"testdata"}}
+ files, err := filepath.Glob(filepath.Join(osutil.Abs("testdata"), "query*"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(files) == 0 {
+ t.Fatal("found no qeury files")
+ }
+ covered := make(map[string]bool)
+ for _, file := range files {
+ t.Run(filepath.Base(file), func(t *testing.T) {
+ testCommand(t, index, covered, file)
+ })
+ }
+ for _, cmd := range Commands {
+ if !covered[cmd.Name] {
+ t.Errorf("command %v is not covered, add at least one test", cmd.Name)
+ }
+ }
+}
+
+func testCommand(t *testing.T, index *Index, covered map[string]bool, file string) {
+ data, err := os.ReadFile(file)
+ if err != nil {
+ t.Fatal(err)
+ }
+ query, _, _ := bytes.Cut(data, []byte{'\n'})
+ args := strings.Fields(string(query))
+ if len(args) == 0 {
+ t.Fatal("no command found")
+ }
+ result, err := index.Command(args[0], args[1:])
+ if err != nil {
+ t.Fatal(err)
+ }
+ got := append([]byte(strings.Join(args, " ")+"\n\n"), result...)
+ tooltest.CompareGoldenData(t, file, got)
+ covered[args[0]] = true
+}