コード例 #1
0
func TestIfElseBasicBlock(t *testing.T) {
	filePath := "./testcode/_ifelse.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	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, 24)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #2
0
func TestGreatestCommonDivisor(t *testing.T) {
	filePath := "./testcode/_gcd.go"
	srcFile, err := ioutil.ReadFile("./testcode/_gcd.go")
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.RETURN_STMT, 12)
	BB2 := bblock.NewBasicBlock(2, bblock.FUNCTION_ENTRY, 14)
	BB3 := bblock.NewBasicBlock(3, bblock.FOR_STATEMENT, 16)
	BB4 := bblock.NewBasicBlock(4, bblock.FOR_BODY, 19)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 20)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #3
0
func TestSimpleLooperSwitch(t *testing.T) {
	filePath := "./testcode/_simplelooperswitch.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Error(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.FOR_STATEMENT, 11)
	BB2 := bblock.NewBasicBlock(2, bblock.SWITCH_STATEMENT, 13)
	BB3 := bblock.NewBasicBlock(3, bblock.CASE_CLAUSE, 15)
	BB4 := bblock.NewBasicBlock(4, bblock.CASE_CLAUSE, 17)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 20)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #4
0
func TestSelectBasicBlock(t *testing.T) {
	filePath := "./testcode/_select.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 12)
	BB1 := bblock.NewBasicBlock(1, bblock.GO_STATEMENT, 16)
	BB2 := bblock.NewBasicBlock(2, bblock.FOR_STATEMENT, 24)
	BB3 := bblock.NewBasicBlock(3, bblock.SELECT_STATEMENT, 26)
	BB4 := bblock.NewBasicBlock(4, bblock.COMM_CLAUSE, 28)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 31)
	BB6 := bblock.NewBasicBlock(6, bblock.RETURN_STMT, 34)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #5
0
func TestLooperBasicBlock(t *testing.T) {
	filePath := "./testcode/_looper.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.FOR_STATEMENT, 11)
	BB2 := bblock.NewBasicBlock(2, bblock.FOR_BODY, 14)
	BB3 := bblock.NewBasicBlock(3, bblock.RETURN_STMT, 16)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #6
0
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)
	}
}
コード例 #7
0
func TestReturnSwitcherBasicBlock(t *testing.T) {
	filePath := "./testcode/_returnswitcher.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.RETURN_STMT, 12)
	BB2 := bblock.NewBasicBlock(2, bblock.FUNCTION_ENTRY, 14)
	BB3 := bblock.NewBasicBlock(3, bblock.SWITCH_STATEMENT, 16)
	BB4 := bblock.NewBasicBlock(4, bblock.RETURN_STMT, 18)
	BB5 := bblock.NewBasicBlock(5, bblock.RETURN_STMT, 20)
	BB6 := bblock.NewBasicBlock(6, bblock.RETURN_STMT, 22)
	BB7 := bblock.NewBasicBlock(7, bblock.RETURN_STMT, 24)
	BB8 := bblock.NewBasicBlock(8, bblock.RETURN_STMT, 26)
	BB9 := bblock.NewBasicBlock(9, bblock.RETURN_STMT, 28)
	BB10 := bblock.NewBasicBlock(10, bblock.RETURN_STMT, 30)
	BB11 := bblock.NewBasicBlock(11, bblock.RETURN_STMT, 32)
	BB12 := bblock.NewBasicBlock(12, bblock.RETURN_STMT, 34)
	BB13 := bblock.NewBasicBlock(13, bblock.RETURN_STMT, 36)
	BB14 := bblock.NewBasicBlock(14, bblock.RETURN_STMT, 38)
	BB15 := bblock.NewBasicBlock(15, bblock.RETURN_STMT, 40)
	BB16 := bblock.NewBasicBlock(16, bblock.RETURN_STMT, 42)

	// Function main.
	BB0.AddSuccessorBlock(BB1)

	// Function monthNumberToString.
	BB2.AddSuccessorBlock(BB3)
	BB3.AddSuccessorBlock(BB4, BB5, BB6, BB7, BB8, BB9, BB10, BB11, BB12, BB13, BB14, BB15, BB16)

	correctBasicBlocks := []*bblock.BasicBlock{
		BB0, BB1, BB2, BB3, BB4, BB5, BB6, BB7, BB8, BB9, BB10, BB11, BB12, BB13, BB14, BB15, BB16,
	}

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #8
0
func GetCyclomaticComplexityFunctionLevel(goFilePath string, goSrcFile []byte) (functions []*FunctionComplexity, err error) {
	blocks, err := bblock.GetBasicBlocksFromSourceCode(goFilePath, goSrcFile)
	if err != nil {
		return nil, err
	}

	for _, cfg := range cfgraph.GetControlFlowGraph(blocks) {
		complexity := GetCyclomaticComplexity(cfg)
		funcBlock := cfg.Root.Value.(*bblock.BasicBlock)
		functions = append(functions, &FunctionComplexity{
			Name:             funcBlock.FunctionName,
			SrcLine:          funcBlock.FunctionDeclLine,
			Complexity:       complexity,
			ControlFlowGraph: cfg,
			BasicBlocks:      blocks,
		})
	}
	return functions, nil
}
コード例 #9
0
func TestTypeSwitchBasicBlock(t *testing.T) {
	filePath := "./testcode/_typeswitch.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Error(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 8)
	BB1 := bblock.NewBasicBlock(1, bblock.SWITCH_STATEMENT, 14)
	BB2 := bblock.NewBasicBlock(2, bblock.CASE_CLAUSE, 17)
	BB3 := bblock.NewBasicBlock(3, bblock.CASE_CLAUSE, 19)
	BB4 := bblock.NewBasicBlock(4, bblock.CASE_CLAUSE, 21)
	BB5 := bblock.NewBasicBlock(5, bblock.CASE_CLAUSE, 23)
	BB6 := bblock.NewBasicBlock(6, bblock.CASE_CLAUSE, 25)
	BB7 := bblock.NewBasicBlock(7, bblock.RETURN_STMT, 28)

	BB0.AddSuccessorBlock(BB1)

	BB1.AddSuccessorBlock(BB2)
	BB1.AddSuccessorBlock(BB3)
	BB1.AddSuccessorBlock(BB4)
	BB1.AddSuccessorBlock(BB5)
	BB1.AddSuccessorBlock(BB6)

	BB2.AddSuccessorBlock(BB7)
	BB3.AddSuccessorBlock(BB7)
	BB4.AddSuccessorBlock(BB7)
	BB5.AddSuccessorBlock(BB7)
	BB6.AddSuccessorBlock(BB7)

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #10
0
func TestNestedSwitchBasicBlock(t *testing.T) {
	filePath := "./testcode/_nestedswitch.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 12)
	BB1 := bblock.NewBasicBlock(1, bblock.SWITCH_STATEMENT, 17)
	BB2 := bblock.NewBasicBlock(2, bblock.CASE_CLAUSE, 20)
	BB3 := bblock.NewBasicBlock(3, bblock.SWITCH_STATEMENT, 23)
	BB4 := bblock.NewBasicBlock(4, bblock.CASE_CLAUSE, 26)
	BB5 := bblock.NewBasicBlock(5, bblock.CASE_CLAUSE, 28)
	BB6 := bblock.NewBasicBlock(6, bblock.CASE_CLAUSE, 30)
	BB7 := bblock.NewBasicBlock(7, bblock.CASE_CLAUSE, 33)
	BB8 := bblock.NewBasicBlock(8, bblock.CASE_CLAUSE, 35)
	BB9 := bblock.NewBasicBlock(9, bblock.CASE_CLAUSE, 37)
	BB10 := bblock.NewBasicBlock(10, bblock.RETURN_STMT, 39)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #11
0
func TestSingleBasicBlock(t *testing.T) {
	filePath := "./testcode/_simple.go"
	sourceFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, sourceFile)
	if err != nil {
		t.Fatal(err)
	}

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

	BB0.AddSuccessorBlock(BB1)

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #12
0
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)
	}
}
コード例 #13
0
func TestNestedIfElseBasicBlock(t *testing.T) {
	filePath := "./testcode/_nestedifelse.go"
	srcFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	expectedBasicBlocks, err := bblock.GetBasicBlocksFromSourceCode(filePath, srcFile)
	if err != nil {
		t.Fatal(err)
	}

	BB0 := bblock.NewBasicBlock(0, bblock.FUNCTION_ENTRY, 11)
	BB1 := bblock.NewBasicBlock(1, bblock.IF_CONDITION, 14)
	BB2 := bblock.NewBasicBlock(2, bblock.IF_CONDITION, 18)
	BB3 := bblock.NewBasicBlock(3, bblock.ELSE_CONDITION, 21)
	BB4 := bblock.NewBasicBlock(4, bblock.ELSE_BODY, 25)
	BB5 := bblock.NewBasicBlock(5, bblock.ELSE_CONDITION, 26)
	BB6 := bblock.NewBasicBlock(6, bblock.ELSE_BODY, 30)
	BB7 := bblock.NewBasicBlock(7, bblock.RETURN_STMT, 34)

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

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

	if err := verifyBasicBlocks(expectedBasicBlocks, correctBasicBlocks); err != nil {
		t.Fatal(err)
	}
}
コード例 #14
0
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)
	}
}
コード例 #15
0
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)
	}
}