github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/grub/echo_test.go (about) 1 // Copyright 2017-2020 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package grub 6 7 import ( 8 "bytes" 9 "context" 10 "flag" 11 "fmt" 12 "io/ioutil" 13 "net/url" 14 "os" 15 "os/exec" 16 "path/filepath" 17 "strings" 18 "testing" 19 20 "github.com/u-root/u-root/pkg/curl" 21 ) 22 23 var update = flag.Bool("run-bash", false, "run bash and update golden file") 24 25 // TestMain is used to warp a go utility in the same test binary 26 // when the environment variable BE_ECHO is set to 1, the binary will echo its 27 // parameters using the %#v format string, so the parameters are escaped and can 28 // be recovered. 29 func TestMain(m *testing.M) { 30 if os.Getenv("BE_ECHO") == "1" { 31 fmt.Printf("echo:%#v\n", os.Args[1:]) 32 return 33 } // call flag.Parse() here if TestMain uses flags 34 os.Exit(m.Run()) 35 } 36 37 // TestHelperEcho tests the echo wrapper in TestMain 38 func TestHelperEcho(t *testing.T) { 39 cmd := exec.Command(os.Args[0], "echothis") 40 cmd.Env = append(os.Environ(), "BE_ECHO=1") 41 out, err := cmd.Output() 42 t.Logf("%q\n", out) 43 if err != nil { 44 t.Fatalf("process ran with err %v", err) 45 } 46 want := "echo:[]string{\"echothis\"}\n" 47 if string(out) != want { 48 t.Fatalf("wrong process output got `%s` want `%s`", out, want) 49 } 50 } 51 52 // TestBashWrapper tests that the "./testdata/bash_wrapper.sh" works as expected 53 // bash_wrapper.sh is a script that replace the internal command echo with its 54 // first argument and source its second argument. 55 // The goal is to be able to run grub's tests scripts, see TestGrubTests 56 func TestBashWrapper(t *testing.T) { 57 if !*update { 58 t.Skip("use -run-bash flag to run this") 59 } 60 cmd := exec.Command("./testdata/bash_wrapper.sh", os.Args[0], "./testdata/test_bash_wrapper.sh") 61 cmd.Env = append(os.Environ(), "BE_ECHO=1") 62 out, err := cmd.Output() 63 t.Logf("%q\n", out) 64 if err != nil { 65 t.Fatalf("process ran with err %v", err) 66 } 67 want := "echo:[]string{\"param1\", \"param2\"}\n" 68 if string(out) != want { 69 t.Fatalf("wrong process output got `%s` want `%s`", out, want) 70 } 71 } 72 73 // TestGrubTests run tests imported from grub source to check our parser 74 // grub has tests in for of scripts that are run both by grub and bash, they 75 // mostly use echo and the test then compare the output of both runs. 76 // In our case we don't want to compare the output of echo, but get the token 77 // passed to echo. So we replace the echo command in bash with the wrapper (see 78 // above). We can then compare the bash output to our parser output. 79 // Also to avoid keeping the dependency on bash, the output are saved in the 80 // golden files. One must run the test with '-run-bash' to update the golden 81 // files in case new tests are added or the echo format is changed. 82 func TestGrubTests(t *testing.T) { 83 files, err := filepath.Glob("testdata/*.in") 84 if err != nil { 85 t.Fatal(err) 86 } 87 for _, file := range files { 88 name := strings.TrimSuffix(filepath.Base(file), ".in") 89 t.Run(name, func(t *testing.T) { 90 golden := strings.TrimSuffix(file, ".in") + ".out" 91 var out []byte 92 if *update { 93 cmd := exec.Command("./testdata/bash_wrapper.sh", os.Args[0], file) 94 cmd.Env = append(os.Environ(), "BE_ECHO=1") 95 out, err = cmd.Output() 96 //t.Logf("%s\n", out) 97 if err != nil { 98 t.Fatalf("process ran with err %v", err) 99 } 100 } else { 101 out, err = ioutil.ReadFile(golden) 102 if err != nil { 103 t.Fatalf("error loading file `%s`, %v", golden, err) 104 } 105 } 106 // parse with our parser and compare 107 var b bytes.Buffer 108 wd := &url.URL{ 109 Scheme: "file", 110 Path: "./testdata", 111 } 112 c := newParser(wd, curl.DefaultSchemes) 113 c.W = &b 114 115 script, err := ioutil.ReadFile(file) 116 if err != nil { 117 t.Fatalf("error loading file `%s`, %v", file, err) 118 } 119 err = c.append(context.Background(), string(script)) 120 if err != nil { 121 t.Fatalf("error parsing file `%s`, %v", file, err) 122 } 123 124 if b.String() != string(out) { 125 t.Fatalf("wrong script parsing output got `%s` want `%s`", b.String(), string(out)) 126 } 127 // update/create golden file on success 128 if *update { 129 err := ioutil.WriteFile(golden, out, 0644) 130 if err != nil { 131 t.Fatalf("error writing file `%s`, %v", file, err) 132 } 133 } 134 }) 135 136 } 137 }