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  }