github.com/Azure/draft-classic@v0.16.0/cmd/draft/plugin_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/spf13/cobra"
    12  
    13  	"github.com/Azure/draft/pkg/draft/draftpath"
    14  )
    15  
    16  func TestManuallyProcessArgs(t *testing.T) {
    17  	input := []string{
    18  		"--debug",
    19  		"--foo", "bar",
    20  		"--host", "example.com",
    21  		"--kube-context", "test1",
    22  		"--home=/tmp",
    23  		"command",
    24  	}
    25  
    26  	expectKnown := []string{
    27  		"--debug", "--host", "example.com", "--kube-context", "test1", "--home=/tmp",
    28  	}
    29  
    30  	expectUnknown := []string{
    31  		"--foo", "bar", "command",
    32  	}
    33  
    34  	known, unknown := manuallyProcessArgs(input)
    35  
    36  	for i, k := range known {
    37  		if k != expectKnown[i] {
    38  			t.Errorf("expected known flag %d to be %q, got %q", i, expectKnown[i], k)
    39  		}
    40  	}
    41  	for i, k := range unknown {
    42  		if k != expectUnknown[i] {
    43  			t.Errorf("expected unknown flag %d to be %q, got %q", i, expectUnknown[i], k)
    44  		}
    45  	}
    46  
    47  }
    48  
    49  func TestLoadPlugins(t *testing.T) {
    50  	// Set draft home to point to testdata
    51  	old := draftHome
    52  	draftHome = filepath.Join("testdata", "drafthome")
    53  	resetEnvVars := unsetEnvVars()
    54  	defer func() {
    55  		draftHome = old
    56  		resetEnvVars()
    57  	}()
    58  	ph := draftpath.Home(homePath())
    59  
    60  	out := bytes.NewBuffer(nil)
    61  	in := bytes.NewBuffer(nil)
    62  	cmd := &cobra.Command{}
    63  	// add `--home` flag to cmd (which is what cmd.Parent() resolves to for the loaded plugin)
    64  	// so that it can be overridden in tests below
    65  	p := cmd.PersistentFlags()
    66  	p.StringVar(&draftHome, "home", draftHome, "location of your Draft config. Overrides $DRAFT_HOME")
    67  
    68  	loadPlugins(cmd, ph, out, in)
    69  
    70  	envs := strings.Join([]string{
    71  		"fullenv",
    72  		ph.Plugins() + "/fullenv",
    73  		ph.Plugins(),
    74  		ph.String(),
    75  		os.Args[0],
    76  	}, "\n")
    77  
    78  	// testVariant represents an expect and args variant of a given test/plugin
    79  	type testVariant struct {
    80  		expect string
    81  		args   []string
    82  	}
    83  
    84  	// Test that the YAML file was correctly converted to a command.
    85  	tests := []struct {
    86  		use      string
    87  		short    string
    88  		long     string
    89  		variants []testVariant
    90  	}{
    91  		{"args", "echo args", "This echos args", []testVariant{
    92  			{expect: "-a -b -c\n", args: []string{"-a", "-b", "-c"}},
    93  		}},
    94  		{"echo", "echo stuff", "This echos stuff", []testVariant{
    95  			{expect: "hello\n", args: []string{}},
    96  		}},
    97  		{"fullenv", "show env vars", "show all env vars", []testVariant{
    98  			{expect: envs + "\n", args: []string{}},
    99  		}},
   100  		{"home", "home stuff", "show DRAFT_HOME", []testVariant{
   101  			{expect: ph.String() + "\n", args: []string{}},
   102  			{expect: "/my/draft/home\n", args: []string{"--home", "/my/draft/home"}},
   103  		}},
   104  	}
   105  
   106  	plugins := cmd.Commands()
   107  
   108  	if len(plugins) != len(tests) {
   109  		t.Fatalf("Expected %d plugins, got %d", len(tests), len(plugins))
   110  	}
   111  
   112  	for i := 0; i < len(plugins); i++ {
   113  		tt := tests[i]
   114  		pp := plugins[i]
   115  		if pp.Use != tt.use {
   116  			t.Errorf("%d: Expected Use=%q, got %q", i, tt.use, pp.Use)
   117  		}
   118  		if pp.Short != tt.short {
   119  			t.Errorf("%d: Expected Use=%q, got %q", i, tt.short, pp.Short)
   120  		}
   121  		if pp.Long != tt.long {
   122  			t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pp.Long)
   123  		}
   124  
   125  		for _, variant := range tt.variants {
   126  			out.Reset()
   127  			// Currently, plugins assume a Linux subsystem. Skip the execution
   128  			// tests until this is fixed
   129  			if runtime.GOOS != "windows" {
   130  				if err := pp.RunE(pp, variant.args); err != nil {
   131  					t.Errorf("Error running %s: %s", tt.use, err)
   132  				}
   133  				if out.String() != variant.expect {
   134  					t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, variant.expect, out.String())
   135  				}
   136  			}
   137  		}
   138  	}
   139  }
   140  
   141  func TestSetupEnv(t *testing.T) {
   142  	name := "pequod"
   143  	ver := "0.1.0"
   144  	ph := draftpath.Home(filepath.Join("testdata", "drafthome"))
   145  	base := filepath.Join(ph.Plugins(), name)
   146  	plugdirs := ph.Plugins()
   147  	flagDebug = true
   148  	defer func() {
   149  		flagDebug = false
   150  	}()
   151  
   152  	resetEnvVars := unsetEnvVars()
   153  	defer resetEnvVars()
   154  	setupPluginEnv(name, ver, base, plugdirs, ph)
   155  	for _, tt := range []struct {
   156  		name   string
   157  		expect string
   158  	}{
   159  		{"DRAFT_PLUGIN_NAME", name},
   160  		{"DRAFT_PLUGIN_VERSION", ver},
   161  		{"DRAFT_PLUGIN_DIR", base},
   162  		{"DRAFT_PLUGIN", ph.Plugins()},
   163  		{"DRAFT_DEBUG", "1"},
   164  		{"DRAFT_HOME", ph.String()},
   165  		{"DRAFT_PACKS_HOME", ph.Packs()},
   166  		{"HELM_HOST", tillerHost},
   167  	} {
   168  		if got := os.Getenv(tt.name); got != tt.expect {
   169  			t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got)
   170  		}
   171  	}
   172  }
   173  
   174  func unsetEnvVars() func() {
   175  	envs := []string{"DRAFT_PLUGIN_NAME", "DRAFT_PLUGIN_DIR", "DRAFT_PLUGIN", "DRAFT_DEBUG", "DRAFT_HOME", "DRAFT_PACKS_HOME", "DRAFT_HOST"}
   176  
   177  	resetVals := map[string]string{}
   178  
   179  	for _, env := range envs {
   180  		val := os.Getenv(env)
   181  		resetVals[env] = val
   182  		if err := os.Unsetenv(env); err != nil {
   183  			debug("error unsetting env %v: %v", env, err)
   184  		}
   185  	}
   186  
   187  	return func() {
   188  		for env, val := range resetVals {
   189  			if err := os.Setenv(env, val); err != nil {
   190  				debug("error setting env variable %s to %s: %s", env, val, err)
   191  			}
   192  		}
   193  	}
   194  }