Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Side by Side Diff: common/system/prober/probe_test.go

Issue 2932443002: Initial transfer. (Closed)
Patch Set: move to system Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « common/system/prober/probe.go ('k') | common/system/prober/probe_unix.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package prober
6
7 import (
8 "fmt"
9 "io/ioutil"
10 "os"
11 "path/filepath"
12 "runtime"
13 "strings"
14 "testing"
15
16 "golang.org/x/net/context"
17
18 "github.com/luci/luci-go/common/errors"
19 "github.com/luci/luci-go/common/logging"
20 "github.com/luci/luci-go/common/logging/gologger"
21 "github.com/luci/luci-go/common/system/environ"
22 "github.com/luci/luci-go/common/testing/testfs"
23
24 . "github.com/luci/luci-go/common/testing/assertions"
25 . "github.com/smartystreets/goconvey/convey"
26 )
27
28 func baseTestContext() context.Context {
29 c := context.Background()
30 c = gologger.StdConfig.Use(c)
31 c = logging.SetLevel(c, logging.Debug)
32 return c
33 }
34
35 // TestFindSystemGit tests the ability to resolve the current executable.
36 func TestResolveSelf(t *testing.T) {
37 t.Parallel()
38
39 realExec, err := os.Executable()
40 if err != nil {
41 t.Fatalf("failed to resolve the real executable: %s", err)
42 }
43 realExecStat, err := os.Stat(realExec)
44 if err != nil {
45 t.Fatalf("failed to stat the real executable %q: %s", realExec, err)
46 }
47
48 Convey(`With a temporary directory`, t, testfs.MustWithTempDir(t, "resol ve_self", func(tdir string) {
49 // Set up a base probe.
50 probe := Probe{
51 Target: "git",
52 }
53
54 Convey(`Will resolve our executable.`, func() {
55 So(probe.ResolveSelf(""), ShouldBeNil)
56 So(probe.Self, ShouldEqual, realExec)
57 So(os.SameFile(probe.SelfStat, realExecStat), ShouldBeTr ue)
58 })
59
60 Convey(`When "self" is a symlink to the executable`, func() {
61 symSelf := filepath.Join(tdir, "me")
62 if err := os.Symlink(realExec, symSelf); err != nil {
63 t.Skipf("Could not create symlink %q => %q: %s", realExec, symSelf, err)
64 return
65 }
66
67 So(probe.ResolveSelf(symSelf), ShouldBeNil)
68 So(probe.Self, ShouldEqual, symSelf)
69 So(os.SameFile(probe.SelfStat, realExecStat), ShouldBeTr ue)
70 })
71 }))
72 }
73
74 // TestFindSystemGit tests the ability to locate the "git" command in PATH.
75 func TestSystemProbe(t *testing.T) {
76 t.Parallel()
77
78 var envBase environ.Env
79 var selfEXESuffix, otherEXESuffix string
80 if runtime.GOOS == "windows" {
81 selfEXESuffix = ".exe"
82 otherEXESuffix = ".bat"
83 envBase.Set("PATHEXT", strings.Join([]string{".com", ".exe", ".b at", ".ohai"}, string(os.PathListSeparator)))
84 }
85
86 Convey(`With a fake PATH setup`, t, testfs.MustWithTempDir(t, "system_pr obe", func(tdir string) {
87 c := baseTestContext()
88
89 createExecutable := func(relPath string) (dir string, path strin g) {
90 path = filepath.Join(tdir, filepath.FromSlash(relPath))
91 dir = filepath.Dir(path)
92 if err := os.MkdirAll(dir, 0755); err != nil {
93 t.Fatalf("Failed to create base directory [%s]: %s", dir, err)
94 }
95 if err := ioutil.WriteFile(path, []byte("fake"), 0755); err != nil {
96 t.Fatalf("Failed to create executable: %s", err)
97 }
98 return
99 }
100
101 // Construct a fake filesystem rooted in "tdir".
102 var (
103 selfDir, selfGit = createExecutable("self/git" + selfEXE Suffix)
104 _, overrideGit = createExecutable("self/override/reldi r/git" + otherEXESuffix)
105 fooDir, fooGit = createExecutable("foo/git" + otherEXE Suffix)
106 wrapperDir, _ = createExecutable("wrapper/git" + othe rEXESuffix)
107 brokenDir, _ = createExecutable("broken/git" + other EXESuffix)
108 otherDir, _ = createExecutable("other/not_git")
109 nonexistDir = filepath.Join(tdir, "nonexist")
110 nonexistGit = filepath.Join(nonexistDir, "git"+othe rEXESuffix)
111 )
112
113 // Set up a base probe.
114 wrapperChecks := 0
115 probe := Probe{
116 Target: "git",
117
118 CheckWrapper: func(c context.Context, path string, env e nviron.Env) (bool, error) {
119 wrapperChecks++
120 switch filepath.Dir(path) {
121 case wrapperDir, selfDir:
122 return true, nil
123 case brokenDir:
124 return false, errors.New("broken")
125 default:
126 return false, nil
127 }
128 },
129 }
130
131 selfGitStat, err := os.Stat(selfGit)
132 if err != nil {
133 t.Fatalf("failed to stat self Git %q: %s", selfGit, err)
134 }
135 probe.Self, probe.SelfStat = selfGit, selfGitStat
136
137 env := envBase.Clone()
138 setPATH := func(v ...string) {
139 env.Set("PATH", strings.Join(v, string(os.PathListSepara tor)))
140 }
141
142 Convey(`Can identify the next Git when it follows self in PATH.` , func() {
143 setPATH(selfDir, selfDir, fooDir, wrapperDir, otherDir, nonexistDir)
144
145 git, err := probe.Locate(c, "", env)
146 So(err, ShouldBeNil)
147 So(git, shouldBeSameFileAs, fooGit)
148 So(wrapperChecks, ShouldEqual, 1)
149 })
150
151 Convey(`When Git precedes self in PATH`, func() {
152 setPATH(fooDir, selfDir, wrapperDir, otherDir, nonexistD ir)
153
154 Convey(`Will identify Git`, func() {
155 git, err := probe.Locate(c, "", env)
156 So(err, ShouldBeNil)
157 So(git, shouldBeSameFileAs, fooGit)
158 So(wrapperChecks, ShouldEqual, 1)
159 })
160
161 Convey(`Will prefer an override Git`, func() {
162 probe.RelativePathOverride = []string{
163 "override/reldir", // (see "overrideGit" )
164 }
165
166 git, err := probe.Locate(c, "", env)
167 So(err, ShouldBeNil)
168 So(git, shouldBeSameFileAs, overrideGit)
169 So(wrapperChecks, ShouldEqual, 1)
170 })
171 })
172
173 Convey(`Can identify the next Git when self does not exist.`, fu nc() {
174 setPATH(wrapperDir, selfDir, wrapperDir, otherDir, nonex istDir, fooDir)
175
176 probe.Self = nonexistGit
177 git, err := probe.Locate(c, "", env)
178 So(err, ShouldBeNil)
179 So(git, shouldBeSameFileAs, fooGit)
180 So(wrapperChecks, ShouldEqual, 2)
181 })
182
183 Convey(`With PATH setup pointing to a wrapper, self, and then th e system Git`, func() {
184 // NOTE: wrapperDir is repeated, but it will only count towards one check,
185 // since we cache checks on a per-directory basis.
186 setPATH(wrapperDir, wrapperDir, selfDir, otherDir, fooDi r, nonexistDir)
187
188 Convey(`Will prefer the cached value.`, func() {
189 git, err := probe.Locate(c, fooGit, env)
190 So(err, ShouldBeNil)
191 So(git, shouldBeSameFileAs, fooGit)
192 So(wrapperChecks, ShouldEqual, 0)
193 })
194
195 Convey(`Will ignore the cached value if it is self.`, fu nc() {
196 git, err := probe.Locate(c, selfGit, env)
197 So(err, ShouldBeNil)
198 So(git, shouldBeSameFileAs, fooGit)
199 So(wrapperChecks, ShouldEqual, 2)
200 })
201
202 Convey(`Will ignore the cached value if it does not exis t.`, func() {
203 git, err := probe.Locate(c, nonexistGit, env)
204 So(err, ShouldBeNil)
205 So(git, shouldBeSameFileAs, fooGit)
206 So(wrapperChecks, ShouldEqual, 2)
207 })
208
209 Convey(`Will skip the wrapper and identify the system Gi t.`, func() {
210 git, err := probe.Locate(c, "", env)
211 So(err, ShouldBeNil)
212 So(git, shouldBeSameFileAs, fooGit)
213 So(wrapperChecks, ShouldEqual, 2)
214 })
215 })
216
217 Convey(`Will skip everything if the wrapper check fails.`, func( ) {
218 setPATH(wrapperDir, brokenDir, selfDir, otherDir, fooDir , nonexistDir)
219
220 git, err := probe.Locate(c, "", env)
221 So(err, ShouldBeNil)
222 So(git, shouldBeSameFileAs, fooGit)
223 So(wrapperChecks, ShouldEqual, 3)
224 })
225
226 Convey(`Will fail if cannot find another Git in PATH.`, func() {
227 setPATH(selfDir, otherDir, nonexistDir)
228
229 _, err := probe.Locate(c, "", env)
230 So(err, ShouldErrLike, "could not find target in system" )
231 So(wrapperChecks, ShouldEqual, 0)
232 })
233
234 Convey(`When a symlink is created`, func() {
235 conveyFn := Convey
236 if err := os.Symlink(selfGit, filepath.Join(otherDir, fi lepath.Base(selfGit))); err != nil {
237 t.Logf("Failed to create symlink; skipping symli nk test: %s", err)
238 conveyFn = SkipConvey
239 }
240
241 conveyFn(`Will ignore symlink because it's the same file .`, func() {
242 setPATH(selfDir, otherDir, fooDir, wrapperDir)
243 git, err := probe.Locate(c, "", env)
244 So(err, ShouldBeNil)
245 So(git, shouldBeSameFileAs, fooGit)
246 So(wrapperChecks, ShouldEqual, 1)
247 })
248 })
249 }))
250 }
251
252 func shouldBeSameFileAs(actual interface{}, expected ...interface{}) string {
253 aPath, ok := actual.(string)
254 if !ok {
255 return "actual must be a path string"
256 }
257
258 if len(expected) != 1 {
259 return "exactly one expected path string must be provided"
260 }
261 expPath, ok := expected[0].(string)
262 if !ok {
263 return "expected must be a path string"
264 }
265
266 aSt, err := os.Stat(aPath)
267 if err != nil {
268 return fmt.Sprintf("failed to stat actual [%s]: %s", aPath, err)
269 }
270 expSt, err := os.Stat(expPath)
271 if err != nil {
272 return fmt.Sprintf("failed to stat expected [%s]: %s", expPath, err)
273 }
274
275 if !os.SameFile(aSt, expSt) {
276 return fmt.Sprintf("[%s] is not the same file as [%s]", expPath, aPath)
277 }
278 return ""
279 }
OLDNEW
« no previous file with comments | « common/system/prober/probe.go ('k') | common/system/prober/probe_unix.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698