github.com/markdia/terraform@v0.5.1-0.20150508012022-f1ae920aa970/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.Connect(BasicEdge(3, 2)) 230 g.Connect(BasicEdge(3, 1)) 231 232 var visits []Vertex 233 var lock sync.Mutex 234 err := g.Walk(func(v Vertex) error { 235 lock.Lock() 236 defer lock.Unlock() 237 238 if v == 2 { 239 return fmt.Errorf("error") 240 } 241 242 visits = append(visits, v) 243 return nil 244 }) 245 if err == nil { 246 t.Fatal("should error") 247 } 248 249 expected := [][]Vertex{ 250 {1}, 251 } 252 for _, e := range expected { 253 if reflect.DeepEqual(visits, e) { 254 return 255 } 256 } 257 258 t.Fatalf("bad: %#v", visits) 259 } 260 261 const testGraphTransReductionStr = ` 262 1 263 2 264 2 265 3 266 3 267 ` 268 269 const testGraphTransReductionMoreStr = ` 270 1 271 2 272 2 273 3 274 3 275 4 276 4 277 `