func (s *ManifoldSuite) TestManifoldEx(c *gc.C) { lock := gate.NewLock() manifold := gate.ManifoldEx(lock) var waiter1 gate.Waiter = lock var unlocker1 gate.Unlocker = lock worker, err := manifold.Start(nil) c.Assert(err, jc.ErrorIsNil) defer checkStop(c, worker) waiter2 := waiter(c, manifold, worker) assertLocked(c, waiter1) assertLocked(c, waiter2) unlocker1.Unlock() assertUnlocked(c, waiter1) assertUnlocked(c, waiter2) }
func assertGate(c *gc.C, manifold dependency.Manifold, unlocker gate.Unlocker) { w, err := manifold.Start(nil) c.Assert(err, jc.ErrorIsNil) defer worker.Stop(w) var waiter gate.Waiter err = manifold.Output(w, &waiter) c.Assert(err, jc.ErrorIsNil) select { case <-waiter.Unlocked(): c.Fatalf("expected gate to be locked") default: } unlocker.Unlock() select { case <-waiter.Unlocked(): default: c.Fatalf("expected gate to be unlocked") } }
// startFunc returns a StartFunc that creates a worker based on the manifolds // named in the supplied config. func startFunc(config ManifoldConfig) dependency.StartFunc { return func(getResource dependency.GetResourceFunc) (worker.Worker, error) { // Get dependencies and open a connection. var gate gate.Unlocker if err := getResource(config.APIInfoGateName, &gate); err != nil { return nil, err } var a agent.Agent if err := getResource(config.AgentName, &a); err != nil { return nil, err } conn, err := openConnection(a) if err != nil { return nil, errors.Annotate(err, "cannot open api") } // Add the environment uuid to agent config if not present. currentConfig := a.CurrentConfig() if currentConfig.Environment().Id() == "" { err := a.ChangeConfig(func(setter agent.ConfigSetter) error { environTag, err := conn.EnvironTag() if err != nil { return errors.Annotate(err, "no environment uuid set on api") } return setter.Migrate(agent.MigrateParams{ Environment: environTag, }) }) if err != nil { logger.Warningf("unable to save environment uuid: %v", err) // Not really fatal, just annoying. } } // Now we know the agent config has been fixed up, notify everyone // else who might depend upon its stability/correctness. gate.Unlock() // Return the worker. return newApiConnWorker(conn) } }