func (s *ImportSuite) TestStreamCharmsTools(c *gc.C) {
	model := description.NewModel(description.ModelArgs{
		Owner: names.NewUserTag("me"),
	})
	model.AddService(description.ServiceArgs{
		Tag:      names.NewServiceTag("magic"),
		CharmURL: "local:trusty/magic",
	})
	model.AddService(description.ServiceArgs{
		Tag:      names.NewServiceTag("magic"),
		CharmURL: "cs:trusty/postgresql-42",
	})

	uploader := &fakeUploader{charms: make(map[string]string)}
	config := migration.UploadBinariesConfig{
		State:            &fakeStateStorage{},
		Model:            model,
		Target:           &fakeAPIConnection{},
		GetCharmUploader: func(api.Connection) migration.CharmUploader { return uploader },
		GetToolsUploader: func(target api.Connection) migration.ToolsUploader { return &noOpUploader{} },
		GetStateStorage:  func(migration.UploadBackend) storage.Storage { return &fakeCharmsStorage{} },
		GetCharmStoragePath: func(_ migration.UploadBackend, u *charm.URL) (string, error) {
			return "/path/for/" + u.String(), nil
		},
	}
	err := migration.UploadBinaries(config)
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(uploader.charms, jc.DeepEquals, map[string]string{
		"local:trusty/magic":      "fake file at /path/for/local:trusty/magic",
		"cs:trusty/postgresql-42": "fake file at /path/for/cs:trusty/postgresql-42",
	})
}
Exemple #2
0
// Rescale requests that all supplied service names be rescaled to
// their minimum configured sizes. It returns the first error it
// encounters.
func (api *API) Rescale(services []string) error {
	args := params.Entities{
		Entities: make([]params.Entity, len(services)),
	}
	for i, service := range services {
		if !names.IsValidService(service) {
			return errors.NotValidf("service name %q", service)
		}
		tag := names.NewServiceTag(service)
		args.Entities[i].Tag = tag.String()
	}
	var results params.ErrorResults
	err := api.caller.FacadeCall("Rescale", args, &results)
	if err != nil {
		return errors.Trace(err)
	}
	for _, result := range results.Results {
		if result.Error != nil {
			if err == nil {
				err = result.Error
			} else {
				logger.Errorf("additional rescale error: %v", err)
			}
		}
	}
	return errors.Trace(err)
}
Exemple #3
0
func (s *settingsSuite) TestWriteSettings(c *gc.C) {

	numWriteSettingCalls := 0
	writeSettings := func(serviceId string, settings map[string]string) error {
		numWriteSettingCalls++
		c.Check(serviceId, gc.Equals, StubServiceNm)
		return nil
	}

	numIsLeaderCalls := 0
	isLeader := func(serviceId, unitId string) (bool, error) {
		numIsLeaderCalls++
		c.Check(serviceId, gc.Equals, StubServiceNm)
		c.Check(unitId, gc.Equals, StubUnitNm)
		return true, nil
	}

	accessor := NewLeadershipSettingsAccessor(&stubAuthorizer{}, nil, nil, writeSettings, isLeader)

	results, err := accessor.Merge(params.MergeLeadershipSettingsBulkParams{
		[]params.MergeLeadershipSettingsParam{
			{
				ServiceTag: names.NewServiceTag(StubServiceNm).String(),
				Settings:   map[string]string{"baz": "biz"},
			},
		},
	})
	c.Assert(err, gc.IsNil)
	c.Assert(results.Results, gc.HasLen, 1)
	c.Check(results.Results[0].Error, gc.IsNil)
	c.Check(numWriteSettingCalls, gc.Equals, 1)
	c.Check(numIsLeaderCalls, gc.Equals, 1)
}
Exemple #4
0
func (*FacadeSuite) TestWatchSuccess(c *gc.C) {
	caller := apiCaller(c, func(_ string, _, results interface{}) error {
		typed, ok := results.(*params.NotifyWatchResults)
		c.Assert(ok, jc.IsTrue)
		*typed = params.NotifyWatchResults{
			Results: []params.NotifyWatchResult{{
				NotifyWatcherId: "123",
			}},
		}
		return nil
	})
	expectWatcher := &struct{ watcher.NotifyWatcher }{}
	newWatcher := func(apiCaller base.APICaller, result params.NotifyWatchResult) watcher.NotifyWatcher {
		c.Check(apiCaller, gc.NotNil) // uncomparable
		c.Check(result, jc.DeepEquals, params.NotifyWatchResult{
			NotifyWatcherId: "123",
		})
		return expectWatcher
	}
	facade := lifeflag.NewFacade(caller, newWatcher)

	watcher, err := facade.Watch(names.NewServiceTag("blah"))
	c.Check(err, jc.ErrorIsNil)
	c.Check(watcher, gc.Equals, expectWatcher)
}
Exemple #5
0
func (*ScaryConnectSuite) TestEntityUnknownLife(c *gc.C) {
	// "random" failure case
	stub := &testing.Stub{}
	expectConn := &mockConn{stub: stub}
	apiOpen := func(info *api.Info, opts api.DialOpts) (api.Connection, error) {
		return expectConn, nil
	}

	entity := names.NewServiceTag("omg")
	connect := func() (api.Connection, error) {
		return apicaller.ScaryConnect(&mockAgent{
			stub:   stub,
			model:  coretesting.ModelTag,
			entity: entity,
		}, apiOpen)
	}

	conn, err := lifeTest(c, stub, apiagent.Life("zombie"), connect)
	c.Check(conn, gc.IsNil)
	c.Check(err, gc.ErrorMatches, `unknown life value "zombie"`)
	stub.CheckCalls(c, []testing.StubCall{{
		FuncName: "Life",
		Args:     []interface{}{entity},
	}, {
		FuncName: "Close",
	}})
}
Exemple #6
0
func (s *leadershipSuite) TestClaimLeadershipTranslation(c *gc.C) {
	var ldrMgr stubLeadershipManager
	ldrMgr.ClaimLeadershipFn = func(sid, uid string, duration time.Duration) error {
		c.Check(sid, gc.Equals, StubServiceNm)
		c.Check(uid, gc.Equals, StubUnitNm)
		expectDuration := time.Duration(299.9 * float64(time.Second))
		checkDurationEquals(c, duration, expectDuration)
		return nil
	}

	ldrSvc := &leadershipService{LeadershipManager: &ldrMgr, authorizer: &stubAuthorizer{}}
	results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
		Params: []params.ClaimLeadershipParams{
			{
				ServiceTag:      names.NewServiceTag(StubServiceNm).String(),
				UnitTag:         names.NewUnitTag(StubUnitNm).String(),
				DurationSeconds: 299.9,
			},
		},
	})

	c.Check(err, jc.ErrorIsNil)
	c.Assert(results.Results, gc.HasLen, 1)
	c.Check(results.Results[0].Error, gc.IsNil)
}
Exemple #7
0
// prepareClaimLeadership creates a single set of params in
// preperation for making a bulk call.
func (c *client) prepareClaimLeadership(serviceId, unitId string, duration time.Duration) params.ClaimLeadershipParams {
	return params.ClaimLeadershipParams{
		names.NewServiceTag(serviceId).String(),
		names.NewUnitTag(unitId).String(),
		duration.Seconds(),
	}
}
Exemple #8
0
func testEntityFine(c *gc.C, life apiagent.Life) {
	stub := &testing.Stub{}
	expectConn := &mockConn{stub: stub}
	apiOpen := func(info *api.Info, opts api.DialOpts) (api.Connection, error) {
		// no apiOpen stub calls necessary in this suite; covered
		// by RetrySuite, just an extra complication here.
		return expectConn, nil
	}

	// to make the point that this code should be entity-agnostic,
	// use an entity that doesn't correspond to an agent at all.
	entity := names.NewServiceTag("omg")
	connect := func() (api.Connection, error) {
		return apicaller.ScaryConnect(&mockAgent{
			stub:   stub,
			model:  coretesting.ModelTag,
			entity: entity,
		}, apiOpen)
	}

	conn, err := lifeTest(c, stub, apiagent.Alive, connect)
	c.Check(conn, gc.Equals, expectConn)
	c.Check(err, jc.ErrorIsNil)
	stub.CheckCalls(c, []testing.StubCall{{
		FuncName: "Life",
		Args:     []interface{}{entity},
	}, {
		FuncName: "SetPassword",
		Args:     []interface{}{entity, "new"},
	}})
}
Exemple #9
0
// NewAddPendingResourcesArgs returns the arguments for the
// AddPendingResources API endpoint.
func NewAddPendingResourcesArgs(serviceID string, chID charmstore.CharmID, csMac *macaroon.Macaroon, resources []charmresource.Resource) (AddPendingResourcesArgs, error) {
	var args AddPendingResourcesArgs

	if !names.IsValidService(serviceID) {
		return args, errors.Errorf("invalid service %q", serviceID)
	}
	tag := names.NewServiceTag(serviceID).String()

	var apiResources []CharmResource
	for _, res := range resources {
		if err := res.Validate(); err != nil {
			return args, errors.Trace(err)
		}
		apiRes := CharmResource2API(res)
		apiResources = append(apiResources, apiRes)
	}
	args.Tag = tag
	args.Resources = apiResources
	if chID.URL != nil {
		args.URL = chID.URL.String()
		args.Channel = string(chID.Channel)
		args.CharmStoreMacaroon = csMac
	}
	return args, nil
}
Exemple #10
0
func (s *leadershipSuite) TestClaimLeadershipDeniedError(c *gc.C) {
	var ldrMgr stubLeadershipManager
	ldrMgr.ClaimLeadershipFn = func(sid, uid string, duration time.Duration) error {
		c.Check(sid, gc.Equals, StubServiceNm)
		c.Check(uid, gc.Equals, StubUnitNm)
		expectDuration := time.Duration(5.001 * float64(time.Second))
		checkDurationEquals(c, duration, expectDuration)
		return errors.Annotatef(leadership.ErrClaimDenied, "obfuscated")
	}

	ldrSvc := &leadershipService{LeadershipManager: &ldrMgr, authorizer: &stubAuthorizer{}}
	results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
		Params: []params.ClaimLeadershipParams{
			{
				ServiceTag:      names.NewServiceTag(StubServiceNm).String(),
				UnitTag:         names.NewUnitTag(StubUnitNm).String(),
				DurationSeconds: 5.001,
			},
		},
	})

	c.Check(err, jc.ErrorIsNil)
	c.Assert(results.Results, gc.HasLen, 1)
	c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeLeadershipClaimDenied)
}
Exemple #11
0
func checkChangePassword(c *gc.C, errs ...error) (*testing.Stub, error) {
	// We prepend the unauth/success pair that triggers password
	// change, and consume them in apiOpen below...
	errUnauth := &params.Error{Code: params.CodeUnauthorized}
	allErrs := append([]error{errUnauth, nil}, errs...)

	stub := &testing.Stub{}
	stub.SetErrors(allErrs...)
	expectConn := &mockConn{stub: stub}
	apiOpen := func(info *api.Info, opts api.DialOpts) (api.Connection, error) {
		// ...but we *don't* record the calls themselves; they
		// are tested plenty elsewhere, and hiding them makes
		// client code simpler.
		if err := stub.NextErr(); err != nil {
			return nil, err
		}
		return expectConn, nil
	}

	entity := names.NewServiceTag("omg")
	connect := func() (api.Connection, error) {
		return apicaller.ScaryConnect(&mockAgent{
			stub:   stub,
			model:  coretesting.ModelTag,
			entity: entity,
		}, apiOpen)
	}

	conn, err := lifeTest(c, stub, apiagent.Alive, connect)
	c.Check(conn, gc.IsNil)
	return stub, err
}
Exemple #12
0
func (*ScaryConnectSuite) TestEntityDenied(c *gc.C) {
	// permanent failure case
	stub := &testing.Stub{}
	stub.SetErrors(apiagent.ErrDenied)
	expectConn := &mockConn{stub: stub}
	apiOpen := func(info *api.Info, opts api.DialOpts) (api.Connection, error) {
		return expectConn, nil
	}

	entity := names.NewServiceTag("omg")
	connect := func() (api.Connection, error) {
		return apicaller.ScaryConnect(&mockAgent{
			stub:   stub,
			model:  coretesting.ModelTag,
			entity: entity,
		}, apiOpen)
	}

	conn, err := lifeTest(c, stub, apiagent.Dead, connect)
	c.Check(conn, gc.IsNil)
	c.Check(err, gc.Equals, apicaller.ErrConnectImpossible)
	stub.CheckCalls(c, []testing.StubCall{{
		FuncName: "Life",
		Args:     []interface{}{entity},
	}, {
		FuncName: "Close",
	}})
}
Exemple #13
0
func (s *agentAuthenticatorSuite) TestNotSupportedTag(c *gc.C) {
	srv := newServer(c, s.State)
	defer srv.Stop()
	authenticator, err := apiserver.ServerAuthenticatorForTag(srv, names.NewServiceTag("not-support"))
	c.Assert(err, gc.ErrorMatches, "unexpected login entity tag: invalid request")
	c.Assert(authenticator, gc.IsNil)
}
Exemple #14
0
func (s *DefinedSuite) TestInit(c *gc.C) {
	tests := []struct {
		should               string
		args                 []string
		expectedSvc          names.ServiceTag
		expectedOutputSchema bool
		expectedErr          string
	}{{
		should:      "fail with missing service name",
		args:        []string{},
		expectedErr: "no service name specified",
	}, {
		should:      "fail with invalid service name",
		args:        []string{invalidServiceId},
		expectedErr: "invalid service name \"" + invalidServiceId + "\"",
	}, {
		should:      "fail with too many args",
		args:        []string{"two", "things"},
		expectedErr: "unrecognized args: \\[\"things\"\\]",
	}, {
		should:      "init properly with valid service name",
		args:        []string{validServiceId},
		expectedSvc: names.NewServiceTag(validServiceId),
	}, {
		should:               "init properly with valid service name and --schema",
		args:                 []string{"--schema", validServiceId},
		expectedOutputSchema: true,
		expectedSvc:          names.NewServiceTag(validServiceId),
	}}

	for i, t := range tests {
		for _, modelFlag := range s.modelFlags {
			c.Logf("test %d should %s: juju actions defined %s", i,
				t.should, strings.Join(t.args, " "))
			s.wrappedCommand, s.command = action.NewDefinedCommand(s.store)
			args := append([]string{modelFlag, "admin"}, t.args...)
			err := testing.InitCommand(s.wrappedCommand, args)
			if t.expectedErr == "" {
				c.Check(s.command.ServiceTag(), gc.Equals, t.expectedSvc)
				c.Check(s.command.FullSchema(), gc.Equals, t.expectedOutputSchema)
			} else {
				c.Check(err, gc.ErrorMatches, t.expectedErr)
			}
		}
	}
}
Exemple #15
0
func (s *rsyslogSuite) TestUpgraderAPIRefusesNonUnitNonMachineAgent(c *gc.C) {
	anAuthorizer := s.authorizer
	anAuthorizer.Tag = names.NewServiceTag("hadoop")
	anUpgrader, err := rsyslog.NewRsyslogAPI(s.State, s.resources, anAuthorizer)
	c.Check(err, gc.NotNil)
	c.Check(anUpgrader, gc.IsNil)
	c.Assert(err, gc.ErrorMatches, "permission denied")
}
Exemple #16
0
func (s *volumeSuite) TestCreateVolumeItemNoUnit(c *gc.C) {
	s.storageInstance.owner = names.NewServiceTag("test-service")
	found := storage.CreateVolumeItem(s.api, s.volumeTag.String(), nil)
	c.Assert(found.Error, gc.IsNil)
	c.Assert(found.Error, gc.IsNil)
	expected, err := storage.ConvertStateVolumeToParams(s.api, s.volume)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(found.Volume, gc.DeepEquals, expected)
}
Exemple #17
0
func (s *commonSuite) TestAuthFuncForTagKind(c *gc.C) {
	// TODO(dimitern): This list of all supported tags and kinds needs
	// to live in juju/names.
	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)

	allTags := []names.Tag{
		nil, // invalid tag
		names.NewActionTag(uuid.String()),
		names.NewCharmTag("cs:precise/missing"),
		names.NewModelTag(uuid.String()),
		names.NewFilesystemTag("20/20"),
		names.NewLocalUserTag("user"),
		names.NewMachineTag("42"),
		names.NewNetworkTag("public"),
		names.NewRelationTag("wordpress:mysql mysql:db"),
		names.NewServiceTag("wordpress"),
		names.NewSpaceTag("apps"),
		names.NewStorageTag("foo/42"),
		names.NewUnitTag("wordpress/5"),
		names.NewUserTag("joe"),
		names.NewVolumeTag("80/20"),
	}
	for i, allowedTag := range allTags {
		c.Logf("test #%d: allowedTag: %v", i, allowedTag)

		var allowedKind string
		if allowedTag != nil {
			allowedKind = allowedTag.Kind()
		}
		getAuthFunc := common.AuthFuncForTagKind(allowedKind)

		authFunc, err := getAuthFunc()
		if allowedKind == "" {
			c.Check(err, gc.ErrorMatches, "tag kind cannot be empty")
			c.Check(authFunc, gc.IsNil)
			continue
		} else if !c.Check(err, jc.ErrorIsNil) {
			continue
		}

		for j, givenTag := range allTags {
			c.Logf("test #%d.%d: givenTag: %v", i, j, givenTag)

			var givenKind string
			if givenTag != nil {
				givenKind = givenTag.Kind()
			}
			if allowedKind == givenKind {
				c.Check(authFunc(givenTag), jc.IsTrue)
			} else {
				c.Check(authFunc(givenTag), jc.IsFalse)
			}
		}
	}
}
Exemple #18
0
func (*FacadeSuite) TestWatchNoResultsError(c *gc.C) {
	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
		return nil
	})
	facade := lifeflag.NewFacade(caller, nil)

	watcher, err := facade.Watch(names.NewServiceTag("blah"))
	c.Check(err, gc.ErrorMatches, "expected 1 Watch result, got 0")
	c.Check(watcher, gc.IsNil)
}
Exemple #19
0
func (*FacadeSuite) TestLifeNoResultsError(c *gc.C) {
	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
		return nil
	})
	facade := lifeflag.NewFacade(caller, nil)

	result, err := facade.Life(names.NewServiceTag("blah"))
	c.Check(err, gc.ErrorMatches, "expected 1 Life result, got 0")
	c.Check(result, gc.Equals, life.Value(""))
}
Exemple #20
0
func (*FacadeSuite) TestLifeCallError(c *gc.C) {
	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
		return errors.New("crunch belch")
	})
	facade := lifeflag.NewFacade(caller, nil)

	result, err := facade.Life(names.NewServiceTag("blah"))
	c.Check(err, gc.ErrorMatches, "crunch belch")
	c.Check(result, gc.Equals, life.Value(""))
}
Exemple #21
0
func (*FacadeSuite) TestWatchCallError(c *gc.C) {
	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
		return errors.New("crunch belch")
	})
	facade := lifeflag.NewFacade(caller, nil)

	watcher, err := facade.Watch(names.NewServiceTag("blah"))
	c.Check(err, gc.ErrorMatches, "crunch belch")
	c.Check(watcher, gc.IsNil)
}
Exemple #22
0
// BlockUntilLeadershipReleased is part of the leadership.Claimer interface.
func (c *client) BlockUntilLeadershipReleased(serviceId string) error {
	const friendlyErrMsg = "error blocking on leadership release"
	var result params.ErrorResult
	err := c.FacadeCall("BlockUntilLeadershipReleased", names.NewServiceTag(serviceId), &result)
	if err != nil {
		return errors.Annotate(err, friendlyErrMsg)
	} else if result.Error != nil {
		return errors.Annotate(result.Error, friendlyErrMsg)
	}
	return nil
}
Exemple #23
0
func (s *leadershipSuite) TestBlockUntilLeadershipReleasedErrors(c *gc.C) {
	authorizer := &stubAuthorizer{
		AuthUnitAgentFn: func() bool { return false },
	}

	ldrSvc := &leadershipService{LeadershipManager: nil, authorizer: authorizer}
	result, err := ldrSvc.BlockUntilLeadershipReleased(names.NewServiceTag(StubServiceNm))

	// Overall function call should succeed, but operations should
	// fail with a permissions issue.
	c.Check(err, jc.ErrorIsNil)
	c.Check(result.Error, jc.Satisfies, params.IsCodeUnauthorized)
}
Exemple #24
0
func (s *ImportSuite) TestUploadBinariesTools(c *gc.C) {
	// Create a model that has three different tools versions:
	// one for a machine, one for a container, and one for a unit agent.
	// We don't care about the actual validity of the model (it isn't).
	model := description.NewModel(description.ModelArgs{
		Owner: names.NewUserTag("me"),
	})
	machine := model.AddMachine(description.MachineArgs{
		Id: names.NewMachineTag("0"),
	})
	machine.SetTools(description.AgentToolsArgs{
		Version: version.MustParseBinary("2.0.1-trusty-amd64"),
	})
	container := machine.AddContainer(description.MachineArgs{
		Id: names.NewMachineTag("0/lxc/0"),
	})
	container.SetTools(description.AgentToolsArgs{
		Version: version.MustParseBinary("2.0.5-trusty-amd64"),
	})
	service := model.AddService(description.ServiceArgs{
		Tag:      names.NewServiceTag("magic"),
		CharmURL: "local:trusty/magic",
	})
	unit := service.AddUnit(description.UnitArgs{
		Tag: names.NewUnitTag("magic/0"),
	})
	unit.SetTools(description.AgentToolsArgs{
		Version: version.MustParseBinary("2.0.3-trusty-amd64"),
	})

	uploader := &fakeUploader{tools: make(map[version.Binary]string)}
	config := migration.UploadBinariesConfig{
		State:            &fakeStateStorage{},
		Model:            model,
		Target:           &fakeAPIConnection{},
		GetCharmUploader: func(api.Connection) migration.CharmUploader { return &noOpUploader{} },
		GetToolsUploader: func(target api.Connection) migration.ToolsUploader {
			return uploader
		},
		GetStateStorage:     func(migration.UploadBackend) storage.Storage { return &fakeCharmsStorage{} },
		GetCharmStoragePath: func(migration.UploadBackend, *charm.URL) (string, error) { return "", nil },
	}
	err := migration.UploadBinaries(config)
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(uploader.tools, jc.DeepEquals, map[version.Binary]string{
		version.MustParseBinary("2.0.1-trusty-amd64"): "fake tools 2.0.1-trusty-amd64",
		version.MustParseBinary("2.0.3-trusty-amd64"): "fake tools 2.0.3-trusty-amd64",
		version.MustParseBinary("2.0.5-trusty-amd64"): "fake tools 2.0.5-trusty-amd64",
	})
}
Exemple #25
0
func (s *WatcherSuite) SetUpTest(c *gc.C) {
	s.BaseSuite.SetUpTest(c)
	s.st = mockState{
		unit: mockUnit{
			tag:  names.NewUnitTag("mysql/0"),
			life: params.Alive,
			service: mockService{
				tag:            names.NewServiceTag("mysql"),
				life:           params.Alive,
				curl:           charm.MustParseURL("cs:trusty/mysql"),
				serviceWatcher: mockNotifyWatcher{changes: make(chan struct{}, 1)},
				leaderSettingsWatcher: mockNotifyWatcher{
					changes: make(chan struct{}, 1),
				},
				relationsWatcher: mockStringsWatcher{
					changes: make(chan []string, 1),
				},
			},
			unitWatcher:           mockNotifyWatcher{changes: make(chan struct{}, 1)},
			addressesWatcher:      mockNotifyWatcher{changes: make(chan struct{}, 1)},
			configSettingsWatcher: mockNotifyWatcher{changes: make(chan struct{}, 1)},
			storageWatcher:        mockStringsWatcher{changes: make(chan []string, 1)},
			actionWatcher:         mockStringsWatcher{changes: make(chan []string, 1)},
		},
		relations:                 make(map[names.RelationTag]*mockRelation),
		storageAttachment:         make(map[params.StorageAttachmentId]params.StorageAttachment),
		relationUnitsWatchers:     make(map[names.RelationTag]*mockRelationUnitsWatcher),
		storageAttachmentWatchers: make(map[names.StorageTag]*mockStorageAttachmentWatcher),
	}

	s.leadership = mockLeadershipTracker{
		claimTicket:  mockTicket{make(chan struct{}, 1), true},
		leaderTicket: mockTicket{make(chan struct{}, 1), true},
		minionTicket: mockTicket{make(chan struct{}, 1), true},
	}

	s.clock = testing.NewClock(time.Now())
	statusTicker := func() <-chan time.Time {
		return s.clock.After(statusTickDuration)
	}

	w, err := remotestate.NewWatcher(remotestate.WatcherConfig{
		State:               &s.st,
		LeadershipTracker:   &s.leadership,
		UnitTag:             s.st.unit.tag,
		UpdateStatusChannel: statusTicker,
	})
	c.Assert(err, jc.ErrorIsNil)
	s.watcher = w
}
Exemple #26
0
func (s *leadershipSuite) TestBlockUntilLeadershipReleasedTranslation(c *gc.C) {

	var ldrMgr stubLeadershipManager
	ldrMgr.BlockUntilLeadershipReleasedFn = func(sid string) error {
		c.Check(sid, gc.Equals, StubServiceNm)
		return nil
	}

	ldrSvc := &leadershipService{LeadershipManager: &ldrMgr, authorizer: &stubAuthorizer{}}
	result, err := ldrSvc.BlockUntilLeadershipReleased(names.NewServiceTag(StubServiceNm))

	c.Check(err, jc.ErrorIsNil)
	c.Check(result.Error, gc.IsNil)
}
Exemple #27
0
// Service returns the service.
func (u *Unit) Service() (*Service, error) {
	serviceTag := names.NewServiceTag(u.ServiceName())
	service := &Service{
		st:  u.st,
		tag: serviceTag,
	}
	// Call Refresh() immediately to get the up-to-date
	// life and other needed locally cached fields.
	err := service.Refresh()
	if err != nil {
		return nil, err
	}
	return service, nil
}
Exemple #28
0
func (s *leadershipSuite) TestBlockUntilLeadershipReleasedTranslation(c *gc.C) {
	claimer := &stubClaimer{
		BlockUntilLeadershipReleasedFn: func(sid string) error {
			c.Check(sid, gc.Equals, StubServiceNm)
			return nil
		},
	}

	ldrSvc := newLeadershipService(c, claimer, nil)
	result, err := ldrSvc.BlockUntilLeadershipReleased(names.NewServiceTag(StubServiceNm))

	c.Check(err, jc.ErrorIsNil)
	c.Check(result.Error, gc.IsNil)
}
Exemple #29
0
// MoveServiceUnitSeqToSequence moves information from unitSeq value
// in the services documents and puts it into a new document in the
// sequence collection.
// The move happens in 3 stages:
// Insert: We insert the new sequence documents based on the values
// in the service collection. Any existing documents with the id we ignore
// Update: We update all the sequence documents with the correct UnitSeq.
// this phase overwrites any existing sequence documents that existed and
// were ignored during the install phase
// Unset: The last phase is to remove the unitseq from the service collection.
func MoveServiceUnitSeqToSequence(st *State) error {
	unitSeqDocs := []struct {
		Name    string `bson:"name"`
		UnitSeq int    `bson:"unitseq"`
	}{}
	servicesCollection, closer := st.getCollection(servicesC)
	defer closer()

	err := servicesCollection.Find(nil).All(&unitSeqDocs)
	if err != nil {
		return errors.Trace(err)
	}
	insertOps := make([]txn.Op, len(unitSeqDocs))
	updateOps := make([]txn.Op, len(unitSeqDocs))
	unsetOps := make([]txn.Op, len(unitSeqDocs))
	for i, svc := range unitSeqDocs {
		tag := names.NewServiceTag(svc.Name)
		insertOps[i] = txn.Op{
			C:  sequenceC,
			Id: st.docID(tag.String()),
			Insert: sequenceDoc{
				Name:    tag.String(),
				EnvUUID: st.EnvironUUID(),
				Counter: svc.UnitSeq,
			},
		}
		updateOps[i] = txn.Op{
			C:  sequenceC,
			Id: st.docID(tag.String()),
			Update: bson.M{
				"$set": bson.M{
					"name":     tag.String(),
					"env-uuid": st.EnvironUUID(),
					"counter":  svc.UnitSeq,
				},
			},
		}
		unsetOps[i] = txn.Op{
			C:  servicesC,
			Id: st.docID(svc.Name),
			Update: bson.M{
				"$unset": bson.M{
					"unitseq": 0},
			},
		}
	}
	ops := append(insertOps, updateOps...)
	ops = append(ops, unsetOps...)
	return st.runRawTransaction(ops)
}
Exemple #30
0
func (s *leadershipSuite) TestClaimLeadershipDurationTooLong(c *gc.C) {
	ldrSvc := &leadershipService{authorizer: &stubAuthorizer{}}
	results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
		Params: []params.ClaimLeadershipParams{
			{
				ServiceTag:      names.NewServiceTag(StubServiceNm).String(),
				UnitTag:         names.NewUnitTag(StubUnitNm).String(),
				DurationSeconds: 300.1,
			},
		},
	})
	c.Check(err, jc.ErrorIsNil)
	c.Assert(results.Results, gc.HasLen, 1)
	c.Check(results.Results[0].Error, gc.ErrorMatches, "invalid duration")
}