github.com/vshn/k8ify@v1.1.2-0.20240502214202-6c9ed3ef0bf4/golden_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"regexp"
    12  	"runtime"
    13  	"testing"
    14  
    15  	"github.com/sirupsen/logrus"
    16  	"gopkg.in/yaml.v3"
    17  )
    18  
    19  const (
    20  	GOLDEN_PATH = "tests/golden"
    21  )
    22  
    23  var (
    24  	ext = regexp.MustCompile(`\.ya?ml$`)
    25  )
    26  
    27  type Instance struct {
    28  	Environments map[string]Environment `yaml:"environments"`
    29  }
    30  
    31  type Environment struct {
    32  	Refs   []string          `yaml:"refs"`
    33  	Vars   map[string]string `yaml:"vars"`
    34  	Params []string          `yaml:"params"`
    35  }
    36  
    37  func init() {
    38  	logrus.SetOutput(io.Discard)
    39  }
    40  
    41  // GetRefs returns the list of refs defined in the test spec, or just an empty
    42  // string if no refs have been defined.
    43  func (e *Environment) GetRefs() []string {
    44  	if len(e.Refs) < 1 {
    45  		return []string{""}
    46  	}
    47  
    48  	return e.Refs
    49  }
    50  
    51  func TestGolden(t *testing.T) {
    52  	instances := findInstances()
    53  	for _, i := range instances {
    54  		t.Run(i, func(t *testing.T) {
    55  			testInstance(t, i)
    56  		})
    57  	}
    58  }
    59  
    60  func findInstances() []string {
    61  	c, err := os.ReadDir(GOLDEN_PATH)
    62  	check(err, "finding instances")
    63  
    64  	instances := make([]string, 0)
    65  	ext := regexp.MustCompile(`\.ya?ml$`)
    66  	for _, e := range c {
    67  		if ext.MatchString(e.Name()) && !e.IsDir() {
    68  			instances = append(instances, e.Name())
    69  		}
    70  	}
    71  
    72  	return instances
    73  }
    74  
    75  func testInstance(t *testing.T, instanceFile string) {
    76  	f, err := os.Open(filepath.Join(GOLDEN_PATH, instanceFile))
    77  	check(err, "reading golden test definition")
    78  
    79  	instance := ext.ReplaceAllString(instanceFile, "")
    80  	i := Instance{}
    81  	check(yaml.NewDecoder(f).Decode(&i), "decoding golden test definition")
    82  
    83  	old, err := os.Getwd()
    84  	check(err, "determining current working directory")
    85  
    86  	root := filepath.Join(GOLDEN_PATH, instance)
    87  	check(os.Chdir(root), "changing working directory")
    88  
    89  	for name, env := range i.Environments {
    90  		t.Run(name, func(t *testing.T) {
    91  			testEnvironment(t, name, env)
    92  		})
    93  	}
    94  
    95  	check(os.Chdir(old), "resetting working directory")
    96  }
    97  
    98  func testEnvironment(t *testing.T, envName string, env Environment) {
    99  	for k, v := range env.Vars {
   100  		t.Setenv(k, v)
   101  	}
   102  
   103  	for _, ref := range env.GetRefs() {
   104  		t.Run(ref, func(t *testing.T) {
   105  			args := []string{"k8ify", envName, ref}
   106  			args = append(args, env.Params...)
   107  			fmt.Printf("Running %v", args)
   108  			var logs bytes.Buffer
   109  			logrus.SetOutput(&logs)
   110  			if c := Main(args); c != 0 {
   111  				t.Errorf("k8ify exited with code %v while compiling with args '%v'\n%s", c, args, logs.String())
   112  			}
   113  
   114  			cmd := exec.Command("git", "diff", "--exit-code", "--minimal", "--", "manifests/")
   115  			if out, err := cmd.CombinedOutput(); err != nil {
   116  				t.Errorf("error from git diff: %v", err)
   117  				fmt.Println(string(out))
   118  			}
   119  		})
   120  	}
   121  }
   122  
   123  func check(err error, context string) {
   124  	if err != nil {
   125  		_, cf, cl, _ := runtime.Caller(0)
   126  		cf = filepath.Base(cf)
   127  		log.Fatalf("%s:%d: Error %s: %v", cf, cl, context, err)
   128  	}
   129  }