diff --git a/dag/walk_test.go b/dag/walk_test.go index 6c1f24942b..9095d71892 100644 --- a/dag/walk_test.go +++ b/dag/walk_test.go @@ -215,63 +215,63 @@ func TestWalker_newEdge(t *testing.T) { } func TestWalker_removeEdge(t *testing.T) { - // Run it a bunch of times since it is timing dependent - for i := 0; i < 50; i++ { - var g AcyclicGraph - g.Add(1) - g.Add(2) - g.Add(3) - g.Connect(BasicEdge(1, 2)) - g.Connect(BasicEdge(3, 2)) - - // Record function - var order []interface{} - recordF := walkCbRecord(&order) - - // The way this works is that our original graph forces - // the order of 1 => 3 => 2. During the execution of 1, we - // remove the edge forcing 3 before 2. Then, during the execution - // of 3, we wait on a channel that is only closed by 2, implicitly - // forcing 2 before 3 via the callback (and not the graph). If - // 2 cannot execute before 3 (edge removal is non-functional), then - // this test will timeout. - var w *Walker - gateCh := make(chan struct{}) - cb := func(v Vertex) error { - if v == 1 { - g.RemoveEdge(BasicEdge(3, 2)) - w.Update(&g) - } + var g AcyclicGraph + g.Add(1) + g.Add(2) + g.Add(3) + g.Connect(BasicEdge(1, 2)) + g.Connect(BasicEdge(1, 3)) + g.Connect(BasicEdge(3, 2)) - if v == 2 { - close(gateCh) - } + // Record function + var order []interface{} + recordF := walkCbRecord(&order) - if v == 3 { - select { - case <-gateCh: - case <-time.After(50 * time.Millisecond): - return fmt.Errorf("timeout 3 waiting for 2") - } - } + // The way this works is that our original graph forces + // the order of 1 => 3 => 2. During the execution of 1, we + // remove the edge forcing 3 before 2. Then, during the execution + // of 3, we wait on a channel that is only closed by 2, implicitly + // forcing 2 before 3 via the callback (and not the graph). If + // 2 cannot execute before 3 (edge removal is non-functional), then + // this test will timeout. + var w *Walker + gateCh := make(chan struct{}) + cb := func(v Vertex) error { + switch v { + case 1: + g.RemoveEdge(BasicEdge(3, 2)) + w.Update(&g) - return recordF(v) + case 2: + // this visit isn't completed until we've recorded it + // Once the visit is official, we can then close the gate to + // let 3 continue. + defer close(gateCh) + + case 3: + select { + case <-gateCh: + case <-time.After(50 * time.Millisecond): + return fmt.Errorf("timeout 3 waiting for 2") + } } - // Add the initial vertices - w = &Walker{Callback: cb} - w.Update(&g) + return recordF(v) + } - // Wait - if err := w.Wait(); err != nil { - t.Fatalf("err: %s", err) - } + // Add the initial vertices + w = &Walker{Callback: cb} + w.Update(&g) - // Check - expected := []interface{}{1, 2, 3} - if !reflect.DeepEqual(order, expected) { - t.Fatalf("bad: %#v", order) - } + // Wait + if err := w.Wait(); err != nil { + t.Fatalf("err: %s", err) + } + + // Check + expected := []interface{}{1, 2, 3} + if !reflect.DeepEqual(order, expected) { + t.Fatalf("bad: %#v", order) } }