github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/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, false).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, false).
   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_ClearEnvvars(t *testing.T) {
   167  	n := mock.Node()
   168  	env := NewTaskEnvironment(n, false).
   169  		SetNetworks(networks).
   170  		SetPortMap(portMap).
   171  		SetEnvvars(map[string]string{"foo": "baz", "bar": "bang"}).Build()
   172  
   173  	act := env.EnvList()
   174  	exp := []string{
   175  		"NOMAD_ADDR_http=127.0.0.1:80",
   176  		"NOMAD_PORT_http=80",
   177  		"NOMAD_IP_http=127.0.0.1",
   178  		"NOMAD_ADDR_https=127.0.0.1:443",
   179  		"NOMAD_PORT_https=443",
   180  		"NOMAD_IP_https=127.0.0.1",
   181  		"NOMAD_HOST_PORT_http=80",
   182  		"NOMAD_HOST_PORT_https=8080",
   183  		"bar=bang",
   184  		"foo=baz",
   185  	}
   186  	sort.Strings(act)
   187  	sort.Strings(exp)
   188  	if !reflect.DeepEqual(act, exp) {
   189  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   190  	}
   191  
   192  	// Clear the environent variables.
   193  	env.ClearEnvvars().Build()
   194  
   195  	act = env.EnvList()
   196  	exp = []string{
   197  		"NOMAD_ADDR_http=127.0.0.1:80",
   198  		"NOMAD_PORT_http=80",
   199  		"NOMAD_IP_http=127.0.0.1",
   200  		"NOMAD_ADDR_https=127.0.0.1:443",
   201  		"NOMAD_PORT_https=443",
   202  		"NOMAD_IP_https=127.0.0.1",
   203  		"NOMAD_HOST_PORT_https=8080",
   204  		"NOMAD_HOST_PORT_http=80",
   205  	}
   206  	sort.Strings(act)
   207  	sort.Strings(exp)
   208  	if !reflect.DeepEqual(act, exp) {
   209  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   210  	}
   211  }
   212  
   213  func TestEnvironment_Interprolate(t *testing.T) {
   214  	env := testTaskEnvironment().
   215  		SetEnvvars(map[string]string{"test": "${node.class}", "test2": "${attr.arch}"}).
   216  		Build()
   217  
   218  	act := env.EnvList()
   219  	exp := []string{fmt.Sprintf("test=%s", nodeClass), fmt.Sprintf("test2=%s", attrVal)}
   220  	sort.Strings(act)
   221  	sort.Strings(exp)
   222  	if !reflect.DeepEqual(act, exp) {
   223  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   224  	}
   225  }
   226  
   227  func TestEnvironment_AppendHostEnvVars(t *testing.T) {
   228  	host := os.Environ()
   229  	if len(host) < 2 {
   230  		t.Skip("No host environment variables. Can't test")
   231  	}
   232  	skip := strings.Split(host[0], "=")[0]
   233  	env := testTaskEnvironment().
   234  		AppendHostEnvvars([]string{skip}).
   235  		Build()
   236  
   237  	act := env.EnvMap()
   238  	if len(act) < 1 {
   239  		t.Fatalf("Host environment variables not properly set")
   240  	}
   241  	if _, ok := act[skip]; ok {
   242  		t.Fatalf("Didn't filter environment variable %q", skip)
   243  	}
   244  }
   245  
   246  func TestEnvironment_MetaPrecedence(t *testing.T) {
   247  	n := mock.Node()
   248  	env := NewTaskEnvironment(n, false).
   249  		SetJobMeta(map[string]string{"foo": "job", "bar": "job", "baz": "job"}).
   250  		SetTaskGroupMeta(map[string]string{"foo": "tg", "bar": "tg"}).
   251  		SetTaskMeta(map[string]string{"foo": "task"}).Build()
   252  
   253  	act := env.EnvList()
   254  	exp := []string{
   255  		"NOMAD_META_FOO=task",
   256  		"NOMAD_META_BAR=tg",
   257  		"NOMAD_META_BAZ=job",
   258  	}
   259  	sort.Strings(act)
   260  	sort.Strings(exp)
   261  	if !reflect.DeepEqual(act, exp) {
   262  		t.Fatalf("env.List() returned %v; want %v", act, exp)
   263  	}
   264  }