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
129 lines
2.4 KiB
Go
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")
|
|
}
|
|
}
|