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

Configure Feed

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

1package archive 2 3import ( 4 "archive/tar" 5 "archive/zip" 6 "compress/gzip" 7 "context" 8 "errors" 9 "flag" 10 "fmt" 11 "io" 12 "log" 13 "os" 14 "path/filepath" 15 "strings" 16 "testing" 17 "time" 18 19 "github.com/stretchr/testify/require" 20 21 "github.com/sourcegraph/zoekt" 22 "github.com/sourcegraph/zoekt/index" 23 "github.com/sourcegraph/zoekt/query" 24 "github.com/sourcegraph/zoekt/search" 25) 26 27func TestMain(m *testing.M) { 28 flag.Parse() 29 if !testing.Verbose() { 30 log.SetOutput(io.Discard) 31 } 32 os.Exit(m.Run()) 33} 34 35var modTime = time.Date(2024, 9, 26, 0, 0, 0, 0, time.UTC) 36 37func writeArchive(w io.Writer, format string, files map[string]string) (err error) { 38 if format == "zip" { 39 zw := zip.NewWriter(w) 40 for name, body := range files { 41 header := &zip.FileHeader{ 42 Name: name, 43 Method: zip.Deflate, 44 Modified: modTime, 45 } 46 f, err := zw.CreateHeader(header) 47 if err != nil { 48 return err 49 } 50 if _, err := f.Write([]byte(body)); err != nil { 51 return err 52 } 53 } 54 return zw.Close() 55 } 56 57 if format == "tgz" { 58 gw := gzip.NewWriter(w) 59 defer func() { 60 err2 := gw.Close() 61 if err == nil { 62 err = err2 63 } 64 }() 65 w = gw 66 format = "tar" 67 } 68 69 if format != "tar" { 70 return errors.New("expected tar") 71 } 72 73 tw := tar.NewWriter(w) 74 75 for name, body := range files { 76 hdr := &tar.Header{ 77 Name: name, 78 Mode: 0o600, 79 Size: int64(len(body)), 80 ModTime: modTime, 81 } 82 if err := tw.WriteHeader(hdr); err != nil { 83 return err 84 } 85 if _, err := tw.Write([]byte(body)); err != nil { 86 return err 87 } 88 } 89 if err := tw.Close(); err != nil { 90 return err 91 } 92 93 return nil 94} 95 96// TestIndexArg tests zoekt-archive-index by creating an archive and then 97// indexing and executing searches and checking we get expected results. 98// Additionally, we test that the index is properly updated with the 99// -incremental=true option changing the options between indexes and ensuring 100// the results change as expected. 101func TestIndexIncrementally(t *testing.T) { 102 for _, format := range []string{"tar", "tgz", "zip"} { 103 t.Run(format, func(t *testing.T) { 104 testIndexIncrementally(t, format) 105 }) 106 } 107} 108 109func testIndexIncrementally(t *testing.T, format string) { 110 indexDir := t.TempDir() 111 112 archive, err := os.CreateTemp("", "TestIndexArg-archive") 113 if err != nil { 114 t.Fatalf("TempFile: %v", err) 115 } 116 defer os.Remove(archive.Name()) 117 118 fileSize := 1000 119 120 files := map[string]string{} 121 for i := range 4 { 122 s := fmt.Sprintf("%d", i) 123 files["F"+s] = strings.Repeat("a", fileSize) 124 files["!F"+s] = strings.Repeat("a", fileSize) 125 } 126 127 err = writeArchive(archive, format, files) 128 if err != nil { 129 t.Fatalf("unable to create archive %v", err) 130 } 131 archive.Close() 132 133 // tests contain options used to build an index and the expected number of 134 // files in the result set based on the options. 135 tests := []struct { 136 largeFiles []string 137 wantNumFiles int 138 }{ 139 { 140 largeFiles: []string{}, 141 wantNumFiles: 0, 142 }, 143 { 144 largeFiles: []string{"F0", "F2"}, 145 wantNumFiles: 2, 146 }, 147 { 148 largeFiles: []string{"F?", "!F2"}, 149 wantNumFiles: 3, 150 }, 151 { 152 largeFiles: []string{"F?", "!F2", "\\!F0"}, 153 wantNumFiles: 4, 154 }, 155 { 156 largeFiles: []string{"F?", "!F2", "\\!F0", "F2"}, 157 wantNumFiles: 5, 158 }, 159 } 160 161 for _, test := range tests { 162 largeFiles, wantNumFiles := test.largeFiles, test.wantNumFiles 163 164 bopts := index.Options{ 165 SizeMax: fileSize - 1, 166 IndexDir: indexDir, 167 LargeFiles: largeFiles, 168 } 169 opts := Options{ 170 Incremental: true, 171 Archive: archive.Name(), 172 Name: "repo", 173 Branch: "master", 174 Commit: "cccccccccccccccccccccccccccccccccccccccc", 175 Strip: 0, 176 } 177 178 if err := Index(opts, bopts); err != nil { 179 t.Fatalf("error creating index: %v", err) 180 } 181 182 ss, err := search.NewDirectorySearcher(indexDir) 183 if err != nil { 184 t.Fatalf("NewDirectorySearcher(%s): %v", indexDir, err) 185 } 186 defer ss.Close() 187 188 q, err := query.Parse("aaa") 189 if err != nil { 190 t.Fatalf("Parse(aaa): %v", err) 191 } 192 193 var sOpts zoekt.SearchOptions 194 result, err := ss.Search(context.Background(), q, &sOpts) 195 if err != nil { 196 t.Fatalf("Search(%v): %v", q, err) 197 } 198 199 if len(result.Files) != wantNumFiles { 200 t.Errorf("got %v, want %d files.", result.Files, wantNumFiles) 201 } 202 } 203} 204 205// TestLatestCommitDate tests that the latest commit date is set correctly if 206// the mod time of the files has been set during the archive creation. 207func TestLatestCommitDate(t *testing.T) { 208 for _, format := range []string{"tar", "tgz", "zip"} { 209 t.Run(format, func(t *testing.T) { 210 testLatestCommitDate(t, format) 211 }) 212 } 213} 214 215func testLatestCommitDate(t *testing.T, format string) { 216 // Create an archive 217 archive, err := os.CreateTemp("", "TestLatestCommitDate") 218 require.NoError(t, err) 219 defer os.Remove(archive.Name()) 220 221 fileSize := 10 222 files := map[string]string{} 223 for i := range 4 { 224 s := fmt.Sprintf("%d", i) 225 files["F"+s] = strings.Repeat("a", fileSize) 226 files["!F"+s] = strings.Repeat("a", fileSize) 227 } 228 229 err = writeArchive(archive, format, files) 230 if err != nil { 231 t.Fatalf("unable to create archive %v", err) 232 } 233 archive.Close() 234 235 // Index 236 indexDir := t.TempDir() 237 bopts := index.Options{ 238 IndexDir: indexDir, 239 } 240 opts := Options{ 241 Archive: archive.Name(), 242 Name: "repo", 243 Branch: "master", 244 Commit: "cccccccccccccccccccccccccccccccccccccccc", 245 } 246 247 err = Index(opts, bopts) 248 require.NoError(t, err) 249 250 // Read the metadata of the index we just created and check the latest commit date. 251 f, err := os.Open(indexDir) 252 require.NoError(t, err) 253 254 indexFiles, err := f.Readdirnames(1) 255 require.Len(t, indexFiles, 1) 256 257 repos, _, err := index.ReadMetadataPath(filepath.Join(indexDir, indexFiles[0])) 258 require.NoError(t, err) 259 require.Len(t, repos, 1) 260 require.True(t, repos[0].LatestCommitDate.Equal(modTime)) 261}