diff --git a/api/mirror_test.go b/api/mirror_test.go index 8b9b751f..cb64d485 100644 --- a/api/mirror_test.go +++ b/api/mirror_test.go @@ -26,6 +26,21 @@ func (s *MirrorSuite) TestDeleteMirrorNonExisting(c *C) { c.Check(response.Body.String(), Equals, "{\"error\":\"unable to drop: mirror with name does-not-exist not found\"}") } +func (s *MirrorSuite) TestCreateMirrorFlatWithAppStream(c *C) { + body, err := json.Marshal(gin.H{ + "Name": "test-flat-appstream", + "ArchiveURL": "http://example.com/repo/", + "Distribution": "./", + "DownloadAppStream": true, + }) + c.Assert(err, IsNil) + + response, err := s.HTTPRequest("POST", "/api/mirrors", bytes.NewReader(body)) + c.Assert(err, IsNil) + c.Check(response.Code, Equals, 400) + c.Check(response.Body.String(), Matches, ".*AppStream.*flat.*") +} + func (s *MirrorSuite) TestCreateMirror(c *C) { c.ExpectFailure("Need to mock downloads") body, err := json.Marshal(gin.H{ diff --git a/deb/publish_test.go b/deb/publish_test.go index 69b925e8..37c1525e 100644 --- a/deb/publish_test.go +++ b/deb/publish_test.go @@ -427,28 +427,60 @@ func (s *PublishedRepoSuite) TestPublish(c *C) { } func (s *PublishedRepoSuite) TestPublishAppStream(c *C) { - appstreamContent := []byte("DEP-11 test content for Components-amd64.yml.gz") - tmpFile := filepath.Join(c.MkDir(), "Components-amd64.yml.gz") - c.Assert(os.WriteFile(tmpFile, appstreamContent, 0644), IsNil) + // Components + icons + content1 := []byte("DEP-11 test content for Components-amd64.yml.gz") + tmpFile1 := filepath.Join(c.MkDir(), "Components-amd64.yml.gz") + c.Assert(os.WriteFile(tmpFile1, content1, 0644), IsNil) - checksums := utils.ChecksumInfo{Size: int64(len(appstreamContent))} - poolPath, err := s.packagePool.Import(tmpFile, "Components-amd64.yml.gz", &checksums, false, s.cs) + checksums1 := utils.ChecksumInfo{Size: int64(len(content1))} + poolPath1, err := s.packagePool.Import(tmpFile1, "Components-amd64.yml.gz", &checksums1, false, s.cs) + c.Assert(err, IsNil) + + content2 := []byte("DEP-11 icons tar data") + tmpFile2 := filepath.Join(c.MkDir(), "icons-48x48.tar.gz") + c.Assert(os.WriteFile(tmpFile2, content2, 0644), IsNil) + + checksums2 := utils.ChecksumInfo{Size: int64(len(content2))} + poolPath2, err := s.packagePool.Import(tmpFile2, "icons-48x48.tar.gz", &checksums2, false, s.cs) + c.Assert(err, IsNil) + + // Include contrib file that should be skipped + contribContent := []byte("DEP-11 contrib content") + tmpFile3 := filepath.Join(c.MkDir(), "Components-contrib.yml.gz") + c.Assert(os.WriteFile(tmpFile3, contribContent, 0644), IsNil) + + checksums3 := utils.ChecksumInfo{Size: int64(len(contribContent))} + poolPath3, err := s.packagePool.Import(tmpFile3, "Components-contrib.yml.gz", &checksums3, false, s.cs) c.Assert(err, IsNil) s.snapshot.AppStreamFiles = map[string]string{ - "main/dep11/Components-amd64.yml.gz": poolPath, + "main/dep11/Components-amd64.yml.gz": poolPath1, + "main/dep11/icons-48x48.tar.gz": poolPath2, + "contrib/dep11/Components-amd64.yml.gz": poolPath3, } err = s.repo.Publish(s.packagePool, s.provider, s.factory, &NullSigner{}, nil, false, "") c.Assert(err, IsNil) - appstreamPath := filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/dep11/Components-amd64.yml.gz") - c.Check(appstreamPath, PathExists) - - actualContent, err := os.ReadFile(appstreamPath) + // Both main files should exist + appstreamPath1 := filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/dep11/Components-amd64.yml.gz") + c.Check(appstreamPath1, PathExists) + actual1, err := os.ReadFile(appstreamPath1) c.Assert(err, IsNil) - c.Check(actualContent, DeepEquals, appstreamContent) + c.Check(actual1, DeepEquals, content1) + appstreamPath2 := filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/dep11/icons-48x48.tar.gz") + c.Check(appstreamPath2, PathExists) + actual2, err := os.ReadFile(appstreamPath2) + c.Assert(err, IsNil) + c.Check(actual2, DeepEquals, content2) + + // Contrib file should not appear + contribPath := filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/contrib/dep11/Components-amd64.yml.gz") + _, statErr := os.Stat(contribPath) + c.Check(os.IsNotExist(statErr), Equals, true) + + // Release file should reference AppStream files rf, err := os.Open(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/Release")) c.Assert(err, IsNil) defer rf.Close() @@ -459,6 +491,14 @@ func (s *PublishedRepoSuite) TestPublishAppStream(c *C) { c.Check(st["MD5Sum"], Matches, "(?s).*main/dep11/Components-amd64\\.yml\\.gz.*") c.Check(st["SHA256"], Matches, "(?s).*main/dep11/Components-amd64\\.yml\\.gz.*") + + // Pool open error + s.snapshot.AppStreamFiles = map[string]string{ + "main/dep11/Components-amd64.yml.gz": "nonexistent/pool/path", + } + + err = s.repo.Publish(s.packagePool, s.provider, s.factory, &NullSigner{}, nil, false, "") + c.Assert(err, ErrorMatches, "unable to open AppStream file from pool.*") } func (s *PublishedRepoSuite) TestPublishNoSigner(c *C) { diff --git a/deb/remote_test.go b/deb/remote_test.go index d4558c5d..4154e0b8 100644 --- a/deb/remote_test.go +++ b/deb/remote_test.go @@ -2,6 +2,7 @@ package deb import ( "errors" + "fmt" "io" "os" "sort" @@ -724,6 +725,74 @@ func (s *RemoteRepoSuite) TestDownloadWithSourcesFlat(c *C) { c.Assert(s.flat.packageRefs, NotNil) } +func (s *RemoteRepoSuite) TestDownloadAppStreamFiles(c *C) { + // No dep11 entries + s.repo.Components = []string{"main"} + s.repo.ReleaseFiles = map[string]utils.ChecksumInfo{ + "main/binary-amd64/Packages": {Size: 100}, + "main/source/Sources": {Size: 200}, + } + + err := s.repo.DownloadAppStreamFiles(s.progress, s.downloader, s.packagePool, s.cs, false) + c.Assert(err, IsNil) + c.Check(s.repo.AppStreamFiles, HasLen, 0) + + s.repo.ReleaseFiles = map[string]utils.ChecksumInfo{ + "main/dep11/Components-amd64.yml.gz": {Size: 16}, + "main/dep11/icons-48x48.tar.gz": {Size: 16}, + "main/binary-amd64/Packages": {Size: 100}, + } + + downloader := http.NewFakeDownloader() + downloader.AnyExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/Components-amd64.yml.gz", "dep11-components") + downloader.AnyExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/icons-48x48.tar.gz", "dep11-icons-data") + + err = s.repo.DownloadAppStreamFiles(s.progress, downloader, s.packagePool, s.cs, false) + c.Assert(err, IsNil) + c.Check(s.repo.AppStreamFiles, HasLen, 2) + c.Check(s.repo.AppStreamFiles["main/dep11/Components-amd64.yml.gz"], Not(Equals), "") + c.Check(s.repo.AppStreamFiles["main/dep11/icons-48x48.tar.gz"], Not(Equals), "") + + // 404 skipped + s.repo.ReleaseFiles = map[string]utils.ChecksumInfo{ + "main/dep11/Components-amd64.yml.gz": {Size: 16}, + "main/dep11/icons-48x48.tar.gz": {Size: 15}, + } + + downloader = http.NewFakeDownloader() + downloader.AnyExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/Components-amd64.yml.gz", "dep11-components") + downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/icons-48x48.tar.gz", &http.Error{Code: 404, URL: "http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/icons-48x48.tar.gz"}) + + err = s.repo.DownloadAppStreamFiles(s.progress, downloader, s.packagePool, s.cs, false) + c.Assert(err, IsNil) + c.Check(s.repo.AppStreamFiles, HasLen, 1) + c.Check(s.repo.AppStreamFiles["main/dep11/Components-amd64.yml.gz"], Not(Equals), "") + + // Generic download error propagated + s.repo.ReleaseFiles = map[string]utils.ChecksumInfo{ + "main/dep11/Components-amd64.yml.gz": {Size: 18}, + } + + downloader = http.NewFakeDownloader() + downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/Components-amd64.yml.gz", fmt.Errorf("connection refused")) + + err = s.repo.DownloadAppStreamFiles(s.progress, downloader, s.packagePool, s.cs, false) + c.Assert(err, ErrorMatches, "unable to download AppStream file.*connection refused") + + // Bypass checksum validation + s.repo.ReleaseFiles = map[string]utils.ChecksumInfo{ + "main/dep11/Components-amd64.yml.gz": {Size: 999, MD5: "bad", SHA256: "bad"}, + } + + downloader = http.NewFakeDownloader() + downloader.AnyExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/dep11/Components-amd64.yml.gz", "dep11-components") + + err = s.repo.DownloadAppStreamFiles(s.progress, downloader, s.packagePool, s.cs, true) + c.Assert(err, IsNil) + c.Check(s.repo.AppStreamFiles, HasLen, 1) + c.Check(s.repo.AppStreamFiles["main/dep11/Components-amd64.yml.gz"], Not(Equals), "") +} + type RemoteRepoCollectionSuite struct { PackageListMixinSuite db database.Storage