Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

129 lines
2.4 KiB
Go

package hub
import (
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zzet/gortex/internal/indexer"
)
func makeEvent(path string) indexer.GraphChangeEvent {
return indexer.GraphChangeEvent{
FilePath: path,
Kind: indexer.ChangeModified,
NodesAdded: 1,
Timestamp: time.Now(),
}
}
func TestHub_MultipleSubscribersReceiveEvent(t *testing.T) {
h := New()
events := make(chan indexer.GraphChangeEvent, 8)
go h.Run(events)
defer h.Stop()
_, ch1 := h.Subscribe()
_, ch2 := h.Subscribe()
ev := makeEvent("a.go")
events <- ev
select {
case got := <-ch1:
assert.Equal(t, "a.go", got.FilePath)
case <-time.After(time.Second):
t.Fatal("subscriber 1 did not receive event")
}
select {
case got := <-ch2:
assert.Equal(t, "a.go", got.FilePath)
case <-time.After(time.Second):
t.Fatal("subscriber 2 did not receive event")
}
}
func TestHub_SlowSubscriberDoesNotBlock(t *testing.T) {
h := New()
events := make(chan indexer.GraphChangeEvent, 64)
go h.Run(events)
defer h.Stop()
// slow subscriber: never reads
h.Subscribe()
// fast subscriber
_, fastCh := h.Subscribe()
// Send more events than the slow subscriber's buffer
for i := 0; i < 32; i++ {
events <- makeEvent("file.go")
}
// Fast subscriber should still get events
received := 0
timeout := time.After(time.Second)
for {
select {
case <-fastCh:
received++
if received >= 16 {
return // success
}
case <-timeout:
require.GreaterOrEqual(t, received, 1, "fast subscriber should receive at least some events")
return
}
}
}
func TestHub_Unsubscribe(t *testing.T) {
h := New()
events := make(chan indexer.GraphChangeEvent, 8)
go h.Run(events)
defer h.Stop()
id, ch := h.Subscribe()
h.Unsubscribe(id)
events <- makeEvent("a.go")
time.Sleep(50 * time.Millisecond)
select {
case _, ok := <-ch:
assert.False(t, ok, "channel should be closed after unsubscribe")
default:
// Channel closed and empty — expected
}
}
func TestHub_StopEndsRun(t *testing.T) {
h := New()
events := make(chan indexer.GraphChangeEvent, 8)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
h.Run(events)
}()
h.Stop()
done := make(chan struct{})
go func() {
wg.Wait()
close(done)
}()
select {
case <-done:
// Run exited — success
case <-time.After(time.Second):
t.Fatal("Run did not exit after Stop")
}
}