fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

1package stream 2 3import ( 4 "bytes" 5 "context" 6 "encoding/gob" 7 "fmt" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 14 "github.com/sourcegraph/zoekt" 15 "github.com/sourcegraph/zoekt/internal/mockSearcher" 16 "github.com/sourcegraph/zoekt/query" 17) 18 19func TestStreamSearch(t *testing.T) { 20 q := query.NewAnd(mustParse("hello world|universe"), query.NewRepoSet("foo/bar", "baz/bam")) 21 searcher := &mockSearcher.MockSearcher{ 22 WantSearch: q, 23 SearchResult: &zoekt.SearchResult{ 24 Files: []zoekt.FileMatch{ 25 {FileName: "bin.go"}, 26 }, 27 }, 28 } 29 30 h := &handler{Searcher: adapter{searcher}} 31 32 s := httptest.NewServer(h) 33 defer s.Close() 34 35 cl := NewClient(s.URL, nil) 36 37 c := make(chan *zoekt.SearchResult, 100) 38 39 err := cl.StreamSearch(context.Background(), q, nil, streamerChan(c)) 40 if err != nil { 41 t.Fatal(err) 42 } 43 close(c) 44 45 for res := range c { 46 if res.Files == nil { 47 continue 48 } 49 if res.Files[0].FileName != "bin.go" { 50 t.Errorf("got %s, wanted %s", res.Files[0].FileName, "bin.go") 51 } 52 } 53} 54 55func TestStreamSearchJustStats(t *testing.T) { 56 wantStats := zoekt.Stats{ 57 Crashes: 1, 58 } 59 q := query.NewAnd(mustParse("hello world|universe"), query.NewRepoSet("foo/bar", "baz/bam")) 60 searcher := &mockSearcher.MockSearcher{ 61 WantSearch: q, 62 SearchResult: &zoekt.SearchResult{ 63 Files: []zoekt.FileMatch{}, 64 Stats: wantStats, 65 }, 66 } 67 68 h := &handler{Searcher: adapter{searcher}} 69 70 s := httptest.NewServer(h) 71 defer s.Close() 72 73 cl := NewClient(s.URL, nil) 74 75 c := make(chan *zoekt.SearchResult, 100) 76 77 err := cl.StreamSearch(context.Background(), q, nil, streamerChan(c)) 78 if err != nil { 79 t.Fatal(err) 80 } 81 close(c) 82 83 count := 0 84 for res := range c { 85 count += 1 86 if count > 1 { 87 t.Fatal("expected exactly 1 result, got at least 2") 88 } 89 if d := cmp.Diff(wantStats, res.Stats); d != "" { 90 t.Fatalf("zoekt.Stats mismatch (-want +got): %s\n", d) 91 } 92 } 93 if count != 1 { 94 t.Fatal("expected exactly 1 result, got 0") 95 } 96} 97 98func TestEventStreamWriter(t *testing.T) { 99 registerGob() 100 network := new(bytes.Buffer) 101 enc := gob.NewEncoder(network) 102 dec := gob.NewDecoder(network) 103 104 esw := eventStreamWriter{ 105 enc: enc, 106 flush: func() {}, 107 } 108 109 tests := []struct { 110 event eventType 111 data interface{} 112 }{ 113 { 114 eventDone, 115 nil, 116 }, 117 { 118 eventMatches, 119 &zoekt.SearchResult{ 120 Files: []zoekt.FileMatch{ 121 {FileName: "bin.go"}, 122 }, 123 }, 124 }, 125 { 126 eventError, 127 "test error", 128 }, 129 } 130 131 for _, tt := range tests { 132 t.Run(tt.event.string(), func(t *testing.T) { 133 err := esw.event(tt.event, tt.data) 134 if err != nil { 135 t.Fatal(err) 136 } 137 reply := new(searchReply) 138 err = dec.Decode(reply) 139 if err != nil { 140 t.Fatal(err) 141 } 142 if reply.Event != tt.event { 143 t.Fatalf("got %s, want %s", reply.Event.string(), tt.event.string()) 144 } 145 if d := cmp.Diff(tt.data, reply.Data); d != "" { 146 t.Fatalf("mismatch for event type %s (-want +got):\n%s", tt.event.string(), d) 147 } 148 }) 149 } 150} 151 152func TestServerError(t *testing.T) { 153 serverError := fmt.Errorf("zoekt server error") 154 h := func(w http.ResponseWriter, r *http.Request) { 155 esw, err := newEventStreamWriter(w) 156 if err != nil { 157 t.Fatal(err) 158 } 159 err = esw.event(eventError, serverError) 160 if err != nil { 161 t.Fatal(err) 162 } 163 } 164 s := httptest.NewServer(http.HandlerFunc(h)) 165 cl := NewClient(s.URL, nil) 166 err := cl.StreamSearch(context.Background(), nil, nil, streamerChan(make(chan *zoekt.SearchResult))) 167 if err == nil { 168 t.Fatalf("got nil, want %s", serverError) 169 } 170} 171 172func mustParse(s string) query.Q { 173 q, err := query.Parse(s) 174 if err != nil { 175 panic(err) 176 } 177 return q 178} 179 180type streamerChan chan<- *zoekt.SearchResult 181 182func (c streamerChan) Send(result *zoekt.SearchResult) { 183 c <- result 184} 185 186type adapter struct { 187 zoekt.Searcher 188} 189 190func (a adapter) StreamSearch(ctx context.Context, q query.Q, opts *zoekt.SearchOptions, sender zoekt.Sender) (err error) { 191 sr, err := a.Searcher.Search(ctx, q, opts) 192 if err != nil { 193 return err 194 } 195 sender.Send(sr) 196 return nil 197}