github.com/stevenmatthewt/agent@v3.5.4+incompatible/bootstrap/integration/plugin_integration_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "runtime" 10 "strings" 11 "testing" 12 13 "github.com/buildkite/agent/bootstrap/shell" 14 "github.com/buildkite/bintest" 15 ) 16 17 func TestRunningPlugins(t *testing.T) { 18 t.Parallel() 19 20 tester, err := NewBootstrapTester() 21 if err != nil { 22 t.Fatal(err) 23 } 24 defer tester.Close() 25 26 pluginMock := tester.MustMock(t, "my-plugin") 27 28 var p *testPlugin 29 30 if runtime.GOOS == "windows" { 31 p = createTestPlugin(t, map[string][]string{ 32 "environment.bat": []string{ 33 "@echo off", 34 "set LLAMAS_ROCK=absolutely", 35 pluginMock.Path + " testing", 36 }, 37 }) 38 } else { 39 p = createTestPlugin(t, map[string][]string{ 40 "environment": []string{ 41 "#!/bin/bash", 42 "export LLAMAS_ROCK=absolutely", 43 pluginMock.Path + " testing", 44 }, 45 }) 46 } 47 48 json, err := p.ToJSON() 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 env := []string{ 54 `MY_CUSTOM_ENV=1`, 55 `BUILDKITE_PLUGINS=` + json, 56 } 57 58 pluginMock.Expect("testing").Once().AndCallFunc(func(c *bintest.Call) { 59 if err := bintest.ExpectEnv(t, c.Env, `MY_CUSTOM_ENV=1`, `LLAMAS_ROCK=absolutely`); err != nil { 60 fmt.Fprintf(c.Stderr, "%v\n", err) 61 c.Exit(1) 62 } 63 c.Exit(0) 64 }) 65 66 tester.ExpectGlobalHook("command").Once().AndExitWith(0).AndCallFunc(func(c *bintest.Call) { 67 if err := bintest.ExpectEnv(t, c.Env, `MY_CUSTOM_ENV=1`, `LLAMAS_ROCK=absolutely`); err != nil { 68 fmt.Fprintf(c.Stderr, "%v\n", err) 69 c.Exit(1) 70 } 71 c.Exit(0) 72 }) 73 74 tester.RunAndCheck(t, env...) 75 } 76 77 func TestExitCodesPropagateOutFromPlugins(t *testing.T) { 78 t.Parallel() 79 80 tester, err := NewBootstrapTester() 81 if err != nil { 82 t.Fatal(err) 83 } 84 defer tester.Close() 85 86 var p *testPlugin 87 88 if runtime.GOOS == "windows" { 89 p = createTestPlugin(t, map[string][]string{ 90 "environment.bat": []string{ 91 "@echo off", 92 "exit 5", 93 }, 94 }) 95 } else { 96 p = createTestPlugin(t, map[string][]string{ 97 "environment": []string{ 98 "#!/bin/bash", 99 "exit 5", 100 }, 101 }) 102 } 103 104 json, err := p.ToJSON() 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 env := []string{ 110 `BUILDKITE_PLUGINS=` + json, 111 } 112 113 err = tester.Run(t, env...) 114 if err == nil { 115 t.Fatal("Expected the bootstrap to fail") 116 } 117 118 exitCode := shell.GetExitCode(err) 119 120 if exitCode != 5 { 121 t.Fatalf("Expected an exit code of %d, got %d", 5, exitCode) 122 } 123 124 tester.CheckMocks(t) 125 } 126 127 func TestMalformedPluginNamesDontCrashBootstrap(t *testing.T) { 128 t.Parallel() 129 130 tester, err := NewBootstrapTester() 131 if err != nil { 132 t.Fatal(err) 133 } 134 defer tester.Close() 135 136 env := []string{ 137 `BUILDKITE_PLUGINS=["sdgmdgn.@$!sdf,asdf#llamas"]`, 138 } 139 140 if err = tester.Run(t, env...); err == nil { 141 t.Fatal("Expected the bootstrap to fail") 142 } 143 144 tester.CheckMocks(t) 145 } 146 147 type testPlugin struct { 148 *gitRepository 149 } 150 151 func createTestPlugin(t *testing.T, hooks map[string][]string) *testPlugin { 152 repo, err := newGitRepository() 153 if err != nil { 154 t.Fatal(err) 155 } 156 157 if err := os.MkdirAll(filepath.Join(repo.Path, "hooks"), 0700); err != nil { 158 t.Fatal(err) 159 } 160 161 for hook, lines := range hooks { 162 data := []byte(strings.Join(lines, "\n")) 163 if err := ioutil.WriteFile(filepath.Join(repo.Path, "hooks", hook), data, 0600); err != nil { 164 t.Fatal(err) 165 } 166 } 167 168 if err = repo.Add("."); err != nil { 169 t.Fatal(err) 170 } 171 172 if err = repo.Commit("Initial commit of plugin hooks"); err != nil { 173 t.Fatal(err) 174 } 175 176 return &testPlugin{repo} 177 } 178 179 func (tp *testPlugin) ToJSON() (string, error) { 180 commitHash, err := tp.RevParse("HEAD") 181 if err != nil { 182 return "", err 183 } 184 normalizedPath := strings.TrimPrefix(strings.Replace(tp.Path, "\\", "/", -1), "/") 185 186 var p = []interface{}{map[string]interface{}{ 187 fmt.Sprintf(`file:///%s#%s`, normalizedPath, strings.TrimSpace(commitHash)): map[string]string{ 188 "settings": "blah", 189 }, 190 }} 191 b, err := json.Marshal(&p) 192 if err != nil { 193 return "", err 194 } 195 return string(b), nil 196 }