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 }