func (s *ManifoldsSuite) TestManifoldNames(c *gc.C) { config := unit.ManifoldsConfig{} manifolds := unit.Manifolds(config) expectedKeys := []string{ "agent", "api-config-watcher", "api-caller", "log-sender", "upgrader", "migration-fortress", "migration-minion", "migration-inactive-flag", "logging-config-updater", "proxy-config-updater", "api-address-updater", "charm-dir", "leadership-tracker", "hook-retry-strategy", "uniter", "metric-spool", "meter-status", "metric-collect", "metric-sender", } keys := make([]string, 0, len(manifolds)) for k := range manifolds { keys = append(keys, k) } c.Assert(expectedKeys, jc.SameContents, keys) }
// APIWorkers returns a dependency.Engine running the unit agent's responsibilities. func (a *UnitAgent) APIWorkers() (worker.Worker, error) { manifolds := unit.Manifolds(unit.ManifoldsConfig{ Agent: agent.APIHostPortsSetter{a}, LogSource: a.bufferedLogs, LeadershipGuarantee: 30 * time.Second, AgentConfigChanged: a.configChangedVal, }) config := dependency.EngineConfig{ IsFatal: cmdutil.IsFatal, WorstError: cmdutil.MoreImportantError, ErrorDelay: 3 * time.Second, BounceDelay: 10 * time.Millisecond, } engine, err := dependency.NewEngine(config) if err != nil { return nil, err } if err := dependency.Install(engine, manifolds); err != nil { if err := worker.Stop(engine); err != nil { logger.Errorf("while stopping engine with bad manifolds: %v", err) } return nil, err } return engine, nil }
func (s *ManifoldsSuite) TestManifoldNames(c *gc.C) { config := unit.ManifoldsConfig{ Agent: nil, LogSource: nil, LeadershipGuarantee: 0, } manifolds := unit.Manifolds(config) expectedKeys := []string{ unit.AgentName, unit.APIAdddressUpdaterName, unit.APICallerName, unit.APIInfoGateName, unit.LeadershipTrackerName, unit.LoggingConfigUpdaterName, unit.LogSenderName, unit.MachineLockName, unit.ProxyConfigUpdaterName, unit.RsyslogConfigUpdaterName, unit.UniterName, unit.UpgraderName, unit.MetricSpoolName, unit.MetricCollectName, unit.MeterStatusName, unit.MetricSenderName, unit.CharmDirName, } keys := make([]string, 0, len(manifolds)) for k := range manifolds { keys = append(keys, k) } c.Assert(expectedKeys, jc.SameContents, keys) }
// TODO(cmars) 2015/08/10: rework this into builtin Engine cycle checker. func (s *ManifoldsSuite) TestAcyclic(c *gc.C) { manifolds := unit.Manifolds(unit.ManifoldsConfig{ Agent: fakeAgent{}, }) err := dependency.Validate(manifolds) c.Assert(err, jc.ErrorIsNil) }
func (s *ManifoldsSuite) TestStartFuncs(c *gc.C) { manifolds := unit.Manifolds(unit.ManifoldsConfig{ Agent: fakeAgent{}, }) for name, manifold := range manifolds { c.Logf("checking %q manifold", name) c.Check(manifold.Start, gc.NotNil) } }
// TODO(cmars) 2015/08/10: rework this into builtin Engine cycle checker. func (s *ManifoldsSuite) TestAcyclic(c *gc.C) { manifolds := unit.Manifolds(unit.ManifoldsConfig{ Agent: fakeAgent{}, }) count := len(manifolds) // Set of vars for depth-first topological sort of manifolds. (Note that, // because we've already got outgoing links stored conveniently, we're // actually checking the transpose of the dependency graph. Cycles will // still be cycles in either direction, though.) done := make(map[string]bool) doing := make(map[string]bool) sorted := make([]string, 0, count) // Stupid _-suffix malarkey allows recursion. Seems cleaner to keep these // considerations inside this func than to embody the algorithm in a type. visit := func(node string) {} visit_ := func(node string) { if doing[node] { c.Fatalf("cycle detected at %q (considering: %v)", node, doing) } if !done[node] { doing[node] = true for _, input := range manifolds[node].Inputs { visit(input) } done[node] = true doing[node] = false sorted = append(sorted, node) } } visit = visit_ // Actually sort them, or fail if we find a cycle. for node := range manifolds { visit(node) } c.Logf("got: %v", sorted) c.Check(sorted, gc.HasLen, count) // Final sanity check. }
func (*ManifoldsSuite) TestMigrationGuards(c *gc.C) { exempt := set.NewStrings( "agent", "machine-lock", "api-config-watcher", "api-caller", "log-sender", "upgrader", "migration-fortress", "migration-minion", "migration-inactive-flag", ) config := unit.ManifoldsConfig{} manifolds := unit.Manifolds(config) for name, manifold := range manifolds { c.Logf(name) if !exempt.Contains(name) { checkContains(c, manifold.Inputs, "migration-inactive-flag") checkContains(c, manifold.Inputs, "migration-fortress") } } }