7a8 > "bytes" 10a12 > "io" 51,52d52 < var preparedDir string < 180,219d179 < < case setting.Database.Type.IsSQLite3(): < setting.Database.Path = ":memory:" < } < < setting.Repository.Local.LocalCopyPath = os.TempDir() < dir, err := os.MkdirTemp("", "prepared-forgejo") < if err != nil { < log.Fatal("os.MkdirTemp: %v", err) < } < preparedDir = dir < < setting.Repository.Local.LocalCopyPath, err = os.MkdirTemp("", "local-upload") < if err != nil { < log.Fatal("os.MkdirTemp: %v", err) < } < < if err := unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), dir); err != nil { < log.Fatal("os.RemoveAll: %v", err) < } < ownerDirs, err := os.ReadDir(dir) < if err != nil { < log.Fatal("os.ReadDir: %v", err) < } < < for _, ownerDir := range ownerDirs { < if !ownerDir.Type().IsDir() { < continue < } < repoDirs, err := os.ReadDir(filepath.Join(dir, ownerDir.Name())) < if err != nil { < log.Fatal("os.ReadDir: %v", err) < } < for _, repoDir := range repoDirs { < _ = os.MkdirAll(filepath.Join(dir, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755) < _ = os.MkdirAll(filepath.Join(dir, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755) < _ = os.MkdirAll(filepath.Join(dir, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755) < _ = os.MkdirAll(filepath.Join(dir, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755) < _ = os.MkdirAll(filepath.Join(dir, ownerDir.Name(), repoDir.Name(), "refs", "pull"), 0o755) < } 269,274c229,235 < func PrepareGitRepoDirectory(t testing.TB) { < var err error < setting.RepoRootPath, err = os.MkdirTemp(t.TempDir(), "forgejo-repo-rooth") < require.NoError(t, err) < require.NoError(t, unittest.CopyDir(preparedDir, setting.RepoRootPath)) < } --- > func PrepareTestEnv(t testing.TB, skip ...int) func() { > t.Helper() > ourSkip := 1 > if len(skip) > 0 { > ourSkip += skip[0] > } > deferFn := PrintCurrentTest(t, ourSkip) 276,278c237,240 < func PrepareArtifactsStorage(t testing.TB) { < // prepare actions artifacts directory and files < require.NoError(t, storage.Clean(storage.ActionsArtifacts)) --- > // kill all background processes to prevent them from interfering with the fixture loading > // see https://codeberg.org/forgejo/forgejo/issues/2962 > cancelProcesses(t, 30*time.Second) > t.Cleanup(func() { cancelProcesses(t, 0) }) // cancel remaining processes in a non-blocking way 280,288c242,266 < s, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{ < Path: filepath.Join(filepath.Dir(setting.AppPath), "tests", "testdata", "data", "artifacts"), < }) < require.NoError(t, err) < require.NoError(t, s.IterateObjects("", func(p string, obj storage.Object) error { < _, err = storage.Copy(storage.ActionsArtifacts, p, s, p) < return err < })) < } --- > // load database fixtures > require.NoError(t, unittest.LoadFixtures()) > > // load git repo fixtures > require.NoError(t, util.RemoveAll(setting.RepoRootPath)) > require.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath)) > ownerDirs, err := os.ReadDir(setting.RepoRootPath) > if err != nil { > require.NoError(t, err, "unable to read the new repo root: %v\n", err) > } > for _, ownerDir := range ownerDirs { > if !ownerDir.Type().IsDir() { > continue > } > repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) > if err != nil { > require.NoError(t, err, "unable to read the new repo root: %v\n", err) > } > for _, repoDir := range repoDirs { > _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755) > _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755) > _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755) > _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755) > } > } 290d267 < func PrepareLFSStorage(t testing.TB) { 292c269 < // (LFS storage can be on any of several backends, including remote servers, so init it with the storage API) --- > // (LFS storage can be on any of several backends, including remote servers, so we init it with the storage API) 302d278 < } 304d279 < func PrepareCleanPackageData(t testing.TB) { 316,323d290 < } < < func PrepareTestEnv(t testing.TB, skip ...int) func() { < t.Helper() < deferFn := PrintCurrentTest(t, util.OptionalArg(skip)+1) < < cancelProcesses(t, 30*time.Second) < t.Cleanup(func() { cancelProcesses(t, 0) }) // cancel remaining processes in a non-blocking way 325,331d291 < // load database fixtures < require.NoError(t, unittest.LoadFixtures()) < < // do not add more Prepare* functions here, only call necessary ones in the related test functions < PrepareGitRepoDirectory(t) < PrepareLFSStorage(t) < PrepareCleanPackageData(t) 337c297,301 < return testlogger.PrintCurrentTest(t, util.OptionalArg(skip)+1) --- > actualSkip := 1 > if len(skip) > 0 { > actualSkip = skip[0] + 1 > } > return testlogger.PrintCurrentTest(t, actualSkip) 489a454,530 > } > > // Decide if two files have the same contents or not. > // chunkSize is the size of the blocks to scan by; pass 0 to get a sensible default. > // *Follows* symlinks. > // > // May return an error if something else goes wrong; in this case, you should ignore the value of 'same'. > // > // derived from https://stackoverflow.com/a/30038571 > // under CC-BY-SA-4.0 by several contributors > func FileCmp(file1, file2 string, chunkSize int) (same bool, err error) { > if chunkSize == 0 { > chunkSize = 4 * 1024 > } > > // shortcuts: check file metadata > stat1, err := os.Stat(file1) > if err != nil { > return false, err > } > > stat2, err := os.Stat(file2) > if err != nil { > return false, err > } > > // are inputs are literally the same file? > if os.SameFile(stat1, stat2) { > return true, nil > } > > // do inputs at least have the same size? > if stat1.Size() != stat2.Size() { > return false, nil > } > > // long way: compare contents > f1, err := os.Open(file1) > if err != nil { > return false, err > } > defer f1.Close() > > f2, err := os.Open(file2) > if err != nil { > return false, err > } > defer f2.Close() > > b1 := make([]byte, chunkSize) > b2 := make([]byte, chunkSize) > for { > n1, err1 := io.ReadFull(f1, b1) > n2, err2 := io.ReadFull(f2, b2) > > // https://pkg.go.dev/io#Reader > // > Callers should always process the n > 0 bytes returned > // > before considering the error err. Doing so correctly > // > handles I/O errors that happen after reading some bytes > // > and also both of the allowed EOF behaviors. > > if !bytes.Equal(b1[:n1], b2[:n2]) { > return false, nil > } > > if (err1 == io.EOF && err2 == io.EOF) || (err1 == io.ErrUnexpectedEOF && err2 == io.ErrUnexpectedEOF) { > return true, nil > } > > // some other error, like a dropped network connection or a bad transfer > if err1 != nil { > return false, err1 > } > if err2 != nil { > return false, err2 > } > }