Example #1
0
func TestDepthFirstSearchInCycleGraph(t *testing.T) {
	//Create some nodes.
	a := graph.Node{Value: Letter{"A"}}
	b := graph.Node{Value: Letter{"B"}}
	c := graph.Node{Value: Letter{"C"}}
	d := graph.Node{Value: Letter{"D"}}
	e := graph.Node{Value: Letter{"E"}}
	f := graph.Node{Value: Letter{"F"}}
	g := graph.Node{Value: Letter{"G"}}

	directGraph := graph.NewGraph()

	directGraph.InsertEdge(&a, &b)
	directGraph.InsertEdge(&a, &c)
	directGraph.InsertEdge(&a, &e)
	directGraph.InsertEdge(&b, &d)
	directGraph.InsertEdge(&b, &f)
	directGraph.InsertEdge(&c, &g)
	directGraph.InsertEdge(&f, &e)

	expectedDepthFirstSearch := directGraph.GetDFS()
	correctDepthFirstSearch := []Letter{
		{"A"}, {"B"}, {"D"}, {"F"}, {"E"}, {"C"}, {"G"},
	}

	//Compare DFS with correct DFS.
	for index := 0; index < len(expectedDepthFirstSearch); index++ {
		if expectedDepthFirstSearch[index].Value.String() != correctDepthFirstSearch[index].letter {
			t.Errorf("Element nr. %d in DFS should be %s, not %s\n", index, correctDepthFirstSearch[index].letter,
				expectedDepthFirstSearch[index].Value.String())
		}
	}

}
Example #2
0
func TestStronglyConnectedComponentsInGraph(t *testing.T) {
	directedGraph := graph.NewGraph()

	a := graph.Node{Value: Letter{"A"}}
	b := graph.Node{Value: Letter{"B"}}
	c := graph.Node{Value: Letter{"C"}}
	d := graph.Node{Value: Letter{"D"}}
	e := graph.Node{Value: Letter{"E"}}
	f := graph.Node{Value: Letter{"F"}}
	g := graph.Node{Value: Letter{"G"}}
	h := graph.Node{Value: Letter{"H"}}

	directedGraph.InsertEdge(&a, &b)
	directedGraph.InsertEdge(&b, &c)
	directedGraph.InsertEdge(&c, &d)
	directedGraph.InsertEdge(&d, &c)
	directedGraph.InsertEdge(&d, &h)
	directedGraph.InsertEdge(&h, &d)
	directedGraph.InsertEdge(&c, &g)
	directedGraph.InsertEdge(&h, &g)
	directedGraph.InsertEdge(&f, &g)
	directedGraph.InsertEdge(&g, &f)
	directedGraph.InsertEdge(&b, &f)
	directedGraph.InsertEdge(&e, &f)
	directedGraph.InsertEdge(&e, &a)
	directedGraph.InsertEdge(&b, &e)

	expectedStronglyConnectedComponents := directedGraph.GetSCComponents()
	correctStronglyConnectedComponents := []*graph.StronglyConnectedComponent{
		{
			Nodes: []*graph.Node{
				{Value: Letter{"F"}},
				{Value: Letter{"G"}},
			}},
		{
			Nodes: []*graph.Node{
				{Value: Letter{"H"}},
				{Value: Letter{"C"}},
				{Value: Letter{"D"}},
			}},
		{
			Nodes: []*graph.Node{
				{Value: Letter{"B"}},
				{Value: Letter{"A"}},
				{Value: Letter{"E"}},
			}},
	}

	// Check the number of SCC sets.
	if len(expectedStronglyConnectedComponents) != len(correctStronglyConnectedComponents) {
		t.Fatalf("Number of strongly connected components be %d, but are %d!\n", len(correctStronglyConnectedComponents),
			len(expectedStronglyConnectedComponents))
	}

	if !sccExists(correctStronglyConnectedComponents, expectedStronglyConnectedComponents) {
		t.Error("Not all SCC exists")
	}

}
func TestIfElseControlFlowGraph(t *testing.T) {
	filePath := "./testcode/_ifelse.go"
	sourceFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	basicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, sourceFile)
	if err != nil {
		t.Fatal(err)
	}
	expectedGraph := cfgraph.GetControlFlowGraph(basicBlocks)
	correctGraph := graph.NewGraph()

	START := bblock.NewBasicBlock(-1, bblock.START, 0)
	EXIT := bblock.NewBasicBlock(-1, bblock.EXIT, 0)

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.IF_CONDITION, 13)
	BB2 := bblock.NewBasicBlock(2, bblock.ELSE_CONDITION, 16)
	BB3 := bblock.NewBasicBlock(3, bblock.ELSE_BODY, 20)
	BB4 := bblock.NewBasicBlock(4, bblock.RETURN_STMT, 23)

	BB0.AddSuccessorBlock(BB1)
	BB1.AddSuccessorBlock(BB2, BB3)
	BB2.AddSuccessorBlock(BB4)
	BB3.AddSuccessorBlock(BB4)

	correctBasicBlocks := []*bblock.BasicBlock{BB0, BB1, BB2, BB3, BB4}

	//Test basic-blocks.
	if err := VerifyBasicBlocks(basicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}

	correctGraph.InsertEdge(&graph.Node{Value: START}, &graph.Node{Value: BB0})
	correctGraph.InsertEdge(&graph.Node{Value: BB0}, &graph.Node{Value: BB1})
	correctGraph.InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: BB2})
	correctGraph.InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: BB3})
	correctGraph.InsertEdge(&graph.Node{Value: BB2}, &graph.Node{Value: BB4})
	correctGraph.InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB4})
	correctGraph.InsertEdge(&graph.Node{Value: BB4}, &graph.Node{Value: EXIT})
	correctGraph.InsertEdge(&graph.Node{Value: EXIT}, &graph.Node{Value: START})

	if err := VerifyControlFlowGraphs(expectedGraph[0], correctGraph); err != nil {
		t.Fatal(err)
	}
}
Example #4
0
func TestDepthFirstSearchInGraph(t *testing.T) {
	//Create some nodes.
	a := graph.Node{Value: Letter{"A"}}
	b := graph.Node{Value: Letter{"B"}}
	c := graph.Node{Value: Letter{"C"}}
	d := graph.Node{Value: Letter{"D"}}
	e := graph.Node{Value: Letter{"E"}}
	f := graph.Node{Value: Letter{"F"}}
	g := graph.Node{Value: Letter{"G"}}
	h := graph.Node{Value: Letter{"H"}}

	graph := graph.NewGraph()

	//Add directed node-pairs to graph.
	graph.InsertEdge(&a, &b)
	graph.InsertEdge(&a, &d)
	graph.InsertEdge(&b, &d)
	graph.InsertEdge(&b, &c)
	graph.InsertEdge(&c, &e)
	graph.InsertEdge(&e, &g)
	graph.InsertEdge(&e, &f)
	graph.InsertEdge(&f, &h)

	expectedDepthFirstSearch := graph.GetDFS()
	correctDfs := []Letter{{"A"}, {"B"}, {"D"}, {"C"}, {"E"}, {"G"}, {"F"}, {"H"}}

	//Equal length.
	if len(correctDfs) != len(expectedDepthFirstSearch) {
		t.Errorf("Length of DFS (%d) is not equal length of correct DFS (%d)!\n", len(expectedDepthFirstSearch), len(correctDfs))
	}

	//Check nodes in depth first search.
	for index, node := range expectedDepthFirstSearch {
		if node.String() != correctDfs[index].String() {
			t.Error("Faen i helvete")
		}
	}

}
func TestSimpleControlFlowGraph(t *testing.T) {
	filePath := "./testcode/_simple.go"
	sourceFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	basicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, sourceFile)
	if err != nil {
		t.Fatal(err)
	}
	expectedGraph := cfgraph.GetControlFlowGraph(basicBlocks)
	correctGraph := graph.NewGraph()

	START := bblock.NewBasicBlock(-1, bblock.START, 0)
	EXIT := bblock.NewBasicBlock(-1, bblock.EXIT, 0)

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.RETURN_STMT, 11)

	BB0.AddSuccessorBlock(BB1)

	correctBasicBlocks := []*bblock.BasicBlock{BB0, BB1}

	//Test basic-blocks.
	if err := VerifyBasicBlocks(basicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}

	correctGraph.InsertEdge(&graph.Node{Value: START}, &graph.Node{Value: BB0})
	correctGraph.InsertEdge(&graph.Node{Value: BB0}, &graph.Node{Value: BB1})
	correctGraph.InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: EXIT})
	correctGraph.InsertEdge(&graph.Node{Value: EXIT}, &graph.Node{Value: START})

	if err := VerifyControlFlowGraphs(expectedGraph[0], correctGraph); err != nil {
		t.Fatal(err)
	}
}
Example #6
0
func New() *ControlFlowGraph {
	return &ControlFlowGraph{graph.NewGraph()}
}
Example #7
0
func TestDirectedGraph(test *testing.T) {
	//Create some nodes.
	a := graph.Node{Value: Letter{"A"}}
	b := graph.Node{Value: Letter{"B"}}
	c := graph.Node{Value: Letter{"C"}}
	d := graph.Node{Value: Letter{"D"}}
	e := graph.Node{Value: Letter{"E"}}
	f := graph.Node{Value: Letter{"F"}}
	g := graph.Node{Value: Letter{"G"}}
	h := graph.Node{Value: Letter{"H"}}

	graph := graph.NewGraph()

	//Add directed node-pairs to graph.
	graph.InsertEdge(&a, &b)
	graph.InsertEdge(&a, &d)
	graph.InsertEdge(&b, &d)
	graph.InsertEdge(&b, &c)
	graph.InsertEdge(&c, &e)
	graph.InsertEdge(&e, &g)
	graph.InsertEdge(&e, &f)
	graph.InsertEdge(&f, &h)

	//Test number of nodes in graph.
	if graph.GetNumberOfNodes() != 8 {
		test.Fatalf("Graph should contain 8 nodes, not %d!\n", graph.GetNumberOfNodes())
	}

	//Node A should be root node.
	if graph.Root.Value != a.Value {
		test.Errorf("Node A should be root node, not node %v\n", graph.Root.Value)
	}

	//Test node A.
	if a.GetInDegree() != 0 {
		test.Errorf("Node A in-degree should be 0, not %d\n", a.GetInDegree())
	}
	if a.GetOutDegree() != 2 {
		test.Errorf("Node A out-degree should be 2, not %d\n", a.GetInDegree())
	}

	//Test node B.
	if b.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", b.GetInDegree())
	}
	if b.GetOutDegree() != 2 {
		test.Errorf("Node A out-degree should be 2, not %d\n", b.GetInDegree())
	}

	//Test node C.
	if c.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", c.GetInDegree())
	}
	if c.GetOutDegree() != 1 {
		test.Errorf("Node A out-degree should be 1, not %d\n", c.GetInDegree())
	}

	//Test node D.
	if d.GetInDegree() != 2 {
		test.Errorf("Node A in-degree should be 2, not %d\n", d.GetInDegree())
	}
	if d.GetOutDegree() != 0 {
		test.Errorf("Node A out-degree should be 0, not %d\n", d.GetInDegree())
	}

	//Test node E.
	if e.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", e.GetInDegree())
	}
	if e.GetOutDegree() != 2 {
		test.Errorf("Node A out-degree should be 2, not %d\n", e.GetInDegree())
	}

	//Test node F.
	if f.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", f.GetInDegree())
	}
	if f.GetOutDegree() != 1 {
		test.Errorf("Node A out-degree should be 1, not %d\n", f.GetInDegree())
	}

	//Test node G.
	if g.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", g.GetInDegree())
	}
	if g.GetOutDegree() != 0 {
		test.Errorf("Node A out-degree should be 0, not %d\n", g.GetInDegree())
	}

	//Test node H.
	if h.GetInDegree() != 1 {
		test.Errorf("Node A in-degree should be 1, not %d\n", h.GetInDegree())
	}
	if h.GetOutDegree() != 0 {
		test.Errorf("Node A out-degree should be 0, not %d\n", h.GetInDegree())
	}

}
func TestGreatestCommonDivisorControlFlowGraph(t *testing.T) {
	filePath := "./testcode/_gcd.go"
	sourceFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	basicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, sourceFile)
	if err != nil {
		t.Fatal(err)
	}

	expectedGraphs := cfgraph.GetControlFlowGraph(basicBlocks)
	correctGraph := []*graph.Graph{
		graph.NewGraph(), // func 'gcd'
		graph.NewGraph(), // func 'main'
	}

	// Function 'gcd'
	START0 := bblock.NewBasicBlock(-1, bblock.START, 0)
	EXIT0 := bblock.NewBasicBlock(-1, bblock.EXIT, 0)
	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.FOR_STATEMENT, 10)
	BB2 := bblock.NewBasicBlock(2, bblock.FOR_BODY, 13)
	BB3 := bblock.NewBasicBlock(3, bblock.RETURN_STMT, 14)

	// Function 'main'
	START1 := bblock.NewBasicBlock(-1, bblock.START, 0)
	EXIT1 := bblock.NewBasicBlock(-1, bblock.EXIT, 0)
	BB4 := bblock.NewBasicBlock(4, bblock.FUNCTION_ENTRY, 17)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 21)

	BB0.AddSuccessorBlock(BB1)
	BB1.AddSuccessorBlock(BB2, BB3)
	BB2.AddSuccessorBlock(BB1)
	BB4.AddSuccessorBlock(BB5)

	correctBasicBlocks := []*bblock.BasicBlock{BB0, BB1, BB2, BB3, BB4, BB5}

	// Function 'gcd'
	correctGraph[0].InsertEdge(&graph.Node{Value: START0}, &graph.Node{Value: BB0})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB0}, &graph.Node{Value: BB1})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: BB2})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB2}, &graph.Node{Value: BB1})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: BB3})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: EXIT0})
	correctGraph[0].InsertEdge(&graph.Node{Value: EXIT0}, &graph.Node{Value: START0})

	// Function 'main'
	correctGraph[1].InsertEdge(&graph.Node{Value: START1}, &graph.Node{Value: BB4})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB4}, &graph.Node{Value: BB5})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB5}, &graph.Node{Value: EXIT1})
	correctGraph[1].InsertEdge(&graph.Node{Value: EXIT1}, &graph.Node{Value: START1})

	// Test basic-blocks.
	if err := VerifyBasicBlocks(basicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
	// Test control-flow graph.
	if err := VerifyControlFlowGraphs(expectedGraphs[0], correctGraph[0]); err != nil {
		t.Fatal(err)
	}
	if err := VerifyControlFlowGraphs(expectedGraphs[1], correctGraph[1]); err != nil {
		t.Fatal(err)
	}
}
func TestSwitchControlFlowGraph(t *testing.T) {
	filePath := "./testcode/_switcher.go"
	sourceFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	basicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, sourceFile)
	if err != nil {
		t.Fatal(err)
	}
	expectedGraphs := cfgraph.GetControlFlowGraph(basicBlocks)
	correctGraph := []*graph.Graph{
		graph.NewGraph(), // func 'main'
		graph.NewGraph(), // func 'integerToString'
	}

	START := bblock.NewBasicBlock(-1, bblock.START, 0)
	EXIT := bblock.NewBasicBlock(-1, bblock.EXIT, 0)

	// Function 'main'
	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.RETURN_STMT, 11)

	// Function 'integerToString'
	BB2 := bblock.NewBasicBlock(2, bblock.FUNCTION_ENTRY, 13)
	BB3 := bblock.NewBasicBlock(3, bblock.SWITCH_STATEMENT, 14)
	BB4 := bblock.NewBasicBlock(4, bblock.RETURN_STMT, 16)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 18)
	BB6 := bblock.NewBasicBlock(6, bblock.RETURN_STMT, 20)
	BB7 := bblock.NewBasicBlock(7, bblock.RETURN_STMT, 22)
	BB8 := bblock.NewBasicBlock(8, bblock.RETURN_STMT, 24)

	BB0.AddSuccessorBlock(BB1)
	BB2.AddSuccessorBlock(BB3)
	BB3.AddSuccessorBlock(BB4, BB5, BB6, BB7, BB8)

	correctBasicBlocks := []*bblock.BasicBlock{BB0, BB1, BB2, BB3, BB4, BB5, BB6, BB7, BB8}

	//Test basic-blocks.
	if err := VerifyBasicBlocks(basicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}

	// Control flow graph for function 'main'.
	correctGraph[0].InsertEdge(&graph.Node{Value: START}, &graph.Node{Value: BB0})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB0}, &graph.Node{Value: BB1})
	correctGraph[0].InsertEdge(&graph.Node{Value: BB1}, &graph.Node{Value: EXIT})
	correctGraph[0].InsertEdge(&graph.Node{Value: EXIT}, &graph.Node{Value: START})

	// Control flow graph for function 'integerToString'.
	correctGraph[1].InsertEdge(&graph.Node{Value: START}, &graph.Node{Value: BB2})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB2}, &graph.Node{Value: BB3})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB4})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB5})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB6})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB7})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB3}, &graph.Node{Value: BB8})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB4}, &graph.Node{Value: EXIT})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB5}, &graph.Node{Value: EXIT})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB6}, &graph.Node{Value: EXIT})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB7}, &graph.Node{Value: EXIT})
	correctGraph[1].InsertEdge(&graph.Node{Value: BB8}, &graph.Node{Value: EXIT})
	correctGraph[1].InsertEdge(&graph.Node{Value: EXIT}, &graph.Node{Value: START})

	if err := VerifyControlFlowGraphs(expectedGraphs[0], correctGraph[0]); err != nil {
		t.Fatal(err)
	}
	if err := VerifyControlFlowGraphs(expectedGraphs[1], correctGraph[1]); err != nil {
		t.Fatal(err)
	}
}