github.com/awesome-flow/flow@v0.0.3-0.20190918184116-508d75d68a2c/pkg/util/data/topology_test.go (about) 1 package data 2 3 import ( 4 "reflect" 5 "strings" 6 "testing" 7 ) 8 9 type testNode struct { 10 name string 11 } 12 13 func (tn *testNode) GetName() string { 14 return tn.name 15 } 16 17 func newNode(name string) *testNode { 18 return &testNode{name} 19 } 20 21 func TestTopology_SortEmpty(t *testing.T) { 22 nodes := []TopologyNode{} 23 top := NewTopology(nodes...) 24 sorted, err := top.Sort() 25 if err != nil { 26 t.Errorf("Unexpected error: %s", err) 27 } 28 if l := len(sorted); l != 0 { 29 t.Errorf("Unexpected length of sorted arr: %d (want 0)", l) 30 } 31 } 32 33 func TestTopology_SortSingle(t *testing.T) { 34 nodes := []TopologyNode{ 35 newNode("1"), 36 } 37 top := NewTopology(nodes...) 38 sorted, err := top.Sort() 39 if err != nil { 40 t.Errorf("Unexpected error: %s", err) 41 } 42 if l := len(sorted); l != 1 { 43 t.Errorf("Unexpected length of sorted arr: %d (want 0)", l) 44 } 45 if !reflect.DeepEqual(sorted[0], nodes[0]) { 46 t.Errorf("Unexpected element in sorted list: %+v", sorted[0]) 47 } 48 } 49 50 type StringerNode string 51 52 func TestTopology_SortUnresolvable(t *testing.T) { 53 nodes := []TopologyNode{ 54 StringerNode("1"), 55 StringerNode("2"), 56 StringerNode("3"), 57 } 58 59 top := NewTopology(nodes...) 60 top.Connect(nodes[0], nodes[1]) 61 top.Connect(nodes[1], nodes[2]) 62 top.Connect(nodes[2], nodes[0]) 63 64 sorted, err := top.Sort() 65 if err == nil { 66 t.Errorf("Expected an error from a cycled graph") 67 } 68 if l := len(sorted); l != 0 { 69 t.Errorf("Unexpected length of the sorted result: %d (want 0)", l) 70 } 71 res := make([]string, 0, len(sorted)) 72 for _, node := range sorted { 73 res = append(res, string(node.(StringerNode))) 74 } 75 t.Log(strings.Join(res, " -> ")) 76 } 77 78 /* 79 https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Directed_acyclic_graph_2.svg/1280px-Directed_acyclic_graph_2.svg.png 80 81 (5) (7) (3) 82 | / | / 83 v / v / 84 (11) (8) 85 | \ \| 86 v \ v \ 87 (2) (9) (10) 88 89 */ 90 func TestTopology_SortExample(t *testing.T) { 91 node2, node3, node5, node7, node8, node9, node10, node11 := 92 StringerNode("2"), 93 StringerNode("3"), 94 StringerNode("5"), 95 StringerNode("7"), 96 StringerNode("8"), 97 StringerNode("9"), 98 StringerNode("10"), 99 StringerNode("11") 100 101 connections := map[StringerNode][]StringerNode{ 102 node5: {node11}, 103 node7: {node11, node8}, 104 node3: {node8, node10}, 105 node11: {node2, node9, node10}, 106 node8: {node9}, 107 } 108 109 top := NewTopology(node2, node3, node5, node7, node8, node9, node10, node11) 110 111 for from, tos := range connections { 112 for _, to := range tos { 113 if err := top.Connect(from, to); err != nil { 114 t.Fatalf(err.Error()) 115 } 116 } 117 } 118 119 sorted, err := top.Sort() 120 if err != nil { 121 t.Fatalf("Failed to perform topological sort of the graph: %s", err) 122 } 123 124 visited := make(map[StringerNode]bool) 125 for _, node := range sorted { 126 if deps, ok := connections[node.(StringerNode)]; ok { 127 for _, dep := range deps { 128 if _, ok := visited[dep]; !ok { 129 t.Fatalf( 130 "Node %#v was expected to be visited after %#v. Full order: %#v\n", 131 node, 132 dep, 133 sorted) 134 } 135 } 136 } 137 visited[node.(StringerNode)] = true 138 } 139 }