github.com/RyanSiu1995/gcb-visualizer@v1.0.2-0.20211121083050-f618fa372726/internal/utils/cloudbuild_test.go (about)

     1  package util
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"gopkg.in/yaml.v2"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  
    14  	graphviz "github.com/goccy/go-graphviz"
    15  	"github.com/goccy/go-graphviz/cgraph"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  var supportedFormat = []string{".yaml", ".yml", ".json"}
    20  
    21  type result struct {
    22  	Nodes []string `yaml:"nodes"`
    23  	Edges []struct {
    24  		From string `yaml:"from"`
    25  		To   string `yaml:"to"`
    26  	} `yaml:"edges"`
    27  }
    28  
    29  func init() {
    30  	// Change the current working dir to root dir
    31  	os.Chdir("../../")
    32  }
    33  
    34  func TestYamlToDAG(t *testing.T) {
    35  	var testFiles []string
    36  	cloudbuildPath := filepath.Join("./", "test", "fixtures", "cloudbuild")
    37  	err := filepath.Walk(cloudbuildPath, func(path string, info os.FileInfo, err error) error {
    38  		if Contains(supportedFormat, filepath.Ext(path)) {
    39  			testFiles = append(testFiles, path)
    40  		}
    41  		return nil
    42  	})
    43  	if err != nil {
    44  		assert.Error(t, err)
    45  	}
    46  	for _, file := range testFiles {
    47  		t.Run(fmt.Sprintf("TestYamlToDAG:%s", file), func(t *testing.T) {
    48  			cloudBuild, err := ParseYaml(file)
    49  			assert.Empty(t, err)
    50  			graph := BuildStepsToDAG(cloudBuild.Steps)
    51  			assert.Empty(t, err)
    52  
    53  			expectedResult := getExpectedResult(file)
    54  			isExpectedGraph(t, expectedResult, graph)
    55  		})
    56  	}
    57  }
    58  
    59  func getExpectedResult(filePath string) *result {
    60  	ext := path.Ext(filePath)
    61  	_, filename := filepath.Split(filePath)
    62  	yamlFile := filename[0:len(filename)-len(ext)] + ".graph.yaml"
    63  	fullPath := filepath.Join("./", "test", "fixtures", "graph", yamlFile)
    64  	resultObj := result{}
    65  	buf, _ := ioutil.ReadFile(fullPath)
    66  	yaml.Unmarshal(buf, &resultObj)
    67  	return &resultObj
    68  }
    69  
    70  func isExpectedGraph(t *testing.T, expected *result, actual *cgraph.Graph) {
    71  	assert.Equalf(t, len(expected.Nodes), actual.NumberNodes(), "Should have the same number of nodes.")
    72  	for _, node := range expected.Nodes {
    73  		n, err := actual.Node(node)
    74  		assert.Empty(t, err)
    75  		assert.NotEmptyf(t, n, "Expected Node %s but not found in generated graph", node)
    76  	}
    77  	assert.Equalf(t, len(expected.Edges), actual.NumberEdges(), "Should have the same number of edges.")
    78  	// FIXME This may not be too good to compare the edge. We may need a better way to compare them programmatically
    79  	var buf bytes.Buffer
    80  	g := graphviz.New()
    81  	g.Render(actual, "dot", &buf)
    82  	actualOutput := buf.String()
    83  	for _, edge := range expected.Edges {
    84  		edge.From = sanitizeDotString(edge.From)
    85  		edge.To = sanitizeDotString(edge.To)
    86  		edgeInDot := fmt.Sprintf("%s -> %s", edge.From, edge.To)
    87  		assert.Truef(t, strings.Contains(actualOutput, edgeInDot), "Should contain the edge \"%s\"\n Actual: %s", edgeInDot, actualOutput)
    88  	}
    89  }
    90  
    91  func sanitizeDotString(s string) string {
    92  	if strings.Contains(s, " ") {
    93  		return fmt.Sprintf("\"%s\"", s)
    94  	}
    95  	return s
    96  }