scripts/testConverage/testConverge.go (216 lines of code) (raw):
package main
import (
"bufio"
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
)
var TerraformProviderPath string
type Node struct {
name string
child []*Node
}
func scanDataTest(fileName string) *Node {
file, _ := os.Open(fileName)
fset := token.NewFileSet()
node, _ := parser.ParseFile(fset, "", file, parser.ParseComments)
var root *ast.KeyValueExpr
ast.Inspect(node, func(n ast.Node) bool {
if returnStmt, ok := n.(*ast.ReturnStmt); ok {
results := returnStmt.Results
if len(results) == 0 {
return true
}
unaryExpr := results[0]
if unaryExpr, ok := unaryExpr.(*ast.UnaryExpr); ok {
if x, ok := unaryExpr.X.(*ast.CompositeLit); ok {
elts := x.Elts
for _, kvexpr := range elts {
if Exprkv, ok := kvexpr.(*ast.KeyValueExpr); ok {
if Exprk, ok := Exprkv.Key.(*ast.Ident); ok && Exprk.Name == "Schema" {
root = Exprkv
}
}
}
}
}
}
return true
})
rootNode := new(Node)
rootNode.child = make([]*Node, 0)
dfs(root, rootNode)
return rootNode
}
func dfs(left *ast.KeyValueExpr, leftNode *Node) {
LeftValue, _ := left.Value.(*ast.CompositeLit)
LeftElts := &LeftValue.Elts
for _, leftAttribute := range *LeftElts {
leftAttribute, _ := leftAttribute.(*ast.KeyValueExpr)
//判断leftAttribute是文件节点还是目录节点
var ifSchema bool
leftKey, _ := leftAttribute.Key.(*ast.BasicLit)
leftAttributeValue, ok := leftAttribute.Value.(*ast.CompositeLit)
if ok {
elts := leftAttributeValue.Elts
for i := 0; i < len(elts); i++ {
if kv, ok := elts[i].(*ast.KeyValueExpr); ok {
if k, ok := kv.Key.(*ast.Ident); ok && k.Name == "Elem" {
ifSchema = true
break
}
}
}
}
childNode := new(Node)
childNode.name = strings.TrimSuffix(strings.TrimPrefix(leftKey.Value, "\""), "\"")
childNode.child = make([]*Node, 0)
leftNode.child = append(leftNode.child, childNode)
//如果是目录类型
if ifSchema {
var leftChild *ast.KeyValueExpr
//提取出左孩子
leftAttributeValue, _ := leftAttribute.Value.(*ast.CompositeLit)
elts := leftAttributeValue.Elts
for _, kvExpr := range elts {
kvExpr := kvExpr.(*ast.KeyValueExpr)
if kExpr, ok := kvExpr.Key.(*ast.Ident); ok && kExpr.Name == "Elem" {
kExprValue := kvExpr.Value
if unaryExpr, ok := kExprValue.(*ast.UnaryExpr); ok {
x := unaryExpr.X.(*ast.CompositeLit)
for _, e := range x.Elts {
if leftchild, ok := e.(*ast.KeyValueExpr); ok {
if leftchildKey, ok := leftchild.Key.(*ast.Ident); ok && leftchildKey.Name == "Schema" {
leftChild = leftchild
}
}
}
}
}
}
if leftChild != nil {
dfs(leftChild, childNode)
}
}
}
}
func hasTested(filename string, dataOut []string) int {
inputFile, _ := os.Open(filename)
defer inputFile.Close()
// 使用bufio.Scanner逐行读取文件
scanner := bufio.NewScanner(inputFile)
mp := make(map[string]interface{})
for scanner.Scan() {
line := scanner.Text()
for _, s := range dataOut {
if strings.Contains(line, s) {
mp[s] = struct{}{}
}
}
}
res := 0
for _, s := range dataOut {
_, ok := mp[s]
if ok {
res++
}
}
return res
}
func main() {
if len(os.Args) < 2 {
fmt.Println("请传入一个参数:terraform项目地址")
os.Exit(1)
}
TerraformProviderPath = os.Args[1]
dirname := TerraformProviderPath + "/alibabacloudstack" // your directory containing Go source files
fmt.Println(dirname)
filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
name := info.Name()
if !info.IsDir() && !strings.HasSuffix(path, "test.go") && strings.HasSuffix(path, "go") { // process only Go files
if strings.HasPrefix(name, "data") {
testFilename := strings.TrimSuffix(path, ".go")
testFilename = testFilename + "_test.go"
_, err := os.Stat(testFilename)
if err != nil {
fmt.Printf("[0.00%%] %s: 缺失测试文件\n", name)
return nil
}
out := strings.TrimSuffix(path, ".go")
outstrs := strings.Split(out, "_")
probablyOut := make([]string, 0)
probablyOut = append(probablyOut, outstrs[len(outstrs)-1])
pout2 := strings.TrimSuffix(strings.TrimPrefix(name, "data_source_apsarastack_"), ".go")
probablyOut = append(probablyOut, pout2)
pout3 := outstrs[len(outstrs)-2] + "_" + outstrs[len(outstrs)-1]
probablyOut = append(probablyOut, pout3)
root := scanDataTest(path)
count := 0
dataOut := make([]string, 0)
for _, attribute := range root.child {
var lock bool
for _, s := range probablyOut {
if attribute.name == s {
lock = true
}
}
if len(attribute.child) != 0 && lock {
count = len(attribute.child)
for _, child := range attribute.child {
dataOut = append(dataOut, child.name)
}
}
}
if count == 0 {
count = len(root.child)
for _, child := range root.child {
dataOut = append(dataOut, child.name)
}
}
if count != 0 {
tested := hasTested(testFilename, dataOut)
percentage := (float64(tested) / float64(count)) * 100
fmt.Printf("[%.2f%%] %s: %d / %d\n", percentage, name, tested, count)
}
}
}
return nil
})
fmt.Println()
// ans := true
filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
name := info.Name()
if !info.IsDir() && !strings.HasSuffix(path, "test.go") && strings.HasSuffix(path, "go") { // process only Go files
if strings.HasPrefix(name, "resource") {
testFilename := strings.TrimSuffix(path, ".go")
testFilename = testFilename + "_test.go"
_, err := os.Stat(testFilename)
if err != nil {
fmt.Printf("[0.00%%] %s: 缺失测试文件\n", name)
return nil
}
root := scanDataTest(path)
count := 0
dataOut := make([]string, 0)
count = len(root.child)
for _, child := range root.child {
dataOut = append(dataOut, child.name)
}
if count != 0 {
tested := hasTested(testFilename, dataOut)
percentage := (float64(tested) / float64(count)) * 100
fmt.Printf("[%.2f%%] %s: %d / %d\n", percentage, name, tested, count)
if tested != count {
// ans = false
}
}
}
}
return nil
})
fmt.Println()
}