| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package environ | 5 package environ |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "testing" | 8 "testing" |
| 9 | 9 |
| 10 . "github.com/smartystreets/goconvey/convey" | 10 . "github.com/smartystreets/goconvey/convey" |
| 11 ) | 11 ) |
| 12 | 12 |
| 13 func newImpl(caseInsensitive bool, entries []string) Env { |
| 14 e := Env{CaseInsensitive: caseInsensitive} |
| 15 e.LoadSlice(entries) |
| 16 return e |
| 17 } |
| 18 |
| 13 func TestEnvironmentConversion(t *testing.T) { | 19 func TestEnvironmentConversion(t *testing.T) { |
| 14 t.Parallel() | 20 t.Parallel() |
| 15 | 21 |
| 16 Convey(`Source environment slice translates correctly to/from an Env.`,
t, func() { | 22 Convey(`Source environment slice translates correctly to/from an Env.`,
t, func() { |
| 17 » » env := New([]string{ | 23 » » Convey(`Case insensitive (e.g., Windows)`, func() { |
| 18 » » » "", | 24 » » » env := newImpl(true, []string{ |
| 19 » » » "FOO", | 25 » » » » "", |
| 20 » » » "BAR=BAZ", | 26 » » » » "FOO", |
| 21 » » » "bar=baz", | 27 » » » » "BAR=BAZ", |
| 22 » » » "qux=quux=quuuuuuux", | 28 » » » » "bar=baz", |
| 23 » » }) | 29 » » » » "qux=quux=quuuuuuux", |
| 24 » » So(env, ShouldResemble, Env{ | 30 » » » }) |
| 25 » » » env: map[string]string{ | 31 » » » So(env, ShouldResemble, Env{ |
| 26 » » » » "": "", | 32 » » » » CaseInsensitive: true, |
| 27 » » » » "FOO": "FOO", | 33 » » » » env: map[string]string{ |
| 28 » » » » "BAR": "BAR=BAZ", | 34 » » » » » "": "", |
| 29 » » » » "bar": "bar=baz", | 35 » » » » » "FOO": "FOO", |
| 30 » » » » "qux": "qux=quux=quuuuuuux", | 36 » » » » » "BAR": "bar=baz", |
| 31 » » » }, | 37 » » » » » "QUX": "qux=quux=quuuuuuux", |
| 38 » » » » }, |
| 39 » » » }) |
| 40 |
| 41 » » » So(env.Sorted(), ShouldResemble, []string{ |
| 42 » » » » "", |
| 43 » » » » "FOO", |
| 44 » » » » "bar=baz", |
| 45 » » » » "qux=quux=quuuuuuux", |
| 46 » » » }) |
| 47 |
| 48 » » » So(env.GetEmpty(""), ShouldEqual, "") |
| 49 » » » So(env.GetEmpty("FOO"), ShouldEqual, "") |
| 50 » » » So(env.GetEmpty("BAR"), ShouldEqual, "baz") |
| 51 » » » So(env.GetEmpty("bar"), ShouldEqual, "baz") |
| 52 » » » So(env.GetEmpty("qux"), ShouldEqual, "quux=quuuuuuux") |
| 53 » » » So(env.GetEmpty("QuX"), ShouldEqual, "quux=quuuuuuux") |
| 32 }) | 54 }) |
| 33 | 55 |
| 34 » » So(env.Sorted(), ShouldResemble, []string{ | 56 » » Convey(`Case sensitive (e.g., POSIX)`, func() { |
| 35 » » » "", | 57 » » » env := newImpl(false, []string{ |
| 36 » » » "BAR=BAZ", | 58 » » » » "", |
| 37 » » » "FOO", | 59 » » » » "FOO", |
| 38 » » » "bar=baz", | 60 » » » » "BAR=BAZ", |
| 39 » » » "qux=quux=quuuuuuux", | 61 » » » » "bar=baz", |
| 62 » » » » "qux=quux=quuuuuuux", |
| 63 » » » }) |
| 64 » » » So(env, ShouldResemble, Env{ |
| 65 » » » » env: map[string]string{ |
| 66 » » » » » "": "", |
| 67 » » » » » "FOO": "FOO", |
| 68 » » » » » "BAR": "BAR=BAZ", |
| 69 » » » » » "bar": "bar=baz", |
| 70 » » » » » "qux": "qux=quux=quuuuuuux", |
| 71 » » » » }, |
| 72 » » » }) |
| 73 |
| 74 » » » So(env.Sorted(), ShouldResemble, []string{ |
| 75 » » » » "", |
| 76 » » » » "BAR=BAZ", |
| 77 » » » » "FOO", |
| 78 » » » » "bar=baz", |
| 79 » » » » "qux=quux=quuuuuuux", |
| 80 » » » }) |
| 81 |
| 82 » » » So(env.GetEmpty(""), ShouldEqual, "") |
| 83 » » » So(env.GetEmpty("FOO"), ShouldEqual, "") |
| 84 » » » So(env.GetEmpty("BAR"), ShouldEqual, "BAZ") |
| 85 » » » So(env.GetEmpty("bar"), ShouldEqual, "baz") |
| 86 » » » So(env.GetEmpty("qux"), ShouldEqual, "quux=quuuuuuux") |
| 87 » » » So(env.GetEmpty("QuX"), ShouldEqual, "") |
| 40 }) | 88 }) |
| 41 }) | 89 }) |
| 42 } | 90 } |
| 43 | 91 |
| 44 func TestEnvironmentManipulation(t *testing.T) { | 92 func TestEnvironmentManipulation(t *testing.T) { |
| 45 t.Parallel() | 93 t.Parallel() |
| 46 | 94 |
| 47 Convey(`A zero-valued Env`, t, func() { | 95 Convey(`A zero-valued Env`, t, func() { |
| 48 var env Env | 96 var env Env |
| 49 So(env.Len(), ShouldEqual, 0) | 97 So(env.Len(), ShouldEqual, 0) |
| 50 | 98 |
| 51 Convey(`Can be sorted.`, func() { | 99 Convey(`Can be sorted.`, func() { |
| 52 So(env.Sorted(), ShouldEqual, nil) | 100 So(env.Sorted(), ShouldEqual, nil) |
| 53 }) | 101 }) |
| 54 | 102 |
| 55 Convey(`Can call Get`, func() { | 103 Convey(`Can call Get`, func() { |
| 56 v, ok := env.Get("foo") | 104 v, ok := env.Get("foo") |
| 57 So(ok, ShouldBeFalse) | 105 So(ok, ShouldBeFalse) |
| 58 So(v, ShouldEqual, "") | 106 So(v, ShouldEqual, "") |
| 59 }) | 107 }) |
| 60 | 108 |
| 61 Convey(`Can call Set`, func() { | 109 Convey(`Can call Set`, func() { |
| 62 env.Set("foo", "bar") | 110 env.Set("foo", "bar") |
| 63 So(env.Len(), ShouldEqual, 1) | 111 So(env.Len(), ShouldEqual, 1) |
| 64 So(env.Sorted(), ShouldResemble, []string{"foo=bar"}) | 112 So(env.Sorted(), ShouldResemble, []string{"foo=bar"}) |
| 65 }) | 113 }) |
| 66 | 114 |
| 67 » » Convey(`Can be cloned.`, func() { | 115 » » Convey(`Can be cloned, and propagates case insensitivity.`, func
() { |
| 116 » » » env.CaseInsensitive = true |
| 68 So(env.Clone(), ShouldResemble, env) | 117 So(env.Clone(), ShouldResemble, env) |
| 69 }) | 118 }) |
| 70 }) | 119 }) |
| 71 | 120 |
| 72 Convey(`A testing Env`, t, func() { | 121 Convey(`A testing Env`, t, func() { |
| 73 » » env := New([]string{ | 122 » » env := newImpl(true, []string{ |
| 74 "PYTHONPATH=/foo:/bar:/baz", | 123 "PYTHONPATH=/foo:/bar:/baz", |
| 75 "http_proxy=wiped-out-by-next", | 124 "http_proxy=wiped-out-by-next", |
| 76 "http_proxy=http://example.com", | 125 "http_proxy=http://example.com", |
| 77 "novalue", | 126 "novalue", |
| 78 }) | 127 }) |
| 79 So(env.Len(), ShouldEqual, 3) | 128 So(env.Len(), ShouldEqual, 3) |
| 80 | 129 |
| 81 Convey(`Can Get values.`, func() { | 130 Convey(`Can Get values.`, func() { |
| 82 v, ok := env.Get("PYTHONPATH") | 131 v, ok := env.Get("PYTHONPATH") |
| 83 So(ok, ShouldBeTrue) | 132 So(ok, ShouldBeTrue) |
| 84 So(v, ShouldEqual, "/foo:/bar:/baz") | 133 So(v, ShouldEqual, "/foo:/bar:/baz") |
| 85 | 134 |
| 86 v, ok = env.Get("http_proxy") | 135 v, ok = env.Get("http_proxy") |
| 87 So(ok, ShouldBeTrue) | 136 So(ok, ShouldBeTrue) |
| 88 So(v, ShouldEqual, "http://example.com") | 137 So(v, ShouldEqual, "http://example.com") |
| 89 | 138 |
| 90 v, ok = env.Get("novalue") | 139 v, ok = env.Get("novalue") |
| 91 So(ok, ShouldBeTrue) | 140 So(ok, ShouldBeTrue) |
| 92 So(v, ShouldEqual, "") | 141 So(v, ShouldEqual, "") |
| 93 }) | 142 }) |
| 94 | 143 |
| 95 Convey(`Will note missing values.`, func() { | 144 Convey(`Will note missing values.`, func() { |
| 96 » » » _, ok := env.Get("pythonpath") | 145 » » » _, ok := env.Get("missing") |
| 97 So(ok, ShouldBeFalse) | 146 So(ok, ShouldBeFalse) |
| 98 | 147 |
| 99 _, ok = env.Get("") | 148 _, ok = env.Get("") |
| 100 So(ok, ShouldBeFalse) | 149 So(ok, ShouldBeFalse) |
| 101 }) | 150 }) |
| 102 | 151 |
| 152 Convey(`Can be converted into a map`, func() { |
| 153 So(env.Map(), ShouldResemble, map[string]string{ |
| 154 "PYTHONPATH": "/foo:/bar:/baz", |
| 155 "http_proxy": "http://example.com", |
| 156 "novalue": "", |
| 157 }) |
| 158 |
| 159 }) |
| 160 |
| 103 Convey(`Can update its values.`, func() { | 161 Convey(`Can update its values.`, func() { |
| 104 orig := env.Clone() | 162 orig := env.Clone() |
| 105 | 163 |
| 106 // Update PYTHONPATH, confirm that it updated correctly. | 164 // Update PYTHONPATH, confirm that it updated correctly. |
| 107 v, _ := env.Get("PYTHONPATH") | 165 v, _ := env.Get("PYTHONPATH") |
| 108 env.Set("PYTHONPATH", "/override:"+v) | 166 env.Set("PYTHONPATH", "/override:"+v) |
| 109 So(env.Sorted(), ShouldResemble, []string{ | 167 So(env.Sorted(), ShouldResemble, []string{ |
| 110 "PYTHONPATH=/override:/foo:/bar:/baz", | 168 "PYTHONPATH=/override:/foo:/bar:/baz", |
| 111 "http_proxy=http://example.com", | 169 "http_proxy=http://example.com", |
| 112 "novalue", | 170 "novalue", |
| 113 }) | 171 }) |
| 114 | 172 |
| 115 » » » // Test that the clone didn't change. | 173 » » » // Use a different-case key, and confirm that it still u
pdated correctly. |
| 116 » » » So(orig.Sorted(), ShouldResemble, []string{ | 174 » » » Convey(`When case insensitive, will update common keys.`
, func() { |
| 117 » » » » "PYTHONPATH=/foo:/bar:/baz", | 175 » » » » env.CaseInsensitive = true |
| 118 » » » » "http_proxy=http://example.com", | 176 |
| 119 » » » » "novalue", | 177 » » » » env.Set("pYtHoNpAtH", "/override:"+v) |
| 178 » » » » So(env.Sorted(), ShouldResemble, []string{ |
| 179 » » » » » "http_proxy=http://example.com", |
| 180 » » » » » "novalue", |
| 181 » » » » » "pYtHoNpAtH=/override:/foo:/bar:/baz", |
| 182 » » » » }) |
| 183 » » » » So(env.GetEmpty("PYTHONPATH"), ShouldEqual, "/ov
erride:/foo:/bar:/baz") |
| 184 |
| 185 » » » » So(env.Remove("HTTP_PROXY"), ShouldBeTrue) |
| 186 » » » » So(env.Remove("nonexistent"), ShouldBeFalse) |
| 187 » » » » So(env.Sorted(), ShouldResemble, []string{ |
| 188 » » » » » "novalue", |
| 189 » » » » » "pYtHoNpAtH=/override:/foo:/bar:/baz", |
| 190 » » » » }) |
| 191 |
| 192 » » » » // Test that the clone didn't change. |
| 193 » » » » So(orig.Sorted(), ShouldResemble, []string{ |
| 194 » » » » » "PYTHONPATH=/foo:/bar:/baz", |
| 195 » » » » » "http_proxy=http://example.com", |
| 196 » » » » » "novalue", |
| 197 » » » » }) |
| 120 }) | 198 }) |
| 121 }) | 199 }) |
| 122 }) | 200 }) |
| 123 } | 201 } |
| 124 | 202 |
| 125 func TestEnvironmentConstruction(t *testing.T) { | 203 func TestEnvironmentConstruction(t *testing.T) { |
| 126 t.Parallel() | 204 t.Parallel() |
| 127 | 205 |
| 128 » Convey(`Can create a new enviornment with Make`, t, func() { | 206 » Convey(`Testing Load* with an empty environment`, t, func() { |
| 129 » » env := Make(map[string]string{ | 207 » » var env Env |
| 130 » » » "FOO": "BAR", | 208 |
| 131 » » » "foo": "bar", | 209 » » Convey(`Can load an initial set of values from a map`, func() { |
| 210 » » » env.Load(map[string]string{ |
| 211 » » » » "FOO": "BAR", |
| 212 » » » » "foo": "bar", |
| 213 » » » }) |
| 214 |
| 215 » » » So(env, ShouldResemble, Env{ |
| 216 » » » » env: map[string]string{ |
| 217 » » » » » "FOO": "FOO=BAR", |
| 218 » » » » » "foo": "foo=bar", |
| 219 » » » » }, |
| 220 » » » }) |
| 132 }) | 221 }) |
| 133 | 222 |
| 134 » » So(env, ShouldResemble, Env{ | 223 » » Convey(`Load with an nil/empty enviornment returns a zero value.
`, func() { |
| 135 » » » env: map[string]string{ | 224 » » » env.Load(nil) |
| 136 » » » » "FOO": "FOO=BAR", | 225 » » » So(env.env, ShouldBeNil) |
| 137 » » » » "foo": "foo=bar", | 226 |
| 138 » » » }, | 227 » » » env.Load(map[string]string{}) |
| 228 » » » So(env.env, ShouldBeNil) |
| 139 }) | 229 }) |
| 140 }) | 230 }) |
| 141 | 231 |
| 142 Convey(`Make with an nil/empty enviornment returns a zero value.`, t, fu
nc() { | |
| 143 So(Make(nil), ShouldResemble, Env{}) | |
| 144 So(Make(map[string]string{}), ShouldResemble, Env{}) | |
| 145 }) | |
| 146 | |
| 147 Convey(`New with a nil/empty slice returns a zero value.`, t, func() { | 232 Convey(`New with a nil/empty slice returns a zero value.`, t, func() { |
| 148 » » So(New(nil), ShouldResemble, Env{}) | 233 » » So(New(nil).env, ShouldBeNil) |
| 149 » » So(New([]string{}), ShouldResemble, Env{}) | 234 » » So(New([]string{}).env, ShouldBeNil) |
| 150 }) | 235 }) |
| 151 } | 236 } |
| OLD | NEW |