34
34
s.stub = &testing.Stub{}
35
35
s.base = statetest.NewStubPersistence(s.stub)
36
s.base.ReturnServiceExistsOps = []txn.Op{{
39
Assert: txn.DocExists,
38
43
func (s *ResourcePersistenceSuite) TestListResourcesOkay(c *gc.C) {
39
44
expected, docs := newPersistenceResources(c, "a-service", "spam", "eggs")
40
45
expected.CharmStoreResources[1].Revision += 1
41
46
docs[3].Revision += 1
42
unitRes, doc := newPersistenceUnitResource(c, "a-service", "a-service/0", "something")
47
unitRes, unitDocs := newPersistenceUnitResources(c, "a-service", "a-service/0", expected.Resources)
48
var progress int64 = 3
49
unitDocs[1].DownloadProgress = &progress // the "eggs" doc
43
50
expected.UnitResources = []resource.UnitResources{{
44
Tag: names.NewUnitTag("a-service/0"),
45
Resources: []resource.Resource{
51
Tag: names.NewUnitTag("a-service/0"),
53
DownloadProgress: map[string]int64{
49
docs = append(docs, doc)
57
docs = append(docs, unitDocs...)
50
58
s.base.ReturnAll = docs
51
59
p := NewResourcePersistence(s.base)
184
192
doc.DocID += "#staged"
185
193
p := NewResourcePersistence(s.base)
186
194
ignoredErr := errors.New("<never reached>")
187
s.stub.SetErrors(nil, nil, ignoredErr)
195
s.stub.SetErrors(nil, nil, nil, ignoredErr)
189
197
staged, err := p.StageResource(res.Resource, res.storagePath)
190
198
c.Assert(err, jc.ErrorIsNil)
192
s.stub.CheckCallNames(c, "Run", "RunTransaction")
193
s.stub.CheckCall(c, 1, "RunTransaction", []txn.Op{{
200
s.stub.CheckCallNames(c, "Run", "ServiceExistsOps", "RunTransaction")
201
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
195
203
Id: "resource#a-service/spam#staged",
196
204
Assert: txn.DocMissing,
209
Assert: txn.DocExists,
199
211
c.Check(staged, jc.DeepEquals, &StagedResource{
232
244
s.base.ReturnOne = doc
233
245
p := NewResourcePersistence(s.base)
234
246
ignoredErr := errors.New("<never reached>")
235
s.stub.SetErrors(nil, nil, nil, ignoredErr)
247
s.stub.SetErrors(nil, nil, nil, nil, ignoredErr)
237
249
err := p.SetResource(res.Resource)
238
250
c.Assert(err, jc.ErrorIsNil)
240
252
s.stub.CheckCallNames(c,
243
256
"RunTransaction",
245
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
258
s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
247
260
Id: "resource#a-service/spam",
248
261
Assert: txn.DocMissing,
266
Assert: txn.DocExists,
259
276
p := NewResourcePersistence(s.base)
260
277
notFound := errors.NewNotFound(nil, "")
261
278
ignoredErr := errors.New("<never reached>")
262
s.stub.SetErrors(notFound, nil, nil, ignoredErr)
279
s.stub.SetErrors(notFound, nil, nil, nil, ignoredErr)
264
281
err := p.SetResource(res.Resource)
265
282
c.Assert(err, jc.ErrorIsNil)
267
284
s.stub.CheckCallNames(c,
270
288
"RunTransaction",
272
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
290
s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
274
292
Id: "resource#a-service/spam",
275
293
Assert: txn.DocMissing,
276
294
Insert: &expected,
298
Assert: txn.DocExists,
297
319
s.stub.CheckCallNames(c,
299
322
"RunTransaction",
301
s.stub.CheckCall(c, 1, "RunTransaction", []txn.Op{{
324
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
303
326
Id: "resource#a-service/spam#charmstore",
304
327
Assert: txn.DocMissing,
305
328
Insert: &expected,
332
Assert: txn.DocExists,
313
340
s.base.ReturnOne = doc
314
341
p := NewResourcePersistence(s.base)
315
342
ignoredErr := errors.New("<never reached>")
316
s.stub.SetErrors(nil, nil, nil, ignoredErr)
343
s.stub.SetErrors(nil, nil, nil, nil, ignoredErr)
318
345
err := p.SetUnitResource("a-service/0", res)
319
346
c.Assert(err, jc.ErrorIsNil)
321
s.stub.CheckCallNames(c, "One", "Run", "RunTransaction")
322
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
348
s.stub.CheckCallNames(c, "One", "Run", "ServiceExistsOps", "RunTransaction")
349
s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
324
351
Id: "resource#a-service/eggs#unit-a-service/0",
325
352
Assert: txn.DocMissing,
357
Assert: txn.DocExists,
347
378
s.base.ReturnOne = doc
348
379
p := NewResourcePersistence(s.base)
349
380
ignoredErr := errors.New("<never reached>")
350
s.stub.SetErrors(nil, nil, txn.ErrAborted, nil, ignoredErr)
381
s.stub.SetErrors(nil, nil, nil, txn.ErrAborted, nil, nil, ignoredErr)
352
383
err := p.SetUnitResource("a-service/0", res)
353
384
c.Assert(err, jc.ErrorIsNil)
355
s.stub.CheckCallNames(c, "One", "Run", "RunTransaction", "RunTransaction")
356
s.stub.CheckCall(c, 2, "RunTransaction", []txn.Op{{
358
Id: "resource#a-service/spam#unit-a-service/0",
359
Assert: txn.DocMissing,
386
s.stub.CheckCallNames(c, "One", "Run", "ServiceExistsOps", "RunTransaction", "ServiceExistsOps", "RunTransaction")
362
387
s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
364
389
Id: "resource#a-service/spam#unit-a-service/0",
390
Assert: txn.DocMissing,
395
Assert: txn.DocExists,
397
s.stub.CheckCall(c, 5, "RunTransaction", []txn.Op{{
399
Id: "resource#a-service/spam#unit-a-service/0",
365
400
Assert: txn.DocExists,
386
425
s.stub.CheckCallNames(c, "One")
428
func (s *ResourcePersistenceSuite) TestSetUnitResourceProgress(c *gc.C) {
429
servicename := "a-service"
430
unitname := "a-service/0"
431
res, doc := newPersistenceUnitResource(c, servicename, unitname, "eggs")
432
s.base.ReturnOne = doc
433
pendingID := "<a pending ID>"
434
res.PendingID = pendingID
435
expected := doc // a copy
436
expected.PendingID = pendingID
437
var progress int64 = 2
438
expected.DownloadProgress = &progress
439
p := NewResourcePersistence(s.base)
440
ignoredErr := errors.New("<never reached>")
441
s.stub.SetErrors(nil, nil, nil, nil, ignoredErr)
443
err := p.SetUnitResourceProgress("a-service/0", res, progress)
444
c.Assert(err, jc.ErrorIsNil)
446
s.stub.CheckCallNames(c, "One", "Run", "ServiceExistsOps", "RunTransaction")
447
s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
449
Id: "resource#a-service/eggs#unit-a-service/0",
450
Assert: txn.DocMissing,
455
Assert: txn.DocExists,
389
459
func (s *ResourcePersistenceSuite) TestNewResourcePendingResourceOpsExists(c *gc.C) {
390
460
pendingID := "some-unique-ID-001"
391
461
stored, expected := newPersistenceResource(c, "a-service", "spam")
396
466
s.base.ReturnOne = doc
397
467
p := NewResourcePersistence(s.base)
469
lastPolled := time.Now().UTC().Round(time.Second)
399
471
ops, err := p.NewResolvePendingResourceOps(stored.ID, stored.PendingID)
400
472
c.Assert(err, jc.ErrorIsNil)
474
csresourceDoc := expected
475
csresourceDoc.DocID = "resource#a-service/spam#charmstore"
476
csresourceDoc.Username = ""
477
csresourceDoc.Timestamp = time.Time{}
478
csresourceDoc.StoragePath = ""
479
csresourceDoc.LastPolled = lastPolled
481
res := ops[4].Insert.(*resourceDoc)
482
res.LastPolled = res.LastPolled.Round(time.Second)
402
484
s.stub.CheckCallNames(c, "One", "One")
403
485
s.stub.CheckCall(c, 0, "One", "resources", "resource#a-service/spam#pending-some-unique-ID-001", &doc)
404
c.Check(ops, jc.DeepEquals, []txn.Op{{
407
Assert: txn.DocExists,
412
Assert: txn.DocExists,
417
Assert: txn.DocMissing,
486
c.Check(ops, jc.DeepEquals, []txn.Op{
490
Assert: txn.DocExists,
495
Assert: txn.DocExists,
500
Assert: txn.DocMissing,
505
Id: csresourceDoc.DocID,
506
Assert: txn.DocExists,
511
Id: csresourceDoc.DocID,
512
Assert: txn.DocMissing,
513
Insert: &csresourceDoc,
422
518
func (s *ResourcePersistenceSuite) TestNewResourcePendingResourceOpsNotFound(c *gc.C) {
431
527
s.stub.SetErrors(nil, notFound)
432
528
p := NewResourcePersistence(s.base)
530
lastPolled := time.Now().UTC().Round(time.Second)
434
531
ops, err := p.NewResolvePendingResourceOps(stored.ID, stored.PendingID)
435
532
c.Assert(err, jc.ErrorIsNil)
437
534
s.stub.CheckCallNames(c, "One", "One")
438
535
s.stub.CheckCall(c, 0, "One", "resources", "resource#a-service/spam#pending-some-unique-ID-001", &doc)
439
c.Check(ops, jc.DeepEquals, []txn.Op{{
442
Assert: txn.DocExists,
447
Assert: txn.DocMissing,
537
csresourceDoc := expected
538
csresourceDoc.DocID = "resource#a-service/spam#charmstore"
539
csresourceDoc.Username = ""
540
csresourceDoc.Timestamp = time.Time{}
541
csresourceDoc.StoragePath = ""
542
csresourceDoc.LastPolled = lastPolled
544
res := ops[2].Insert.(*resourceDoc)
545
res.LastPolled = res.LastPolled.Round(time.Second)
547
c.Check(ops, jc.DeepEquals, []txn.Op{
551
Assert: txn.DocExists,
556
Assert: txn.DocMissing,
561
Id: csresourceDoc.DocID,
562
Assert: txn.DocMissing,
563
Insert: &csresourceDoc,
568
func newPersistenceUnitResources(c *gc.C, serviceID, unitID string, resources []resource.Resource) ([]resource.Resource, []resourceDoc) {
569
var unitResources []resource.Resource
570
var docs []resourceDoc
571
for _, res := range resources {
572
res, doc := newPersistenceUnitResource(c, serviceID, unitID, res.Name)
573
unitResources = append(unitResources, res)
574
docs = append(docs, doc)
576
return unitResources, docs
579
func newPersistenceUnitResource(c *gc.C, serviceID, unitID, name string) (resource.Resource, resourceDoc) {
580
res, doc := newPersistenceResource(c, serviceID, name)
581
doc.DocID += "#unit-" + unitID
583
return res.Resource, doc
452
586
func newPersistenceResources(c *gc.C, serviceID string, names ...string) (resource.ServiceResources, []resourceDoc) {
468
602
return svcResources, docs
471
func newPersistenceUnitResource(c *gc.C, serviceID, unitID, name string) (resource.Resource, resourceDoc) {
472
res, doc := newPersistenceResource(c, serviceID, name)
473
doc.DocID += "#unit-" + unitID
475
return res.Resource, doc
478
605
func newPersistenceResource(c *gc.C, serviceID, name string) (storedResource, resourceDoc) {
480
607
opened := resourcetesting.NewResource(c, nil, name, serviceID, content)