github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/release/dependency/graph_test.go (about) 1 package dependency_test 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/helmwave/helmwave/pkg/release/dependency" 8 "github.com/stretchr/testify/suite" 9 ) 10 11 type GraphTestSuite struct { 12 suite.Suite 13 } 14 15 func (s *GraphTestSuite) TestNewNode() { 16 key := "1" 17 data := "123" 18 19 graph := dependency.NewGraph[string, string]() 20 s.Require().NoError(graph.NewNode(key, data)) 21 22 s.Require().Len(graph.Nodes, 1) 23 s.Require().Contains(graph.Nodes, key) 24 s.Require().Equal(graph.Nodes[key].Data, data) 25 s.Require().False(graph.Nodes[key].IsDone()) 26 s.Require().True(graph.Nodes[key].IsReady()) 27 28 s.Require().NoError(graph.Build()) 29 } 30 31 func (s *GraphTestSuite) TestDuplicateNode() { 32 key := "1" 33 34 graph := dependency.NewGraph[string, string]() 35 36 s.Require().NoError(graph.NewNode(key, "123")) 37 s.Require().Error(graph.NewNode(key, "321")) 38 s.Require().Len(graph.Nodes, 1) 39 40 s.Require().NoError(graph.Build()) 41 } 42 43 // 1 -> 3 -> 4 44 // 2 / 45 func (s *GraphTestSuite) TestDependencies() { 46 graph := dependency.NewGraph[string, string]() 47 48 s.Require().NoError(graph.NewNode("1", "1")) 49 s.Require().NoError(graph.NewNode("2", "2")) 50 s.Require().NoError(graph.NewNode("3", "3")) 51 s.Require().NoError(graph.NewNode("4", "4")) 52 53 graph.AddDependency("3", "1") 54 graph.AddDependency("3", "2") 55 graph.AddDependency("4", "3") 56 57 s.Require().NoError(graph.Build()) 58 59 ch := graph.Run() 60 61 s.Require().NotNil(ch) 62 s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond) 63 s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond) 64 d1, d2 := <-ch, <-ch 65 s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data}) 66 d1.SetSucceeded() 67 d2.SetSucceeded() 68 69 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 70 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 71 d := <-ch 72 s.Require().Equal("3", d.Data) 73 d.SetSucceeded() 74 75 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 76 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 77 d = <-ch 78 s.Require().Equal("4", d.Data) 79 d.SetSucceeded() 80 81 s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond) 82 } 83 84 func (s *GraphTestSuite) TestFailedDependencies() { 85 graph := dependency.NewGraph[string, string]() 86 87 s.Require().NoError(graph.NewNode("1", "1")) 88 s.Require().NoError(graph.NewNode("2", "2")) 89 s.Require().NoError(graph.NewNode("3", "3")) 90 s.Require().NoError(graph.NewNode("4", "4")) 91 92 graph.AddDependency("3", "1") 93 graph.AddDependency("3", "2") 94 graph.AddDependency("4", "3") 95 96 s.Require().NoError(graph.Build()) 97 98 ch := graph.Run() 99 100 s.Require().NotNil(ch) 101 s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond) 102 s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond) 103 d1, d2 := <-ch, <-ch 104 s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data}) 105 d1.SetSucceeded() 106 d2.SetFailed() 107 108 s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond) 109 } 110 111 func (s *GraphTestSuite) TestCycles() { 112 graph := dependency.NewGraph[string, string]() 113 114 s.Require().NoError(graph.NewNode("1", "1")) 115 s.Require().NoError(graph.NewNode("2", "2")) 116 117 graph.AddDependency("1", "2") 118 graph.AddDependency("2", "1") 119 120 s.Require().Error(graph.Build()) 121 } 122 123 // 1 -> 3 -> 4 124 // 2 / 125 // Reversed 126 // 4 -> 3 -> 1 127 // 128 // \-> 2 129 func (s *GraphTestSuite) TestReverse() { 130 graph := dependency.NewGraph[string, string]() 131 132 s.Require().NoError(graph.NewNode("1", "1")) 133 s.Require().NoError(graph.NewNode("2", "2")) 134 s.Require().NoError(graph.NewNode("3", "3")) 135 s.Require().NoError(graph.NewNode("4", "4")) 136 137 graph.AddDependency("3", "1") 138 graph.AddDependency("3", "2") 139 graph.AddDependency("4", "3") 140 141 s.Require().NoError(graph.Build()) 142 graph, err := graph.Reverse() 143 s.Require().NoError(err) 144 145 ch := graph.Run() 146 147 s.Require().NotNil(ch) 148 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 149 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 150 d := <-ch 151 s.Require().Equal("4", d.Data) 152 d.SetSucceeded() 153 154 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 155 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 156 d = <-ch 157 s.Require().Equal("3", d.Data) 158 d.SetSucceeded() 159 160 s.Require().Eventually(func() bool { return len(ch) == 2 }, time.Second, time.Millisecond) 161 s.Require().Never(func() bool { return len(ch) > 2 }, time.Second, time.Millisecond) 162 d1, d2 := <-ch, <-ch 163 s.Require().ElementsMatch([]string{"1", "2"}, []string{d1.Data, d2.Data}) 164 d1.SetSucceeded() 165 d2.SetSucceeded() 166 167 s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond) 168 } 169 170 func (s *GraphTestSuite) TestReverseFailedDependencies() { 171 graph := dependency.NewGraph[string, string]() 172 173 s.Require().NoError(graph.NewNode("1", "1")) 174 s.Require().NoError(graph.NewNode("2", "2")) 175 s.Require().NoError(graph.NewNode("3", "3")) 176 s.Require().NoError(graph.NewNode("4", "4")) 177 178 graph.AddDependency("3", "1") 179 graph.AddDependency("3", "2") 180 graph.AddDependency("4", "3") 181 182 s.Require().NoError(graph.Build()) 183 graph, err := graph.Reverse() 184 s.Require().NoError(err) 185 186 ch := graph.Run() 187 188 s.Require().NotNil(ch) 189 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 190 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 191 d := <-ch 192 s.Require().Equal("4", d.Data) 193 d.SetSucceeded() 194 195 s.Require().Eventually(func() bool { return len(ch) == 1 }, time.Second, time.Millisecond) 196 s.Require().Never(func() bool { return len(ch) > 1 }, time.Second, time.Millisecond) 197 d = <-ch 198 s.Require().Equal("3", d.Data) 199 d.SetFailed() 200 201 s.Require().Never(func() bool { return len(ch) > 0 }, time.Second, time.Millisecond) 202 } 203 204 func TestGraphTestSuite(t *testing.T) { 205 t.Parallel() 206 suite.Run(t, new(GraphTestSuite)) 207 }