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 }