github.com/hzck/speedroute@v0.0.0-20201115191102-403b7d0e443f/algorithm/algorithm_test.go (about) 1 package algorithm 2 3 import ( 4 "bufio" 5 "fmt" 6 "math/rand" 7 "os" 8 "testing" 9 10 m "github.com/hzck/speedroute/model" 11 "github.com/hzck/speedroute/parser" 12 ) 13 14 // TestAllFiles goes through tests/ folder and tries to route a path, verifying towards files 15 // in validations/ folder. Folder structure is the same in both tests/ and validations/ to 16 // know which validation belongs to which test case. 17 func TestAllFiles(t *testing.T) { 18 for _, testPath := range getDirFileNames(t, "tests/") { 19 graph, err := parser.CreateGraphFromFile(testPath) 20 if err != nil { 21 failAndPrint(t, err.Error()) 22 } 23 validation, err := os.Open("validations/" + testPath[6:]) 24 defer func() { 25 if closeErr := validation.Close(); closeErr != nil && err == nil { 26 failAndPrint(t, closeErr.Error()) 27 } 28 }() 29 if err != nil { 30 assertFailingPath(t, graph, testPath) 31 continue 32 } 33 var path []string 34 scanner := bufio.NewScanner(validation) 35 for scanner.Scan() { 36 path = append(path, scanner.Text()) 37 } 38 assertCorrectPath(t, path, Route(graph), testPath) 39 } 40 } 41 42 func getDirFileNames(t *testing.T, dirName string) []string { 43 var fileNames []string 44 dir, err := os.Open(dirName) 45 defer func() { 46 if closeErr := dir.Close(); closeErr != nil && err == nil { 47 failAndPrint(t, "Can't close dir: "+closeErr.Error()) 48 } 49 }() 50 if err != nil { 51 failAndPrint(t, "Can't open dir: "+err.Error()) 52 return nil 53 } 54 files, _ := dir.Readdir(-1) 55 for _, file := range files { 56 if file.IsDir() { 57 fileNames = append(fileNames, getDirFileNames(t, dirName+file.Name()+"/")...) 58 continue 59 } 60 fileNames = append(fileNames, dirName+file.Name()) 61 } 62 return fileNames 63 } 64 65 func assertFailingPath(t *testing.T, graph *m.Graph, testPath string) { 66 if Route(graph) != nil { 67 failAndPrint(t, "assertFailingPath: "+testPath) 68 } 69 } 70 71 func assertCorrectPath(t *testing.T, nodes []string, path []*m.Edge, testPath string) { 72 if len(path) != len(nodes)-1 { 73 failAndPrint(t, "assertCorrectPath - len: "+testPath) 74 } 75 for i, edge := range path { 76 if edge.From().ID() != nodes[i] || edge.To().ID() != nodes[i+1] { 77 failAndPrint(t, "assertCorrectPath - correct "+nodes[i]+"->"+nodes[i+1]+", is "+edge.From().ID()+"->"+edge.To().ID()+": "+testPath) 78 } 79 } 80 } 81 82 func failAndPrint(t *testing.T, testPath string) { 83 t.Fail() 84 fmt.Println("Failing " + testPath) 85 } 86 87 // TestBenchmarkGraph verifies that the benchmarking randomized graph works. 88 func TestBenchmarkGraph(t *testing.T) { 89 size := 4 90 graph := createBenchmarkGraph(size) 91 path := Route(graph) 92 if len(path) != size*2 { 93 t.Fail() 94 } 95 } 96 97 // BenchmarkAlgorithm consists of an int of the magnitude the graph should be benchmarked against. 98 func BenchmarkAlgorithm(b *testing.B) { 99 graph := createBenchmarkGraph(30) 100 b.ResetTimer() 101 Route(graph) 102 } 103 104 // createBenchmarkGraph creates a graph from an int parameter specifying the magnitude of the graph. 105 // Nodes: n²+n+1. Edges: n³+n². Possible paths: (can't remember). 106 func createBenchmarkGraph(size int) *m.Graph { 107 transitionNode := m.CreateNode("tempId", false) 108 startNode := transitionNode 109 for i := 0; i < size; i++ { 110 var nodes []*m.Node 111 tempNode := m.CreateNode("tempId", false) 112 for k := 0; k < size; k++ { 113 newNode := m.CreateNode("tempId", false) 114 nodes = append(nodes, newNode) 115 createWeightedEdge(transitionNode, newNode, rand.Intn(10000)+1) 116 createWeightedEdge(newNode, tempNode, rand.Intn(10000)+1) 117 } 118 transitionNode = tempNode 119 for _, a := range nodes { 120 for _, b := range nodes { 121 if a != b { 122 createWeightedEdge(a, b, rand.Intn(10000)+1) 123 } 124 } 125 } 126 } 127 return m.CreateGraph(startNode, transitionNode) 128 } 129 130 func createWeightedEdge(from, to *m.Node, time int) { 131 edge := m.CreateEdge(from, to) 132 edge.AddWeight(m.CreateWeight(time)) 133 }