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