github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/dag/dag_test.go (about) 1 package dag 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 "sync" 8 "testing" 9 ) 10 11 func TestAcyclicGraphRoot(t *testing.T) { 12 var g AcyclicGraph 13 g.Add(1) 14 g.Add(2) 15 g.Add(3) 16 g.Connect(BasicEdge(3, 2)) 17 g.Connect(BasicEdge(3, 1)) 18 19 if root, err := g.Root(); err != nil { 20 t.Fatalf("err: %s", err) 21 } else if root != 3 { 22 t.Fatalf("bad: %#v", root) 23 } 24 } 25 26 func TestAcyclicGraphRoot_cycle(t *testing.T) { 27 var g AcyclicGraph 28 g.Add(1) 29 g.Add(2) 30 g.Add(3) 31 g.Connect(BasicEdge(1, 2)) 32 g.Connect(BasicEdge(2, 3)) 33 g.Connect(BasicEdge(3, 1)) 34 35 if _, err := g.Root(); err == nil { 36 t.Fatal("should error") 37 } 38 } 39 40 func TestAcyclicGraphRoot_multiple(t *testing.T) { 41 var g AcyclicGraph 42 g.Add(1) 43 g.Add(2) 44 g.Add(3) 45 g.Connect(BasicEdge(3, 2)) 46 47 if _, err := g.Root(); err == nil { 48 t.Fatal("should error") 49 } 50 } 51 52 func TestAyclicGraphTransReduction(t *testing.T) { 53 var g AcyclicGraph 54 g.Add(1) 55 g.Add(2) 56 g.Add(3) 57 g.Connect(BasicEdge(1, 2)) 58 g.Connect(BasicEdge(1, 3)) 59 g.Connect(BasicEdge(2, 3)) 60 g.TransitiveReduction() 61 62 actual := strings.TrimSpace(g.String()) 63 expected := strings.TrimSpace(testGraphTransReductionStr) 64 if actual != expected { 65 t.Fatalf("bad: %s", actual) 66 } 67 } 68 69 func TestAyclicGraphTransReduction_more(t *testing.T) { 70 var g AcyclicGraph 71 g.Add(1) 72 g.Add(2) 73 g.Add(3) 74 g.Add(4) 75 g.Connect(BasicEdge(1, 2)) 76 g.Connect(BasicEdge(1, 3)) 77 g.Connect(BasicEdge(1, 4)) 78 g.Connect(BasicEdge(2, 3)) 79 g.Connect(BasicEdge(2, 4)) 80 g.Connect(BasicEdge(3, 4)) 81 g.TransitiveReduction() 82 83 actual := strings.TrimSpace(g.String()) 84 expected := strings.TrimSpace(testGraphTransReductionMoreStr) 85 if actual != expected { 86 t.Fatalf("bad: %s", actual) 87 } 88 } 89 90 func TestAcyclicGraphValidate(t *testing.T) { 91 var g AcyclicGraph 92 g.Add(1) 93 g.Add(2) 94 g.Add(3) 95 g.Connect(BasicEdge(3, 2)) 96 g.Connect(BasicEdge(3, 1)) 97 98 if err := g.Validate(); err != nil { 99 t.Fatalf("err: %s", err) 100 } 101 } 102 103 func TestAcyclicGraphValidate_cycle(t *testing.T) { 104 var g AcyclicGraph 105 g.Add(1) 106 g.Add(2) 107 g.Add(3) 108 g.Connect(BasicEdge(3, 2)) 109 g.Connect(BasicEdge(3, 1)) 110 g.Connect(BasicEdge(1, 2)) 111 g.Connect(BasicEdge(2, 1)) 112 113 if err := g.Validate(); err == nil { 114 t.Fatal("should error") 115 } 116 } 117 118 func TestAcyclicGraphValidate_cycleSelf(t *testing.T) { 119 var g AcyclicGraph 120 g.Add(1) 121 g.Add(2) 122 g.Connect(BasicEdge(1, 1)) 123 124 if err := g.Validate(); err == nil { 125 t.Fatal("should error") 126 } 127 } 128 129 func TestAcyclicGraphAncestors(t *testing.T) { 130 var g AcyclicGraph 131 g.Add(1) 132 g.Add(2) 133 g.Add(3) 134 g.Add(4) 135 g.Add(5) 136 g.Connect(BasicEdge(0, 1)) 137 g.Connect(BasicEdge(1, 2)) 138 g.Connect(BasicEdge(2, 3)) 139 g.Connect(BasicEdge(3, 4)) 140 g.Connect(BasicEdge(4, 5)) 141 142 actual, err := g.Ancestors(2) 143 if err != nil { 144 t.Fatalf("err: %#v", err) 145 } 146 147 expected := []Vertex{3, 4, 5} 148 149 if actual.Len() != len(expected) { 150 t.Fatalf("bad length! expected %#v to have len %d", actual, len(expected)) 151 } 152 153 for _, e := range expected { 154 if !actual.Include(e) { 155 t.Fatalf("expected: %#v to include: %#v", expected, actual) 156 } 157 } 158 } 159 160 func TestAcyclicGraphDescendents(t *testing.T) { 161 var g AcyclicGraph 162 g.Add(1) 163 g.Add(2) 164 g.Add(3) 165 g.Add(4) 166 g.Add(5) 167 g.Connect(BasicEdge(0, 1)) 168 g.Connect(BasicEdge(1, 2)) 169 g.Connect(BasicEdge(2, 3)) 170 g.Connect(BasicEdge(3, 4)) 171 g.Connect(BasicEdge(4, 5)) 172 173 actual, err := g.Descendents(2) 174 if err != nil { 175 t.Fatalf("err: %#v", err) 176 } 177 178 expected := []Vertex{0, 1} 179 180 if actual.Len() != len(expected) { 181 t.Fatalf("bad length! expected %#v to have len %d", actual, len(expected)) 182 } 183 184 for _, e := range expected { 185 if !actual.Include(e) { 186 t.Fatalf("expected: %#v to include: %#v", expected, actual) 187 } 188 } 189 } 190 191 func TestAcyclicGraphWalk(t *testing.T) { 192 var g AcyclicGraph 193 g.Add(1) 194 g.Add(2) 195 g.Add(3) 196 g.Connect(BasicEdge(3, 2)) 197 g.Connect(BasicEdge(3, 1)) 198 199 var visits []Vertex 200 var lock sync.Mutex 201 err := g.Walk(func(v Vertex) error { 202 lock.Lock() 203 defer lock.Unlock() 204 visits = append(visits, v) 205 return nil 206 }) 207 if err != nil { 208 t.Fatalf("err: %s", err) 209 } 210 211 expected := [][]Vertex{ 212 {1, 2, 3}, 213 {2, 1, 3}, 214 } 215 for _, e := range expected { 216 if reflect.DeepEqual(visits, e) { 217 return 218 } 219 } 220 221 t.Fatalf("bad: %#v", visits) 222 } 223 224 func TestAcyclicGraphWalk_error(t *testing.T) { 225 var g AcyclicGraph 226 g.Add(1) 227 g.Add(2) 228 g.Add(3) 229 g.Add(4) 230 g.Connect(BasicEdge(4, 3)) 231 g.Connect(BasicEdge(3, 2)) 232 g.Connect(BasicEdge(2, 1)) 233 234 var visits []Vertex 235 var lock sync.Mutex 236 err := g.Walk(func(v Vertex) error { 237 lock.Lock() 238 defer lock.Unlock() 239 240 if v == 2 { 241 return fmt.Errorf("error") 242 } 243 244 visits = append(visits, v) 245 return nil 246 }) 247 if err == nil { 248 t.Fatal("should error") 249 } 250 251 expected := [][]Vertex{ 252 {1}, 253 } 254 for _, e := range expected { 255 if reflect.DeepEqual(visits, e) { 256 return 257 } 258 } 259 260 t.Fatalf("bad: %#v", visits) 261 } 262 263 const testGraphTransReductionStr = ` 264 1 265 2 266 2 267 3 268 3 269 ` 270 271 const testGraphTransReductionMoreStr = ` 272 1 273 2 274 2 275 3 276 3 277 4 278 4 279 `