github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/jujud/agent/unit/manifolds_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package unit_test 5 6 import ( 7 gc "gopkg.in/check.v1" 8 9 "github.com/juju/juju/agent" 10 "github.com/juju/juju/cmd/jujud/agent/unit" 11 "github.com/juju/juju/testing" 12 ) 13 14 type ManifoldsSuite struct { 15 testing.BaseSuite 16 } 17 18 var _ = gc.Suite(&ManifoldsSuite{}) 19 20 func (s *ManifoldsSuite) TestStartFuncs(c *gc.C) { 21 manifolds := unit.Manifolds(unit.ManifoldsConfig{ 22 Agent: fakeAgent{}, 23 }) 24 25 for name, manifold := range manifolds { 26 c.Logf("checking %q manifold", name) 27 c.Check(manifold.Start, gc.NotNil) 28 } 29 } 30 31 // TODO(cmars) 2015/08/10: rework this into builtin Engine cycle checker. 32 func (s *ManifoldsSuite) TestAcyclic(c *gc.C) { 33 manifolds := unit.Manifolds(unit.ManifoldsConfig{ 34 Agent: fakeAgent{}, 35 }) 36 count := len(manifolds) 37 38 // Set of vars for depth-first topological sort of manifolds. (Note that, 39 // because we've already got outgoing links stored conveniently, we're 40 // actually checking the transpose of the dependency graph. Cycles will 41 // still be cycles in either direction, though.) 42 done := make(map[string]bool) 43 doing := make(map[string]bool) 44 sorted := make([]string, 0, count) 45 46 // Stupid _-suffix malarkey allows recursion. Seems cleaner to keep these 47 // considerations inside this func than to embody the algorithm in a type. 48 visit := func(node string) {} 49 visit_ := func(node string) { 50 if doing[node] { 51 c.Fatalf("cycle detected at %q (considering: %v)", node, doing) 52 } 53 if !done[node] { 54 doing[node] = true 55 for _, input := range manifolds[node].Inputs { 56 visit(input) 57 } 58 done[node] = true 59 doing[node] = false 60 sorted = append(sorted, node) 61 } 62 } 63 visit = visit_ 64 65 // Actually sort them, or fail if we find a cycle. 66 for node := range manifolds { 67 visit(node) 68 } 69 c.Logf("got: %v", sorted) 70 c.Check(sorted, gc.HasLen, count) // Final sanity check. 71 } 72 73 type fakeAgent struct { 74 agent.Agent 75 }