github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/client/driver/env/env_test.go (about)

     1  package env
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"sort"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/nomad/nomad/mock"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  )
    14  
    15  const (
    16  	// Node values that tests can rely on
    17  	metaKey   = "instance"
    18  	metaVal   = "t2-micro"
    19  	attrKey   = "arch"
    20  	attrVal   = "amd64"
    21  	nodeName  = "test node"
    22  	nodeClass = "test class"
    23  
    24  	// Environment variable values that tests can rely on
    25  	envOneKey = "NOMAD_IP"
    26  	envOneVal = "127.0.0.1"
    27  	envTwoKey = "NOMAD_PORT_WEB"
    28  	envTwoVal = ":80"
    29  )
    30  
    31  var (
    32  	// Networks that tests can rely on
    33  	networks = []*structs.NetworkResource{
    34  		&structs.NetworkResource{
    35  			IP:            "127.0.0.1",
    36  			ReservedPorts: []structs.Port{{"http", 80}},
    37  			DynamicPorts:  []structs.Port{{"https", 8080}},
    38  		},
    39  	}
    40  	portMap = map[string]int{
    41  		"https": 443,
    42  	}
    43  )
    44  
    45  func testTaskEnvironment() *TaskEnvironment {
    46  	n := mock.Node()
    47  	n.Attributes = map[string]string{
    48  		attrKey: attrVal,
    49  	}
    50  	n.Meta = map[string]string{
    51  		metaKey: metaVal,
    52  	}
    53  	n.Name = nodeName
    54  	n.NodeClass = nodeClass
    55  
    56  	envVars := map[string]string{
    57  		envOneKey: envOneVal,
    58  		envTwoKey: envTwoVal,
    59  	}
    60  	return NewTaskEnvironment(n).SetEnvvars(envVars).Build()
    61  }
    62  
    63  func TestEnvironment_ParseAndReplace_Env(t *testing.T) {
    64  	env := testTaskEnvironment()
    65  
    66  	input := []string{fmt.Sprintf(`"${%v}"!`, envOneKey), fmt.Sprintf("${%s}${%s}", envOneKey, envTwoKey)}
    67  	act := env.ParseAndReplace(input)
    68  	exp := []string{fmt.Sprintf(`"%s"!`, envOneVal), fmt.Sprintf("%s%s", envOneVal, envTwoVal)}
    69  
    70  	if !reflect.DeepEqual(act, exp) {
    71  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
    72  	}
    73  }
    74  
    75  func TestEnvironment_ParseAndReplace_Meta(t *testing.T) {
    76  	input := []string{fmt.Sprintf("${%v%v}", nodeMetaPrefix, metaKey)}
    77  	exp := []string{metaVal}
    78  	env := testTaskEnvironment()
    79  	act := env.ParseAndReplace(input)
    80  
    81  	if !reflect.DeepEqual(act, exp) {
    82  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
    83  	}
    84  }
    85  
    86  func TestEnvironment_ParseAndReplace_Attr(t *testing.T) {
    87  	input := []string{fmt.Sprintf("${%v%v}", nodeAttributePrefix, attrKey)}
    88  	exp := []string{attrVal}
    89  	env := testTaskEnvironment()
    90  	act := env.ParseAndReplace(input)
    91  
    92  	if !reflect.DeepEqual(act, exp) {
    93  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
    94  	}
    95  }
    96  
    97  func TestEnvironment_ParseAndReplace_Node(t *testing.T) {
    98  	input := []string{fmt.Sprintf("${%v}", nodeNameKey), fmt.Sprintf("${%v}", nodeClassKey)}
    99  	exp := []string{nodeName, nodeClass}
   100  	env := testTaskEnvironment()
   101  	act := env.ParseAndReplace(input)
   102  
   103  	if !reflect.DeepEqual(act, exp) {
   104  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
   105  	}
   106  }
   107  
   108  func TestEnvironment_ParseAndReplace_Mixed(t *testing.T) {
   109  	input := []string{
   110  		fmt.Sprintf("${%v}${%v%v}", nodeNameKey, nodeAttributePrefix, attrKey),
   111  		fmt.Sprintf("${%v}${%v%v}", nodeClassKey, nodeMetaPrefix, metaKey),
   112  		fmt.Sprintf("${%v}${%v}", envTwoKey, nodeClassKey),
   113  	}
   114  	exp := []string{
   115  		fmt.Sprintf("%v%v", nodeName, attrVal),
   116  		fmt.Sprintf("%v%v", nodeClass, metaVal),
   117  		fmt.Sprintf("%v%v", envTwoVal, nodeClass),
   118  	}
   119  	env := testTaskEnvironment()
   120  	act := env.ParseAndReplace(input)
   121  
   122  	if !reflect.DeepEqual(act, exp) {
   123  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
   124  	}
   125  }
   126  
   127  func TestEnvironment_ReplaceEnv_Mixed(t *testing.T) {
   128  	input := fmt.Sprintf("${%v}${%v%v}", nodeNameKey, nodeAttributePrefix, attrKey)
   129  	exp := fmt.Sprintf("%v%v", nodeName, attrVal)
   130  	env := testTaskEnvironment()
   131  	act := env.ReplaceEnv(input)
   132  
   133  	if act != exp {
   134  		t.Fatalf("ParseAndReplace(%v) returned %#v; want %#v", input, act, exp)
   135  	}
   136  }
   137  
   138  func TestEnvironment_AsList(t *testing.T) {
   139  	n := mock.Node()
   140  	env := NewTaskEnvironment(n).
   141  		SetNetworks(networks).
   142  		SetPortMap(portMap).
   143  		SetTaskGroupMeta(map[string]string{"foo": "bar", "baz": "bam"}).
   144  		SetTaskMeta(map[string]string{"foo": "baz"}).Build()
   145  
   146  	act := env.EnvList()
   147  	exp := []string{
   148  		"NOMAD_ADDR_http=127.0.0.1:80",
   149  		"NOMAD_PORT_http=80",
   150  		"NOMAD_IP_http=127.0.0.1",
   151  		"NOMAD_ADDR_https=127.0.0.1:443",
   152  		"NOMAD_PORT_https=443",
   153  		"NOMAD_IP_https=127.0.0.1",
   154  		"NOMAD_HOST_PORT_http=80",
   155  		"NOMAD_HOST_PORT_https=8080",
   156  		"NOMAD_META_FOO=baz",
   157  		"NOMAD_META_BAZ=bam",
   158  	}
   159  	sort.Strings(act)
   160  	sort.Strings(exp)
   161  	if !reflect.DeepEqual(act, exp) {
   162  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   163  	}
   164  }
   165  
   166  func TestEnvironment_VaultToken(t *testing.T) {
   167  	n := mock.Node()
   168  	env := NewTaskEnvironment(n).SetVaultToken("123", false).Build()
   169  
   170  	act := env.EnvList()
   171  	if len(act) != 0 {
   172  		t.Fatalf("Unexpected environment variables: %v", act)
   173  	}
   174  
   175  	env = env.SetVaultToken("123", true).Build()
   176  	act = env.EnvList()
   177  	exp := []string{"VAULT_TOKEN=123"}
   178  	if !reflect.DeepEqual(act, exp) {
   179  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   180  	}
   181  }
   182  
   183  func TestEnvironment_ClearEnvvars(t *testing.T) {
   184  	n := mock.Node()
   185  	env := NewTaskEnvironment(n).
   186  		SetNetworks(networks).
   187  		SetPortMap(portMap).
   188  		SetEnvvars(map[string]string{"foo": "baz", "bar": "bang"}).Build()
   189  
   190  	act := env.EnvList()
   191  	exp := []string{
   192  		"NOMAD_ADDR_http=127.0.0.1:80",
   193  		"NOMAD_PORT_http=80",
   194  		"NOMAD_IP_http=127.0.0.1",
   195  		"NOMAD_ADDR_https=127.0.0.1:443",
   196  		"NOMAD_PORT_https=443",
   197  		"NOMAD_IP_https=127.0.0.1",
   198  		"NOMAD_HOST_PORT_http=80",
   199  		"NOMAD_HOST_PORT_https=8080",
   200  		"bar=bang",
   201  		"foo=baz",
   202  	}
   203  	sort.Strings(act)
   204  	sort.Strings(exp)
   205  	if !reflect.DeepEqual(act, exp) {
   206  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   207  	}
   208  
   209  	// Clear the environent variables.
   210  	env.ClearEnvvars().Build()
   211  
   212  	act = env.EnvList()
   213  	exp = []string{
   214  		"NOMAD_ADDR_http=127.0.0.1:80",
   215  		"NOMAD_PORT_http=80",
   216  		"NOMAD_IP_http=127.0.0.1",
   217  		"NOMAD_ADDR_https=127.0.0.1:443",
   218  		"NOMAD_PORT_https=443",
   219  		"NOMAD_IP_https=127.0.0.1",
   220  		"NOMAD_HOST_PORT_https=8080",
   221  		"NOMAD_HOST_PORT_http=80",
   222  	}
   223  	sort.Strings(act)
   224  	sort.Strings(exp)
   225  	if !reflect.DeepEqual(act, exp) {
   226  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   227  	}
   228  }
   229  
   230  func TestEnvironment_Interprolate(t *testing.T) {
   231  	env := testTaskEnvironment().
   232  		SetEnvvars(map[string]string{"test": "${node.class}", "test2": "${attr.arch}"}).
   233  		Build()
   234  
   235  	act := env.EnvList()
   236  	exp := []string{fmt.Sprintf("test=%s", nodeClass), fmt.Sprintf("test2=%s", attrVal)}
   237  	sort.Strings(act)
   238  	sort.Strings(exp)
   239  	if !reflect.DeepEqual(act, exp) {
   240  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   241  	}
   242  }
   243  
   244  func TestEnvironment_AppendHostEnvVars(t *testing.T) {
   245  	host := os.Environ()
   246  	if len(host) < 2 {
   247  		t.Skip("No host environment variables. Can't test")
   248  	}
   249  	skip := strings.Split(host[0], "=")[0]
   250  	env := testTaskEnvironment().
   251  		AppendHostEnvvars([]string{skip}).
   252  		Build()
   253  
   254  	act := env.EnvMap()
   255  	if len(act) < 1 {
   256  		t.Fatalf("Host environment variables not properly set")
   257  	}
   258  	if _, ok := act[skip]; ok {
   259  		t.Fatalf("Didn't filter environment variable %q", skip)
   260  	}
   261  }
   262  
   263  func TestEnvironment_MetaPrecedence(t *testing.T) {
   264  	n := mock.Node()
   265  	env := NewTaskEnvironment(n).
   266  		SetJobMeta(map[string]string{"foo": "job", "bar": "job", "baz": "job"}).
   267  		SetTaskGroupMeta(map[string]string{"foo": "tg", "bar": "tg"}).
   268  		SetTaskMeta(map[string]string{"foo": "task"}).Build()
   269  
   270  	act := env.EnvList()
   271  	exp := []string{
   272  		"NOMAD_META_FOO=task",
   273  		"NOMAD_META_BAR=tg",
   274  		"NOMAD_META_BAZ=job",
   275  	}
   276  	sort.Strings(act)
   277  	sort.Strings(exp)
   278  	if !reflect.DeepEqual(act, exp) {
   279  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   280  	}
   281  }