1package deb 2 3import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 "github.com/aptly-dev/aptly/aptly" 12 "github.com/aptly-dev/aptly/database" 13 "github.com/aptly-dev/aptly/files" 14 "github.com/ugorji/go/codec" 15 16 . "gopkg.in/check.v1" 17) 18 19type pathExistsChecker struct { 20 *CheckerInfo 21} 22 23var PathExists = &pathExistsChecker{ 24 &CheckerInfo{Name: "PathExists", Params: []string{"path"}}, 25} 26 27func (checker *pathExistsChecker) Check(params []interface{}, names []string) (result bool, error string) { 28 _, err := os.Stat(params[0].(string)) 29 return err == nil, "" 30} 31 32type NullSigner struct{} 33 34func (n *NullSigner) Init() error { 35 return nil 36} 37 38func (n *NullSigner) SetKey(keyRef string) { 39} 40 41func (n *NullSigner) SetBatch(batch bool) { 42} 43 44func (n *NullSigner) SetKeyRing(keyring, secretKeyring string) { 45} 46 47func (n *NullSigner) SetPassphrase(passphrase, passphraseFile string) { 48} 49 50func (n *NullSigner) DetachedSign(source string, destination string) error { 51 return ioutil.WriteFile(destination, []byte{}, 0644) 52} 53 54func (n *NullSigner) ClearSign(source string, destination string) error { 55 return ioutil.WriteFile(destination, []byte{}, 0644) 56} 57 58type FakeStorageProvider struct { 59 storages map[string]aptly.PublishedStorage 60} 61 62func (p *FakeStorageProvider) GetPublishedStorage(name string) aptly.PublishedStorage { 63 storage, ok := p.storages[name] 64 if !ok { 65 panic(fmt.Sprintf("unknown storage: %#v", name)) 66 } 67 return storage 68} 69 70type PublishedRepoSuite struct { 71 PackageListMixinSuite 72 repo, repo2, repo3, repo4, repo5 *PublishedRepo 73 root, root2 string 74 provider *FakeStorageProvider 75 publishedStorage, publishedStorage2 *files.PublishedStorage 76 packagePool aptly.PackagePool 77 cs aptly.ChecksumStorage 78 localRepo *LocalRepo 79 snapshot, snapshot2 *Snapshot 80 db database.Storage 81 factory *CollectionFactory 82 packageCollection *PackageCollection 83} 84 85var _ = Suite(&PublishedRepoSuite{}) 86 87func (s *PublishedRepoSuite) SetUpTest(c *C) { 88 s.SetUpPackages() 89 90 s.db, _ = database.NewOpenDB(c.MkDir()) 91 s.factory = NewCollectionFactory(s.db) 92 93 s.root = c.MkDir() 94 s.publishedStorage = files.NewPublishedStorage(s.root, "", "") 95 s.root2 = c.MkDir() 96 s.publishedStorage2 = files.NewPublishedStorage(s.root2, "", "") 97 s.provider = &FakeStorageProvider{map[string]aptly.PublishedStorage{ 98 "": s.publishedStorage, 99 "files:other": s.publishedStorage2}} 100 s.packagePool = files.NewPackagePool(s.root, false) 101 s.cs = files.NewMockChecksumStorage() 102 103 tmpFilepath := filepath.Join(c.MkDir(), "file") 104 c.Assert(ioutil.WriteFile(tmpFilepath, nil, 0777), IsNil) 105 106 var err error 107 s.p1.Files()[0].PoolPath, err = s.packagePool.Import(tmpFilepath, s.p1.Files()[0].Filename, &s.p1.Files()[0].Checksums, false, s.cs) 108 c.Assert(err, IsNil) 109 110 s.p1.UpdateFiles(s.p1.Files()) 111 s.p2.UpdateFiles(s.p1.Files()) 112 s.p3.UpdateFiles(s.p1.Files()) 113 114 s.reflist = NewPackageRefListFromPackageList(s.list) 115 116 repo, _ := NewRemoteRepo("yandex", "http://mirror.yandex.ru/debian/", "squeeze", []string{"main"}, []string{}, false, false, false) 117 repo.packageRefs = s.reflist 118 s.factory.RemoteRepoCollection().Add(repo) 119 120 s.localRepo = NewLocalRepo("local1", "comment1") 121 s.localRepo.packageRefs = s.reflist 122 s.factory.LocalRepoCollection().Add(s.localRepo) 123 124 s.snapshot, _ = NewSnapshotFromRepository("snap", repo) 125 s.factory.SnapshotCollection().Add(s.snapshot) 126 127 s.snapshot2, _ = NewSnapshotFromRepository("snap", repo) 128 s.factory.SnapshotCollection().Add(s.snapshot2) 129 130 s.packageCollection = s.factory.PackageCollection() 131 s.packageCollection.Update(s.p1) 132 s.packageCollection.Update(s.p2) 133 s.packageCollection.Update(s.p3) 134 135 s.repo, _ = NewPublishedRepo("", "ppa", "squeeze", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory) 136 s.repo.SkipContents = true 137 138 s.repo2, _ = NewPublishedRepo("", "ppa", "maverick", nil, []string{"main"}, []interface{}{s.localRepo}, s.factory) 139 s.repo2.SkipContents = true 140 141 s.repo3, _ = NewPublishedRepo("", "linux", "natty", nil, []string{"main", "contrib"}, []interface{}{s.snapshot, s.snapshot2}, s.factory) 142 s.repo3.SkipContents = true 143 144 s.repo4, _ = NewPublishedRepo("", "ppa", "maverick", []string{"source"}, []string{"main"}, []interface{}{s.localRepo}, s.factory) 145 s.repo4.SkipContents = true 146 147 s.repo5, _ = NewPublishedRepo("files:other", "ppa", "maverick", []string{"source"}, []string{"main"}, []interface{}{s.localRepo}, s.factory) 148 s.repo5.SkipContents = true 149} 150 151func (s *PublishedRepoSuite) TearDownTest(c *C) { 152 s.db.Close() 153} 154 155func (s *PublishedRepoSuite) TestNewPublishedRepo(c *C) { 156 c.Check(s.repo.sourceItems["main"].snapshot, Equals, s.snapshot) 157 c.Check(s.repo.SourceKind, Equals, "snapshot") 158 c.Check(s.repo.Sources["main"], Equals, s.snapshot.UUID) 159 c.Check(s.repo.Components(), DeepEquals, []string{"main"}) 160 161 c.Check(s.repo2.sourceItems["main"].localRepo, Equals, s.localRepo) 162 c.Check(s.repo2.SourceKind, Equals, "local") 163 c.Check(s.repo2.Sources["main"], Equals, s.localRepo.UUID) 164 c.Check(s.repo2.sourceItems["main"].packageRefs.Len(), Equals, 3) 165 c.Check(s.repo2.Components(), DeepEquals, []string{"main"}) 166 167 c.Check(s.repo.RefList("main").Len(), Equals, 3) 168 c.Check(s.repo2.RefList("main").Len(), Equals, 3) 169 170 c.Check(s.repo3.Sources, DeepEquals, map[string]string{"main": s.snapshot.UUID, "contrib": s.snapshot2.UUID}) 171 c.Check(s.repo3.SourceKind, Equals, "snapshot") 172 c.Check(s.repo3.sourceItems["main"].snapshot, Equals, s.snapshot) 173 c.Check(s.repo3.sourceItems["contrib"].snapshot, Equals, s.snapshot2) 174 c.Check(s.repo3.Components(), DeepEquals, []string{"contrib", "main"}) 175 176 c.Check(s.repo3.RefList("main").Len(), Equals, 3) 177 c.Check(s.repo3.RefList("contrib").Len(), Equals, 3) 178 179 c.Check(func() { NewPublishedRepo("", ".", "a", nil, nil, nil, s.factory) }, PanicMatches, "publish with empty sources") 180 c.Check(func() { 181 NewPublishedRepo("", ".", "a", nil, []string{"main"}, []interface{}{s.snapshot, s.snapshot2}, s.factory) 182 }, PanicMatches, "sources and components should be equal in size") 183 c.Check(func() { 184 NewPublishedRepo("", ".", "a", nil, []string{"main", "contrib"}, []interface{}{s.localRepo, s.snapshot2}, s.factory) 185 }, PanicMatches, "interface conversion:.*") 186 187 _, err := NewPublishedRepo("", ".", "a", nil, []string{"main", "main"}, []interface{}{s.snapshot, s.snapshot2}, s.factory) 188 c.Check(err, ErrorMatches, "duplicate component name: main") 189 190 _, err = NewPublishedRepo("", ".", "wheezy/updates", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory) 191 c.Check(err, ErrorMatches, "invalid distribution wheezy/updates, '/' is not allowed") 192} 193 194func (s *PublishedRepoSuite) TestPrefixNormalization(c *C) { 195 196 for _, t := range []struct { 197 prefix string 198 expected string 199 errorExpected string 200 }{ 201 { 202 prefix: "ppa", 203 expected: "ppa", 204 }, 205 { 206 prefix: "", 207 expected: ".", 208 }, 209 { 210 prefix: "/", 211 expected: ".", 212 }, 213 { 214 prefix: "//", 215 expected: ".", 216 }, 217 { 218 prefix: "//ppa/", 219 expected: "ppa", 220 }, 221 { 222 prefix: "ppa/..", 223 expected: ".", 224 }, 225 { 226 prefix: "ppa/ubuntu/", 227 expected: "ppa/ubuntu", 228 }, 229 { 230 prefix: "ppa/../ubuntu/", 231 expected: "ubuntu", 232 }, 233 { 234 prefix: "../ppa/", 235 errorExpected: "invalid prefix .*", 236 }, 237 { 238 prefix: "../ppa/../ppa/", 239 errorExpected: "invalid prefix .*", 240 }, 241 { 242 prefix: "ppa/dists", 243 errorExpected: "invalid prefix .*", 244 }, 245 { 246 prefix: "ppa/pool", 247 errorExpected: "invalid prefix .*", 248 }, 249 } { 250 repo, err := NewPublishedRepo("", t.prefix, "squeeze", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory) 251 if t.errorExpected != "" { 252 c.Check(err, ErrorMatches, t.errorExpected) 253 } else { 254 c.Check(repo.Prefix, Equals, t.expected) 255 } 256 } 257} 258 259func (s *PublishedRepoSuite) TestDistributionComponentGuessing(c *C) { 260 repo, err := NewPublishedRepo("", "ppa", "", nil, []string{""}, []interface{}{s.snapshot}, s.factory) 261 c.Check(err, IsNil) 262 c.Check(repo.Distribution, Equals, "squeeze") 263 c.Check(repo.Components(), DeepEquals, []string{"main"}) 264 265 repo, err = NewPublishedRepo("", "ppa", "wheezy", nil, []string{""}, []interface{}{s.snapshot}, s.factory) 266 c.Check(err, IsNil) 267 c.Check(repo.Distribution, Equals, "wheezy") 268 c.Check(repo.Components(), DeepEquals, []string{"main"}) 269 270 repo, err = NewPublishedRepo("", "ppa", "", nil, []string{"non-free"}, []interface{}{s.snapshot}, s.factory) 271 c.Check(err, IsNil) 272 c.Check(repo.Distribution, Equals, "squeeze") 273 c.Check(repo.Components(), DeepEquals, []string{"non-free"}) 274 275 repo, err = NewPublishedRepo("", "ppa", "squeeze", nil, []string{""}, []interface{}{s.localRepo}, s.factory) 276 c.Check(err, IsNil) 277 c.Check(repo.Distribution, Equals, "squeeze") 278 c.Check(repo.Components(), DeepEquals, []string{"main"}) 279 280 _, err = NewPublishedRepo("", "ppa", "", nil, []string{"main"}, []interface{}{s.localRepo}, s.factory) 281 c.Check(err, ErrorMatches, "unable to guess distribution name, please specify explicitly") 282 283 s.localRepo.DefaultDistribution = "precise" 284 s.localRepo.DefaultComponent = "contrib" 285 s.factory.LocalRepoCollection().Update(s.localRepo) 286 287 repo, err = NewPublishedRepo("", "ppa", "", nil, []string{""}, []interface{}{s.localRepo}, s.factory) 288 c.Check(err, IsNil) 289 c.Check(repo.Distribution, Equals, "precise") 290 c.Check(repo.Components(), DeepEquals, []string{"contrib"}) 291 292 s.localRepo.DefaultDistribution = "precise/updates" 293 294 repo, err = NewPublishedRepo("", "ppa", "", nil, []string{""}, []interface{}{s.localRepo}, s.factory) 295 c.Check(err, IsNil) 296 c.Check(repo.Distribution, Equals, "precise-updates") 297 c.Check(repo.Components(), DeepEquals, []string{"contrib"}) 298 299 repo, err = NewPublishedRepo("", "ppa", "", nil, []string{"", "contrib"}, []interface{}{s.snapshot, s.snapshot2}, s.factory) 300 c.Check(err, IsNil) 301 c.Check(repo.Distribution, Equals, "squeeze") 302 c.Check(repo.Components(), DeepEquals, []string{"contrib", "main"}) 303 304 _, err = NewPublishedRepo("", "ppa", "", nil, []string{"", ""}, []interface{}{s.snapshot, s.snapshot2}, s.factory) 305 c.Check(err, ErrorMatches, "duplicate component name: main") 306} 307 308func (s *PublishedRepoSuite) TestPublish(c *C) { 309 err := s.repo.Publish(s.packagePool, s.provider, s.factory, &NullSigner{}, nil, false) 310 c.Assert(err, IsNil) 311 312 c.Check(s.repo.Architectures, DeepEquals, []string{"i386"}) 313 314 rf, err := os.Open(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/Release")) 315 c.Assert(err, IsNil) 316 317 cfr := NewControlFileReader(rf, true, false) 318 st, err := cfr.ReadStanza() 319 c.Assert(err, IsNil) 320 321 c.Check(st["Origin"], Equals, "ppa squeeze") 322 c.Check(st["Components"], Equals, "main") 323 c.Check(st["Architectures"], Equals, "i386") 324 325 pf, err := os.Open(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/binary-i386/Packages")) 326 c.Assert(err, IsNil) 327 328 cfr = NewControlFileReader(pf, false, false) 329 330 for i := 0; i < 3; i++ { 331 st, err = cfr.ReadStanza() 332 c.Assert(err, IsNil) 333 334 c.Check(st["Filename"], Equals, "pool/main/a/alien-arena/alien-arena-common_7.40-2_i386.deb") 335 } 336 337 st, err = cfr.ReadStanza() 338 c.Assert(err, IsNil) 339 c.Assert(st, IsNil) 340 341 drf, err := os.Open(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/binary-i386/Release")) 342 c.Assert(err, IsNil) 343 344 cfr = NewControlFileReader(drf, true, false) 345 st, err = cfr.ReadStanza() 346 c.Assert(err, IsNil) 347 348 c.Check(st["Archive"], Equals, "squeeze") 349 c.Check(st["Architecture"], Equals, "i386") 350 351 _, err = os.Stat(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main/a/alien-arena/alien-arena-common_7.40-2_i386.deb")) 352 c.Assert(err, IsNil) 353} 354 355func (s *PublishedRepoSuite) TestPublishNoSigner(c *C) { 356 err := s.repo.Publish(s.packagePool, s.provider, s.factory, nil, nil, false) 357 c.Assert(err, IsNil) 358 359 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/Release"), PathExists) 360 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/binary-i386/Release"), PathExists) 361} 362 363func (s *PublishedRepoSuite) TestPublishLocalRepo(c *C) { 364 err := s.repo2.Publish(s.packagePool, s.provider, s.factory, nil, nil, false) 365 c.Assert(err, IsNil) 366 367 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), PathExists) 368 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/main/binary-i386/Release"), PathExists) 369} 370 371func (s *PublishedRepoSuite) TestPublishLocalSourceRepo(c *C) { 372 err := s.repo4.Publish(s.packagePool, s.provider, s.factory, nil, nil, false) 373 c.Assert(err, IsNil) 374 375 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), PathExists) 376 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/main/source/Release"), PathExists) 377} 378 379func (s *PublishedRepoSuite) TestPublishOtherStorage(c *C) { 380 err := s.repo5.Publish(s.packagePool, s.provider, s.factory, nil, nil, false) 381 c.Assert(err, IsNil) 382 383 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/maverick/Release"), PathExists) 384 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), Not(PathExists)) 385} 386 387func (s *PublishedRepoSuite) TestString(c *C) { 388 c.Check(s.repo.String(), Equals, 389 "ppa/squeeze [] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 390 c.Check(s.repo2.String(), Equals, 391 "ppa/maverick [] publishes {main: [local1]: comment1}") 392 repo, _ := NewPublishedRepo("", "", "squeeze", []string{"s390"}, []string{"main"}, []interface{}{s.snapshot}, s.factory) 393 c.Check(repo.String(), Equals, 394 "./squeeze [s390] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 395 repo, _ = NewPublishedRepo("", "", "squeeze", []string{"i386", "amd64"}, []string{"main"}, []interface{}{s.snapshot}, s.factory) 396 c.Check(repo.String(), Equals, 397 "./squeeze [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 398 repo.Origin = "myorigin" 399 c.Check(repo.String(), Equals, 400 "./squeeze (origin: myorigin) [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 401 repo.Label = "mylabel" 402 c.Check(repo.String(), Equals, 403 "./squeeze (origin: myorigin, label: mylabel) [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 404 c.Check(s.repo3.String(), Equals, 405 "linux/natty [] publishes {contrib: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}, {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}") 406 c.Check(s.repo5.String(), Equals, 407 "files:other:ppa/maverick [source] publishes {main: [local1]: comment1}") 408} 409 410func (s *PublishedRepoSuite) TestKey(c *C) { 411 c.Check(s.repo.Key(), DeepEquals, []byte("Uppa>>squeeze")) 412 c.Check(s.repo5.Key(), DeepEquals, []byte("Ufiles:other:ppa>>maverick")) 413} 414 415func (s *PublishedRepoSuite) TestRefKey(c *C) { 416 c.Check(s.repo.RefKey(""), DeepEquals, []byte("E"+s.repo.UUID)) 417 c.Check(s.repo.RefKey("main"), DeepEquals, []byte("E"+s.repo.UUID+"main")) 418} 419 420func (s *PublishedRepoSuite) TestEncodeDecode(c *C) { 421 encoded := s.repo.Encode() 422 repo := &PublishedRepo{} 423 err := repo.Decode(encoded) 424 425 s.repo.sourceItems = nil 426 c.Assert(err, IsNil) 427 c.Assert(repo, DeepEquals, s.repo) 428 429 encoded2 := s.repo2.Encode() 430 repo2 := &PublishedRepo{} 431 err = repo2.Decode(encoded2) 432 433 s.repo2.sourceItems = nil 434 c.Assert(err, IsNil) 435 c.Assert(repo2, DeepEquals, s.repo2) 436} 437 438type PublishedRepoCollectionSuite struct { 439 PackageListMixinSuite 440 db database.Storage 441 factory *CollectionFactory 442 snapshotCollection *SnapshotCollection 443 collection *PublishedRepoCollection 444 snap1, snap2 *Snapshot 445 localRepo *LocalRepo 446 repo1, repo2, repo3, repo4, repo5 *PublishedRepo 447} 448 449var _ = Suite(&PublishedRepoCollectionSuite{}) 450 451func (s *PublishedRepoCollectionSuite) SetUpTest(c *C) { 452 s.db, _ = database.NewOpenDB(c.MkDir()) 453 s.factory = NewCollectionFactory(s.db) 454 455 s.snapshotCollection = s.factory.SnapshotCollection() 456 457 s.snap1 = NewSnapshotFromPackageList("snap1", []*Snapshot{}, NewPackageList(), "desc1") 458 s.snap2 = NewSnapshotFromPackageList("snap2", []*Snapshot{}, NewPackageList(), "desc2") 459 460 s.snapshotCollection.Add(s.snap1) 461 s.snapshotCollection.Add(s.snap2) 462 463 s.localRepo = NewLocalRepo("local1", "comment1") 464 s.factory.LocalRepoCollection().Add(s.localRepo) 465 466 s.repo1, _ = NewPublishedRepo("", "ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory) 467 s.repo2, _ = NewPublishedRepo("", "", "anaconda", []string{}, []string{"main", "contrib"}, []interface{}{s.snap2, s.snap1}, s.factory) 468 s.repo3, _ = NewPublishedRepo("", "ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap2}, s.factory) 469 s.repo4, _ = NewPublishedRepo("", "ppa", "precise", []string{}, []string{"main"}, []interface{}{s.localRepo}, s.factory) 470 s.repo5, _ = NewPublishedRepo("files:other", "ppa", "precise", []string{}, []string{"main"}, []interface{}{s.localRepo}, s.factory) 471 472 s.collection = s.factory.PublishedRepoCollection() 473} 474 475func (s *PublishedRepoCollectionSuite) TearDownTest(c *C) { 476 s.db.Close() 477} 478 479func (s *PublishedRepoCollectionSuite) TestAddByStoragePrefixDistribution(c *C) { 480 _, err := s.collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 481 c.Assert(err, ErrorMatches, "*.not found") 482 483 c.Assert(s.collection.Add(s.repo1), IsNil) 484 c.Assert(s.collection.Add(s.repo1), ErrorMatches, ".*already exists") 485 c.Assert(s.collection.CheckDuplicate(s.repo2), IsNil) 486 c.Assert(s.collection.Add(s.repo2), IsNil) 487 c.Assert(s.collection.Add(s.repo3), ErrorMatches, ".*already exists") 488 c.Assert(s.collection.CheckDuplicate(s.repo3), Equals, s.repo1) 489 c.Assert(s.collection.Add(s.repo4), IsNil) 490 c.Assert(s.collection.Add(s.repo5), IsNil) 491 492 r, err := s.collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 493 c.Assert(err, IsNil) 494 495 err = s.collection.LoadComplete(r, s.factory) 496 c.Assert(err, IsNil) 497 c.Assert(r.String(), Equals, s.repo1.String()) 498 499 collection := NewPublishedRepoCollection(s.db) 500 r, err = collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 501 c.Assert(err, IsNil) 502 503 err = s.collection.LoadComplete(r, s.factory) 504 c.Assert(err, IsNil) 505 c.Assert(r.String(), Equals, s.repo1.String()) 506 507 r, err = s.collection.ByStoragePrefixDistribution("files:other", "ppa", "precise") 508 c.Assert(err, IsNil) 509 c.Check(r.String(), Equals, s.repo5.String()) 510} 511 512func (s *PublishedRepoCollectionSuite) TestByUUID(c *C) { 513 _, err := s.collection.ByUUID(s.repo1.UUID) 514 c.Assert(err, ErrorMatches, "*.not found") 515 516 c.Assert(s.collection.Add(s.repo1), IsNil) 517 518 r, err := s.collection.ByUUID(s.repo1.UUID) 519 c.Assert(err, IsNil) 520 521 err = s.collection.LoadComplete(r, s.factory) 522 c.Assert(err, IsNil) 523 c.Assert(r.String(), Equals, s.repo1.String()) 524} 525 526func (s *PublishedRepoCollectionSuite) TestUpdateLoadComplete(c *C) { 527 c.Assert(s.collection.Update(s.repo1), IsNil) 528 c.Assert(s.collection.Update(s.repo4), IsNil) 529 530 collection := NewPublishedRepoCollection(s.db) 531 r, err := collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 532 c.Assert(err, IsNil) 533 c.Assert(r.sourceItems["main"].snapshot, IsNil) 534 c.Assert(s.collection.LoadComplete(r, s.factory), IsNil) 535 c.Assert(r.Sources["main"], Equals, s.repo1.sourceItems["main"].snapshot.UUID) 536 c.Assert(r.RefList("main").Len(), Equals, 0) 537 538 r, err = collection.ByStoragePrefixDistribution("", "ppa", "precise") 539 c.Assert(err, IsNil) 540 c.Assert(r.sourceItems["main"].localRepo, IsNil) 541 c.Assert(s.collection.LoadComplete(r, s.factory), IsNil) 542 c.Assert(r.sourceItems["main"].localRepo.UUID, Equals, s.repo4.sourceItems["main"].localRepo.UUID) 543 c.Assert(r.sourceItems["main"].packageRefs.Len(), Equals, 0) 544 c.Assert(r.RefList("main").Len(), Equals, 0) 545} 546 547func (s *PublishedRepoCollectionSuite) TestLoadPre0_6(c *C) { 548 type oldPublishedRepo struct { 549 UUID string 550 Prefix string 551 Distribution string 552 Origin string 553 Label string 554 Architectures []string 555 SourceKind string 556 Component string 557 SourceUUID string `codec:"SnapshotUUID"` 558 } 559 560 old := oldPublishedRepo{ 561 UUID: s.repo1.UUID, 562 Prefix: "ppa", 563 Distribution: "anaconda", 564 Architectures: []string{"i386"}, 565 SourceKind: SourceLocalRepo, 566 Component: "contrib", 567 SourceUUID: s.localRepo.UUID, 568 } 569 570 var buf bytes.Buffer 571 572 encoder := codec.NewEncoder(&buf, &codec.MsgpackHandle{}) 573 encoder.Encode(&old) 574 575 c.Assert(s.db.Put(s.repo1.Key(), buf.Bytes()), IsNil) 576 c.Assert(s.db.Put(s.repo1.RefKey(""), s.localRepo.RefList().Encode()), IsNil) 577 578 collection := NewPublishedRepoCollection(s.db) 579 repo, err := collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 580 c.Check(err, IsNil) 581 c.Check(repo.Component, Equals, "") 582 c.Check(repo.SourceUUID, Equals, "") 583 c.Check(repo.Sources, DeepEquals, map[string]string{"contrib": s.localRepo.UUID}) 584 585 c.Check(collection.LoadComplete(repo, s.factory), IsNil) 586 c.Check(repo.sourceItems["contrib"].localRepo.UUID, Equals, s.localRepo.UUID) 587 c.Check(repo.RefList("contrib").Len(), Equals, 0) 588} 589 590func (s *PublishedRepoCollectionSuite) TestForEachAndLen(c *C) { 591 s.collection.Add(s.repo1) 592 593 count := 0 594 err := s.collection.ForEach(func(*PublishedRepo) error { 595 count++ 596 return nil 597 }) 598 c.Assert(count, Equals, 1) 599 c.Assert(err, IsNil) 600 601 c.Check(s.collection.Len(), Equals, 1) 602 603 e := errors.New("c") 604 605 err = s.collection.ForEach(func(*PublishedRepo) error { 606 return e 607 }) 608 c.Assert(err, Equals, e) 609} 610 611func (s *PublishedRepoCollectionSuite) TestBySnapshot(c *C) { 612 c.Check(s.collection.Add(s.repo1), IsNil) 613 c.Check(s.collection.Add(s.repo2), IsNil) 614 615 c.Check(s.collection.BySnapshot(s.snap1), DeepEquals, []*PublishedRepo{s.repo1, s.repo2}) 616 c.Check(s.collection.BySnapshot(s.snap2), DeepEquals, []*PublishedRepo{s.repo2}) 617} 618 619func (s *PublishedRepoCollectionSuite) TestByLocalRepo(c *C) { 620 c.Check(s.collection.Add(s.repo1), IsNil) 621 c.Check(s.collection.Add(s.repo4), IsNil) 622 c.Check(s.collection.Add(s.repo5), IsNil) 623 624 c.Check(s.collection.ByLocalRepo(s.localRepo), DeepEquals, []*PublishedRepo{s.repo4, s.repo5}) 625} 626 627type PublishedRepoRemoveSuite struct { 628 PackageListMixinSuite 629 db database.Storage 630 factory *CollectionFactory 631 snapshotCollection *SnapshotCollection 632 collection *PublishedRepoCollection 633 root, root2 string 634 provider *FakeStorageProvider 635 publishedStorage, publishedStorage2 *files.PublishedStorage 636 snap1 *Snapshot 637 repo1, repo2, repo3, repo4, repo5 *PublishedRepo 638} 639 640var _ = Suite(&PublishedRepoRemoveSuite{}) 641 642func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) { 643 s.db, _ = database.NewOpenDB(c.MkDir()) 644 s.factory = NewCollectionFactory(s.db) 645 646 s.snapshotCollection = s.factory.SnapshotCollection() 647 648 s.snap1 = NewSnapshotFromPackageList("snap1", []*Snapshot{}, NewPackageList(), "desc1") 649 650 s.snapshotCollection.Add(s.snap1) 651 652 s.repo1, _ = NewPublishedRepo("", "ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory) 653 s.repo2, _ = NewPublishedRepo("", "", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory) 654 s.repo3, _ = NewPublishedRepo("", "ppa", "meduza", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory) 655 s.repo4, _ = NewPublishedRepo("", "ppa", "osminog", []string{}, []string{"contrib"}, []interface{}{s.snap1}, s.factory) 656 s.repo5, _ = NewPublishedRepo("files:other", "ppa", "osminog", []string{}, []string{"contrib"}, []interface{}{s.snap1}, s.factory) 657 658 s.collection = s.factory.PublishedRepoCollection() 659 s.collection.Add(s.repo1) 660 s.collection.Add(s.repo2) 661 s.collection.Add(s.repo3) 662 s.collection.Add(s.repo4) 663 s.collection.Add(s.repo5) 664 665 s.root = c.MkDir() 666 s.publishedStorage = files.NewPublishedStorage(s.root, "", "") 667 s.publishedStorage.MkDir("ppa/dists/anaconda") 668 s.publishedStorage.MkDir("ppa/dists/meduza") 669 s.publishedStorage.MkDir("ppa/dists/osminog") 670 s.publishedStorage.MkDir("ppa/pool/main") 671 s.publishedStorage.MkDir("ppa/pool/contrib") 672 s.publishedStorage.MkDir("dists/anaconda") 673 s.publishedStorage.MkDir("pool/main") 674 675 s.root2 = c.MkDir() 676 s.publishedStorage2 = files.NewPublishedStorage(s.root2, "", "") 677 s.publishedStorage2.MkDir("ppa/dists/osminog") 678 s.publishedStorage2.MkDir("ppa/pool/contrib") 679 680 s.provider = &FakeStorageProvider{map[string]aptly.PublishedStorage{ 681 "": s.publishedStorage, 682 "files:other": s.publishedStorage2}} 683} 684 685func (s *PublishedRepoRemoveSuite) TearDownTest(c *C) { 686 s.db.Close() 687} 688 689func (s *PublishedRepoRemoveSuite) TestRemoveFilesOnlyDist(c *C) { 690 s.repo1.RemoveFiles(s.provider, false, []string{}, nil) 691 692 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 693 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 694 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 695 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 696 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 697 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 698 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 699 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 700 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 701} 702 703func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPool(c *C) { 704 s.repo1.RemoveFiles(s.provider, false, []string{"main"}, nil) 705 706 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 707 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 708 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 709 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists)) 710 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 711 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 712 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 713 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 714 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 715} 716 717func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithTwoPools(c *C) { 718 s.repo1.RemoveFiles(s.provider, false, []string{"main", "contrib"}, nil) 719 720 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 721 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 722 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 723 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists)) 724 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), Not(PathExists)) 725 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 726 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 727 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 728 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 729} 730 731func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefix(c *C) { 732 s.repo1.RemoveFiles(s.provider, true, []string{"main"}, nil) 733 734 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 735 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), Not(PathExists)) 736 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), Not(PathExists)) 737 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists)) 738 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), Not(PathExists)) 739 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 740 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 741 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 742 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 743} 744 745func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefixRoot(c *C) { 746 s.repo2.RemoveFiles(s.provider, true, []string{"main"}, nil) 747 748 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), PathExists) 749 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 750 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 751 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 752 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), Not(PathExists)) 753 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), Not(PathExists)) 754 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 755 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 756} 757 758func (s *PublishedRepoRemoveSuite) TestRemoveRepo1and2(c *C) { 759 err := s.collection.Remove(s.provider, "", "ppa", "anaconda", s.factory, nil, false, false) 760 c.Check(err, IsNil) 761 762 _, err = s.collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 763 c.Check(err, ErrorMatches, ".*not found") 764 765 collection := NewPublishedRepoCollection(s.db) 766 _, err = collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 767 c.Check(err, ErrorMatches, ".*not found") 768 769 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 770 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 771 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 772 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 773 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 774 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 775 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 776 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 777 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 778 779 err = s.collection.Remove(s.provider, "", "ppa", "anaconda", s.factory, nil, false, false) 780 c.Check(err, ErrorMatches, ".*not found") 781 782 err = s.collection.Remove(s.provider, "", "ppa", "meduza", s.factory, nil, false, false) 783 c.Check(err, IsNil) 784 785 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 786 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), Not(PathExists)) 787 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 788 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists)) 789 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 790 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 791 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 792 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 793 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 794} 795 796func (s *PublishedRepoRemoveSuite) TestRemoveRepo1and2SkipCleanup(c *C) { 797 err := s.collection.Remove(s.provider, "", "ppa", "anaconda", s.factory, nil, false, true) 798 c.Check(err, IsNil) 799 800 _, err = s.collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 801 c.Check(err, ErrorMatches, ".*not found") 802 803 collection := NewPublishedRepoCollection(s.db) 804 _, err = collection.ByStoragePrefixDistribution("", "ppa", "anaconda") 805 c.Check(err, ErrorMatches, ".*not found") 806 807 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 808 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 809 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 810 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 811 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 812 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 813 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 814 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 815 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 816 817 err = s.collection.Remove(s.provider, "", "ppa", "anaconda", s.factory, nil, false, true) 818 c.Check(err, ErrorMatches, ".*not found") 819 820 err = s.collection.Remove(s.provider, "", "ppa", "meduza", s.factory, nil, false, true) 821 c.Check(err, IsNil) 822 823 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists)) 824 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), Not(PathExists)) 825 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 826 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists)) 827 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 828 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists) 829 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists) 830 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 831 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 832} 833 834func (s *PublishedRepoRemoveSuite) TestRemoveRepo3(c *C) { 835 err := s.collection.Remove(s.provider, "", ".", "anaconda", s.factory, nil, false, false) 836 c.Check(err, IsNil) 837 838 _, err = s.collection.ByStoragePrefixDistribution("", ".", "anaconda") 839 c.Check(err, ErrorMatches, ".*not found") 840 841 collection := NewPublishedRepoCollection(s.db) 842 _, err = collection.ByStoragePrefixDistribution("", ".", "anaconda") 843 c.Check(err, ErrorMatches, ".*not found") 844 845 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), PathExists) 846 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 847 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 848 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 849 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 850 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/"), Not(PathExists)) 851 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/"), Not(PathExists)) 852 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), PathExists) 853 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), PathExists) 854} 855 856func (s *PublishedRepoRemoveSuite) TestRemoveRepo5(c *C) { 857 err := s.collection.Remove(s.provider, "files:other", "ppa", "osminog", s.factory, nil, false, false) 858 c.Check(err, IsNil) 859 860 _, err = s.collection.ByStoragePrefixDistribution("files:other", "ppa", "osminog") 861 c.Check(err, ErrorMatches, ".*not found") 862 863 collection := NewPublishedRepoCollection(s.db) 864 _, err = collection.ByStoragePrefixDistribution("files:other", "ppa", "osminog") 865 c.Check(err, ErrorMatches, ".*not found") 866 867 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), PathExists) 868 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists) 869 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists) 870 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), PathExists) 871 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), PathExists) 872 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/"), PathExists) 873 c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/"), PathExists) 874 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/dists/osminog"), Not(PathExists)) 875 c.Check(filepath.Join(s.publishedStorage2.PublicPath(), "ppa/pool/contrib"), Not(PathExists)) 876} 877