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

Side by Side Diff: vpython/python/python_test.go

Issue 2701073002: vpython: Add Python interpreter handling package. (Closed)
Patch Set: rebase Created 3 years, 10 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 | « vpython/python/python.go ('k') | vpython/python/version.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 under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package python
6
7 import (
8 "fmt"
9 "os"
10 "os/exec"
11 "testing"
12
13 "golang.org/x/net/context"
14
15 . "github.com/luci/luci-go/common/testing/assertions"
16 . "github.com/smartystreets/goconvey/convey"
17 )
18
19 func TestParsePythonCommandLine(t *testing.T) {
20 t.Parallel()
21
22 successes := []struct {
23 args []string
24 cmd CommandLine
25 }{
26 {nil, CommandLine{}},
27
28 {[]string{"-a", "-b", "-Q'foo.bar.baz'", "-Wbar"},
29 CommandLine{
30 Flags: []string{"-a", "-b", "-Q'foo.bar.baz'", " -Wbar"},
31 Args: []string{},
32 },
33 },
34
35 {[]string{"path.py", "--", "foo", "bar"},
36 CommandLine{
37 Type: TargetScript,
38 Value: "path.py",
39 Flags: []string{},
40 Args: []string{"--", "foo", "bar"},
41 },
42 },
43
44 {[]string{"-a", "-Wfoo", "-", "--", "foo"},
45 CommandLine{
46 Type: TargetScript,
47 Value: "-",
48 Flags: []string{"-a", "-Wfoo"},
49 Args: []string{"--", "foo"},
50 },
51 },
52
53 {[]string{"-a", "-b", "-W", "foo", "-Wbar", "-c", "<script>", "- -", "arg"},
54 CommandLine{
55 Type: TargetCommand,
56 Value: "<script>",
57 Flags: []string{"-a", "-b", "-W", "foo", "-Wbar" },
58 Args: []string{"--", "arg"},
59 },
60 },
61
62 {[]string{"-a", "-b", "-m'foo.bar.baz'", "arg"},
63 CommandLine{
64 Type: TargetModule,
65 Value: "'foo.bar.baz'",
66 Flags: []string{"-a", "-b"},
67 Args: []string{"arg"},
68 },
69 },
70 }
71
72 failures := []struct {
73 args []string
74 err string
75 }{
76 {[]string{"-a", "-b", "-Q"}, "truncated two-variable argument"},
77 {[]string{"-c"}, "missing second value"},
78 {[]string{"-\x80"}, "invalid rune in flag"},
79 }
80
81 Convey(`Testing Python command-line parsing`, t, func() {
82 for _, tc := range successes {
83 Convey(fmt.Sprintf(`Success cases: %v`, tc.args), func() {
84 cmd, err := ParseCommandLine(tc.args)
85 So(err, ShouldBeNil)
86 So(cmd, ShouldResemble, tc.cmd)
87 })
88 }
89
90 for _, tc := range failures {
91 Convey(fmt.Sprintf(`Error cases: %v`, tc.args), func() {
92 _, err := ParseCommandLine(tc.args)
93 So(err, ShouldErrLike, tc.err)
94 })
95 }
96 })
97 }
98
99 func TestInterpreter(t *testing.T) {
100 t.Parallel()
101
102 versionSuccesses := []struct {
103 output string
104 vers Version
105 }{
106 {"Python 2.7.1\n", Version{2, 7, 1}},
107 {"Python 3", Version{3, 0, 0}},
108 }
109
110 versionFailures := []struct {
111 output string
112 err string
113 }{
114 {"", "unknown version output"},
115 {"Python2.7.11\n", "unknown version output"},
116 {"Python", "unknown version output"},
117 {"Python 2.7.11 foo bar junk", "invalid number value"},
118 {"Python 3.1.2.3.4", "failed to parse version"},
119 }
120
121 Convey(`A Python interpreter`, t, func() {
122 c := context.Background()
123
124 var (
125 runnerOutput string
126 runnerErr error
127 lastCmd *exec.Cmd
128 )
129 i := Interpreter{
130 testRunner: func(cmd *exec.Cmd, capture bool) (string, e rror) {
131 // Sanitize exec.Cmd to exclude its private memb ers for comparison.
132 lastCmd = &exec.Cmd{
133 Path: cmd.Path,
134 Args: cmd.Args,
135 Stdin: cmd.Stdin,
136 Stdout: cmd.Stdout,
137 Stderr: cmd.Stderr,
138 Env: cmd.Env,
139 Dir: cmd.Dir,
140 }
141 return runnerOutput, runnerErr
142 },
143 }
144
145 Convey(`Will error if no Python interpreter is supplied.`, func( ) {
146 So(i.Command().Run(c, "foo", "bar"), ShouldErrLike, "a P ython interpreter must be supplied")
147 })
148
149 Convey(`With a Python interpreter installed`, func() {
150 i.Python = "/path/to/python"
151
152 Convey(`Testing Run`, func() {
153 cmd := i.Command()
154
155 Convey(`Can run a command.`, func() {
156 So(cmd.Run(c, "foo", "bar"), ShouldBeNil )
157 So(lastCmd, ShouldResemble, &exec.Cmd{
158 Path: "/path/to/python",
159 Args: []string{"/path/to/pytho n", "foo", "bar"},
160 Stdout: os.Stdout,
161 Stderr: os.Stderr,
162 })
163 })
164
165 Convey(`Can run an isolated environment command. `, func() {
166 cmd.Isolated = true
167
168 So(cmd.Run(c, "foo", "bar"), ShouldBeNil )
169 So(lastCmd, ShouldResemble, &exec.Cmd{
170 Path: "/path/to/python",
171 Args: []string{"/path/to/pytho n", "-B", "-E", "-s", "foo", "bar"},
172 Stdout: os.Stdout,
173 Stderr: os.Stderr,
174 })
175 })
176
177 Convey(`Can connect STDIN.`, func() {
178 cmd.ConnectSTDIN = true
179
180 So(cmd.Run(c, "foo", "bar"), ShouldBeNil )
181 So(lastCmd, ShouldResemble, &exec.Cmd{
182 Path: "/path/to/python",
183 Args: []string{"/path/to/pytho n", "foo", "bar"},
184 Stdout: os.Stdout,
185 Stderr: os.Stderr,
186 Stdin: os.Stdin,
187 })
188 })
189
190 Convey(`Will forward a working directory and env iornment`, func() {
191 cmd.WorkDir = "zugzug"
192 cmd.Env = []string{"pants=on"}
193
194 So(cmd.Run(c, "foo", "bar"), ShouldBeNil )
195 So(lastCmd, ShouldResemble, &exec.Cmd{
196 Path: "/path/to/python",
197 Args: []string{"/path/to/pytho n", "foo", "bar"},
198 Stdout: os.Stdout,
199 Stderr: os.Stderr,
200 Env: []string{"pants=on"},
201 Dir: "zugzug",
202 })
203 })
204 })
205
206 Convey(`Testing GetVersion`, func() {
207 for _, tc := range versionSuccesses {
208 Convey(fmt.Sprintf(`Can successfully par se %q => %s`, tc.output, tc.vers), func() {
209 runnerOutput = tc.output
210 vers, err := i.GetVersion(c)
211 So(err, ShouldBeNil)
212 So(vers, ShouldResemble, tc.vers )
213 })
214 }
215
216 for _, tc := range versionFailures {
217 Convey(fmt.Sprintf(`Will fail to parse % q (%s)`, tc.output, tc.err), func() {
218 runnerOutput = tc.output
219 _, err := i.GetVersion(c)
220 So(err, ShouldErrLike, tc.err)
221 })
222 }
223 })
224 })
225 })
226 }
OLDNEW
« no previous file with comments | « vpython/python/python.go ('k') | vpython/python/version.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698