Skip to content

Commit 011087e

Browse files
authored
Merge pull request #1961 from ilyabrykau-orca/test/windows-guards-go-fixture
test(ci): make the Windows path guard fixture polyglot so CI indexes Go end to end
2 parents 58fb945 + a874b6b commit 011087e

1 file changed

Lines changed: 118 additions & 10 deletions

File tree

‎tests/windows/test_non_ascii_path.py‎

Lines changed: 118 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
33
Guards the fix for issue #636 / #357 (landed on main via #700) at the product
44
surface (real codebase-memory-mcp process, real SQLite DB, real stdio). Two
5-
byte-identical TypeScript fixtures are indexed: one under an ASCII parent path,
6-
one under a non-ASCII parent path. The invariant under test:
5+
byte-identical polyglot fixtures (TypeScript + Go, #1959) are indexed: one under
6+
an ASCII parent path, one under a non-ASCII parent path. The invariant under test:
77
88
A byte-identical fixture must produce equivalent graph counts regardless of
99
whether its absolute path contains non-ASCII characters.
@@ -54,6 +54,81 @@
5454
"run();\n"
5555
)
5656

57+
# Dummy Go package covering the shapes the Go/cgo extraction work (#1932
58+
# family) showed were previously invisible to CI: struct fields and a method,
59+
# a build-tag twin pair sharing one function name, a cgo file (C preamble,
60+
# `C.` call, `//export` directive), and a channel producer/consumer pair
61+
# (#1959). Go qualified names embed the containing directory, so these also
62+
# put non-ASCII repo paths through the Go pipeline passes.
63+
GO_MOD = "module example.com/fixture\n\ngo 1.22\n"
64+
65+
GO_STORE = """package gopkg
66+
67+
type Store struct {
68+
Total int
69+
Name string
70+
}
71+
72+
func (s *Store) Push(x int) {
73+
s.Total = s.Total + x
74+
}
75+
76+
func NewStore(name string) *Store {
77+
return &Store{Name: name}
78+
}
79+
"""
80+
81+
GO_FLUSH_LINUX = """//go:build linux
82+
83+
package gopkg
84+
85+
func FlushDisk() int { return 1 }
86+
"""
87+
88+
GO_FLUSH_WINDOWS = """//go:build windows
89+
90+
package gopkg
91+
92+
func FlushDisk() int { return 2 }
93+
"""
94+
95+
GO_BRIDGE = """package gopkg
96+
97+
/*
98+
#include <stdio.h>
99+
static void announce(void) { puts("hi"); }
100+
*/
101+
import "C"
102+
103+
//export FixtureReady
104+
func FixtureReady() int { return 3 }
105+
106+
func Announce() {
107+
C.announce()
108+
}
109+
"""
110+
111+
GO_EVENTS = """package gopkg
112+
113+
func Produce(events chan string) {
114+
events <- "tick"
115+
}
116+
117+
func Drain(events chan string) string {
118+
v := <-events
119+
return v
120+
}
121+
"""
122+
123+
GO_FILES = (
124+
("go.mod", GO_MOD),
125+
("gopkg/store.go", GO_STORE),
126+
("gopkg/flush_linux.go", GO_FLUSH_LINUX),
127+
("gopkg/flush_windows.go", GO_FLUSH_WINDOWS),
128+
("gopkg/bridge.go", GO_BRIDGE),
129+
("gopkg/events.go", GO_EVENTS),
130+
)
131+
57132
# Distinct non-ASCII scripts — each must behave like the ASCII baseline.
58133
NON_ASCII_SEGMENTS = {
59134
"latin1_accents": "café_repo",
@@ -244,6 +319,11 @@ def make_fixture(root):
244319
for name, text in (("math.ts", MATH_TS), ("main.ts", MAIN_TS)):
245320
with open(os.path.join(src, name), "wb") as f:
246321
f.write(text.encode("utf-8")) # exact bytes, identical across copies
322+
for rel, text in GO_FILES:
323+
path = os.path.join(root, rel.replace("/", os.sep))
324+
os.makedirs(os.path.dirname(path) or root, exist_ok=True)
325+
with open(path, "wb") as f:
326+
f.write(text.encode("utf-8"))
247327

248328

249329
def no_project_error(index_txt, repo, cache):
@@ -323,6 +403,25 @@ def index_and_count(binary, repo, cache):
323403
except Exception:
324404
pass
325405
out["definition_nodes"] = defs
406+
# Go-file definitions separately: the Go passes derive qualified names
407+
# from the containing directory, so they meet non-ASCII paths on a
408+
# different route than the TS passes; a Go-specific count catches a
409+
# regression that total counts could mask (#1959).
410+
go_defs = 0
411+
for label in ("Function", "Method"):
412+
q = ("MATCH (n:%s) WHERE n.file_path CONTAINS '.go' "
413+
"RETURN count(n)" % label)
414+
r = s.call_tool("query_graph",
415+
{"query": q, "project": name, "format": "json"},
416+
timeout=60)
417+
t, _ = s.tool_text(r)
418+
try:
419+
rows = json.loads(t).get("rows") or []
420+
if rows and rows[0]:
421+
go_defs += int(rows[0][0])
422+
except Exception:
423+
pass
424+
out["go_definition_nodes"] = go_defs
326425
return out
327426

328427

@@ -363,11 +462,16 @@ def main():
363462
if base.get("error") or not base.get("nodes"):
364463
print("SETUP FAIL: ASCII baseline did not index: %r" % base)
365464
return 2
366-
print("baseline (ASCII): nodes=%s edges=%s definitions=%s" %
367-
(base["nodes"], base["edges"], base["definition_nodes"]))
465+
print("baseline (ASCII): nodes=%s edges=%s definitions=%s go=%s" %
466+
(base["nodes"], base["edges"], base["definition_nodes"],
467+
base["go_definition_nodes"]))
368468
if base["definition_nodes"] < 1:
369469
print("SETUP FAIL: ASCII baseline produced no definitions: %r" % base)
370470
return 2
471+
if base["go_definition_nodes"] < 1:
472+
print("SETUP FAIL: ASCII baseline extracted no Go definitions: %r"
473+
% base)
474+
return 2
371475

372476
for key, seg in NON_ASCII_SEGMENTS.items():
373477
repo = os.path.join(work, seg)
@@ -376,13 +480,15 @@ def main():
376480
ok = (not got.get("error")
377481
and got.get("nodes") == base["nodes"]
378482
and got.get("edges") == base["edges"]
379-
and got.get("definition_nodes") == base["definition_nodes"])
483+
and got.get("definition_nodes") == base["definition_nodes"]
484+
and got.get("go_definition_nodes") == base["go_definition_nodes"])
380485
status = "PASS" if ok else "FAIL"
381-
print("[%s] non-ascii/%-14s nodes=%s edges=%s definitions=%s "
382-
"(baseline %s/%s/%s) name=%r" %
486+
print("[%s] non-ascii/%-14s nodes=%s edges=%s definitions=%s go=%s "
487+
"(baseline %s/%s/%s/%s) name=%r" %
383488
(status, key, got.get("nodes"), got.get("edges"),
384-
got.get("definition_nodes"), base["nodes"], base["edges"],
385-
base["definition_nodes"], got.get("name")))
489+
got.get("definition_nodes"), got.get("go_definition_nodes"),
490+
base["nodes"], base["edges"], base["definition_nodes"],
491+
base["go_definition_nodes"], got.get("name")))
386492
if not ok:
387493
# The counts alone cannot explain a venue-specific failure;
388494
# surface the captured error verbatim so CI logs carry the
@@ -400,7 +506,9 @@ def main():
400506
if (not retry.get("error")
401507
and retry.get("nodes") == base["nodes"]
402508
and retry.get("edges") == base["edges"]
403-
and retry.get("definition_nodes") == base["definition_nodes"]):
509+
and retry.get("definition_nodes") == base["definition_nodes"]
510+
and retry.get("go_definition_nodes")
511+
== base["go_definition_nodes"]):
404512
print(" %s retry matched baseline -- order-dependent, "
405513
"not path-dependent" % key)
406514
else:

0 commit comments

Comments
 (0)