// assertCharmOps returns txn.Ops to assert the current charm of the unit.
// If the unit currently has no charm URL set, then the application's charm
// URL will be checked by the txn.Ops also.
765800
func (u *Unit) assertCharmOps(ch *Charm) []txn.Op {
	ops := []txn.Op{{
		C:      unitsC,
		Id:     u.doc.Name,
		Assert: bson.D{{"charmurl", u.doc.CharmURL}},
	}}
	if _, ok := u.CharmURL(); !ok {
		appName := u.ApplicationName()
		ops = append(ops, txn.Op{
			C:      applicationsC,
			Id:     appName,
			Assert: bson.D{{"charmurl", ch.URL()}},
		})
	}
	return ops
}
358950
func SerialCtxDeps(ctx context.Context, fns ...interface{}) {
	types := checkFns(fns)
	for i := range fns {
		runDeps(ctx, types[i:i+1], fns[i:i+1])
	}
}
1009219
func insertAnnotationsOps(st *State, entity GlobalEntity, toInsert map[string]string) ([]txn.Op, error) {
	tag := entity.Tag()
	ops := []txn.Op{{
		C:      annotationsC,
		Id:     st.docID(entity.globalKey()),
		Assert: txn.DocMissing,
		Insert: &annotatorDoc{
			GlobalKey:   entity.globalKey(),
			Tag:         tag.String(),
			Annotations: toInsert,
		},
	}}

	switch tag := tag.(type) {
	case names.ModelTag:
		if tag.Id() == st.ControllerModelUUID() {
			// This is the controller model, and cannot be removed.
			// Ergo, we can skip the existence check below.
			return ops, nil
		}
	}

	// If the entity is not the controller model, add a DocExists check on the
	// entity document, in order to avoid possible races between entity
	// removal and annotation creation.
	coll, id, err := st.tagToCollectionAndId(tag)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return append(ops, txn.Op{
		C:      coll,
		Id:     id,
		Assert: txn.DocExists,
	}), nil
}
967111
func (st *State) suspendRevokedRelationsOps(offerUUID, userId string) ([]txn.Op, error) {
	conns, err := st.OfferConnections(offerUUID)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var ops []txn.Op
	relIdsToSuspend := make(set.Ints)
	for _, oc := range conns {
		if oc.UserName() == userId {
			rel, err := st.Relation(oc.RelationId())
			if err != nil {
				return nil, errors.Trace(err)
			}
			if rel.Suspended() {
				continue
			}
			relIdsToSuspend.Add(rel.Id())
			suspendOp := txn.Op{
				C:      relationsC,
				Id:     rel.doc.DocID,
				Assert: txn.DocExists,
				Update: bson.D{{"$set", bson.D{{"suspended", true}}}},
			}
			ops = append(ops, suspendOp)
		}
	}

	// Add asserts that the relations against the offered application don't change.
	// This is broader than what we need but it's all that's possible.
	ao := NewApplicationOffers(st)
	offer, err := ao.ApplicationOfferForUUID(offerUUID)
	if err != nil {
		return nil, errors.Trace(err)
	}
	app, err := st.Application(offer.ApplicationName)
	if err != nil {
		return nil, errors.Trace(err)
	}
	relations, err := app.Relations()
	if err != nil {
		return nil, errors.Trace(err)
	}
	sameRelCount := bson.D{{"relationcount", len(relations)}}
	ops = append(ops, txn.Op{
		C:      applicationsC,
		Id:     app.doc.DocID,
		Assert: sameRelCount,
	})
	// Ensure any relations not being updated still exist.
	for _, r := range relations {
		if relIdsToSuspend.Contains(r.Id()) {
			continue
		}
		ops = append(ops, txn.Op{
			C:      relationsC,
			Id:     r.doc.DocID,
			Assert: txn.DocExists,
		})
	}

	return ops, nil
}
1028054
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
	if h, ok := a.t.(tHelper); ok {
		h.Helper()
	}
	return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
}
497621
func (rc *rawConn) checkOperation(projectID string, op *compute.Operation) (*compute.Operation, error) {
	var call opDoer
	if op.Zone != "" {
		zoneName := path.Base(op.Zone)
		call = rc.ZoneOperations.Get(projectID, zoneName, op.Name)
	} else if op.Region != "" {
		region := path.Base(op.Region)
		call = rc.RegionOperations.Get(projectID, region, op.Name)
	} else {
		call = rc.GlobalOperations.Get(projectID, op.Name)
	}

	operation, err := doOpCall(call)
	if err != nil {
		return nil, errors.Annotatef(err, "request for GCE operation %q failed", op.Name)
	}
	return operation, nil
}
463267
func (api *APIBase) CharmConfig(args params.ApplicationGetArgs) (params.ApplicationGetConfigResults, error) {
	if err := api.checkCanRead(); err != nil {
		return params.ApplicationGetConfigResults{}, err
	}
	results := params.ApplicationGetConfigResults{
		Results: make([]params.ConfigResult, len(args.Args)),
	}
	for i, arg := range args.Args {
		config, err := api.getCharmConfig(arg.BranchName, arg.ApplicationName)
		results.Results[i].Config = config
		results.Results[i].Error = common.ServerError(err)
	}
	return results, nil
}
34657
func (f *Facade) Charm(args params.Entities) (params.ApplicationCharmResults, error) {
	results := params.ApplicationCharmResults{
		Results: make([]params.ApplicationCharmResult, len(args.Entities)),
	}
	authTag := f.auth.GetAuthTag()
	for i, entity := range args.Entities {
		tag, err := names.ParseApplicationTag(entity.Tag)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		if tag != authTag {
			results.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		application, err := f.state.Application(tag.Id())
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		charm, force, err := application.Charm()
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		results.Results[i].Result = &params.ApplicationCharm{
			URL:                  charm.URL().String(),
			ForceUpgrade:         force,
			SHA256:               charm.BundleSha256(),
			CharmModifiedVersion: application.CharmModifiedVersion(),
		}
	}
	return results, nil
}
189414
func deleteOldPlaceholderCharmsOps(mb modelBackend, charms mongo.Collection, curl *charm.URL) ([]txn.Op, error) {
	// Get a regex with the charm URL and no revision.
	noRevURL := curl.WithRevision(-1)
	curlRegex := "^" + regexp.QuoteMeta(mb.docID(noRevURL.String()))

	var docs []charmDoc
	query := bson.D{{"_id", bson.D{{"$regex", curlRegex}}}, {"placeholder", true}}
	err := charms.Find(query).Select(bson.D{{"_id", 1}, {"url", 1}}).All(&docs)
	if err != nil {
		return nil, errors.Trace(err)
	}

	refcounts, closer := mb.db().GetCollection(refcountsC)
	defer closer()

	var ops []txn.Op
	for _, doc := range docs {
		if doc.URL.Revision >= curl.Revision {
			continue
		}
		key := charmGlobalKey(doc.URL)
		refOp, err := nsRefcounts.RemoveOp(refcounts, key, 0)
		if err != nil {
			return nil, errors.Trace(err)
		}
		ops = append(ops, refOp, txn.Op{
			C:      charms.Name(),
			Id:     doc.DocID,
			Assert: stillPlaceholder,
			Remove: true,
		})
	}
	return ops, nil
}
874480
func (m *MockProfileBackend) Charm(arg0 *charm_v6.URL) (provisioner.ProfileCharm, error) {
	ret := m.ctrl.Call(m, "Charm", arg0)
	ret0, _ := ret[0].(provisioner.ProfileCharm)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}
889386
func (api *APIv8) CharmConfig(args params.Entities) (params.ApplicationGetConfigResults, error) {
	return api.GetConfig(args)
}
29729
func (store *store) assertOpTrapdoor(name, holder string) lease.Trapdoor {
	op := txn.Op{
		C:  store.config.Collection,
		Id: store.leaseDocId(name),
		Assert: bson.M{
			fieldHolder: holder,
		},
	}
	return func(_ int, out interface{}) error {
		outPtr, ok := out.(*[]txn.Op)
		if !ok {
			return errors.NotValidf("expected *[]txn.Op; %T", out)
		}
		*outPtr = []txn.Op{op}
		return nil
	}
}
529123
func updateCharmDir(opState operation.State, guard fortress.Guard, abort fortress.Abort) error {
	var changing bool

	// Determine if the charm content is changing.
	if opState.Kind == operation.Install || opState.Kind == operation.Upgrade {
		changing = true
	} else if opState.Kind == operation.RunHook && opState.Hook != nil && opState.Hook.Kind == hooks.UpgradeCharm {
		changing = true
	}

	available := opState.Started && !opState.Stopped && !changing
	logger.Tracef("charmdir: available=%v opState: started=%v stopped=%v changing=%v",
		available, opState.Started, opState.Stopped, changing)
	if available {
		return guard.Unlock()
	} else {
		return guard.Lockdown(abort)
	}
}
372253
func charmDestroyOps(st modelBackend, curl *charm.URL) ([]txn.Op, error) {
	db := st.db()
	charms, closer := db.GetCollection(charmsC)
	defer closer()

	charmKey := curl.String()
	charmOp, err := nsLife.destroyOp(charms, charmKey, nil)
	if err != nil {
		return nil, errors.Annotate(err, "charm")
	}

	refcounts, closer := db.GetCollection(refcountsC)
	defer closer()

	refcountKey := charmGlobalKey(curl)
	refcountOp, err := nsRefcounts.RemoveOp(refcounts, refcountKey, 0)
	switch errors.Cause(err) {
	case nil:
	case errRefcountChanged:
		return nil, errCharmInUse
	default:
		return nil, errors.Annotate(err, "charm reference")
	}

	return []txn.Op{charmOp, refcountOp}, nil
}
153326
func (m *Mock) AssertExpectations(t testingT) bool {
	var somethingMissing bool
	var failedExpectations int

	// iterate through each expectation
	expectedQueries := m.expectedQueries()
	for _, expectedQuery := range expectedQueries {
		if !m.queryWasExecuted(expectedQuery) && expectedQuery.executed == 0 {
			somethingMissing = true
			failedExpectations++
			t.Logf("❌\t%s", expectedQuery.Query.Term.String())
		} else {
			m.mu.Lock()
			if expectedQuery.Repeatability > 0 {
				somethingMissing = true
				failedExpectations++
			} else {
				t.Logf("✅\t%s", expectedQuery.Query.Term.String())
			}
			m.mu.Unlock()
		}
	}

	if somethingMissing {
		t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe query you are testing needs to be executed %d more times(s).", len(expectedQueries)-failedExpectations, len(expectedQueries), failedExpectations)
	}

	return !somethingMissing
}
393445
func (p ResourcePersistence) SetCharmStoreResource(id, applicationID string, res charmresource.Resource, lastPolled time.Time) error {
	if err := res.Validate(); err != nil {
		return errors.Annotate(err, "bad resource")
	}

	csRes := charmStoreResource{
		Resource:      res,
		id:            id,
		applicationID: applicationID,
		lastPolled:    lastPolled,
	}

	buildTxn := func(attempt int) ([]txn.Op, error) {
		// This is an "upsert".
		var ops []txn.Op
		switch attempt {
		case 0:
			ops = newInsertCharmStoreResourceOps(csRes)
		case 1:
			ops = newUpdateCharmStoreResourceOps(csRes)
		default:
			// Either insert or update will work so we should not get here.
			return nil, errors.New("setting the resource failed")
		}
		// No pending resources so we always do this here.
		ops = append(ops, p.base.ApplicationExistsOps(applicationID)...)
		return ops, nil
	}
	if err := p.base.Run(buildTxn); err != nil {
		return errors.Trace(err)
	}
	return nil
}
341619
func (a *Application) incUnitCountOp(asserts bson.D) txn.Op {
	op := txn.Op{
		C:      applicationsC,
		Id:     a.doc.DocID,
		Update: bson.D{{"$inc", bson.D{{"unitcount", 1}}}},
	}
	if len(asserts) > 0 {
		op.Assert = asserts
	}
	return op
}