forked from taskcluster/taskcluster
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelper_windows_test.go
156 lines (136 loc) · 4.42 KB
/
helper_windows_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/taskcluster/taskcluster/v40/workers/generic-worker/win32"
)
func helloGoodbye() []string {
return []string{
"echo hello world!",
"echo goodbye world!",
}
}
func rawHelloGoodbye() string {
return `"echo hello world!", "echo goodbye world!"`
}
func checkSHASums() []string {
return []string{
"PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File preloaded\\check-shasums.ps1",
}
}
func returnExitCode(exitCode uint) []string {
return []string{
fmt.Sprintf("exit %d", exitCode),
}
}
func incrementCounterInCache() []string {
// The `echo | set /p dummyName...` construction is to avoid printing a
// newline. See answer by xmechanix on:
// http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line/19468559#19468559
command := `
setlocal EnableDelayedExpansion
if exist my-task-caches\test-modifications\counter (
set /p counter=<my-task-caches\test-modifications\counter
set /a counter=counter+1
echo | set /p dummyName="!counter!" > my-task-caches\test-modifications\counter
) else (
echo | set /p dummyName="1" > my-task-caches\test-modifications\counter
)
`
return []string{command}
}
func GoEnv() []string {
return []string{
"go env",
"set",
"where go",
"go version",
}
}
func logOncePerSecond(count uint, file string) []string {
return goRunFileOutput(file, "spawn-orphan-process.go", strconv.Itoa(int(count)))
// return []string{
// "ping 127.0.0.1 -n " + strconv.Itoa(int(count)) + " > " + file,
// }
}
func sleep(seconds uint) []string {
return []string{
"ping 127.0.0.1 -n " + strconv.Itoa(int(seconds+1)) + " > nul",
}
}
func goRun(goFile string, args ...string) []string {
return goRunFileOutput("", goFile, args...)
}
func goRunFileOutput(outputFile, goFile string, args ...string) []string {
prepare := []string{}
for _, envVar := range []string{
"PATH", "GOPATH", "GOROOT",
} {
if val, exists := os.LookupEnv(envVar); exists {
prepare = append(prepare, "set "+envVar+"="+win32.CMDExeEscape(val))
}
}
prepare = append(prepare, copyTestdataFile(goFile)...)
cmd := []string{"go", "run", goFile}
cmd = append(cmd, args...)
return append(prepare, run(cmd, outputFile))
}
// run runs the command line args specified in args and redirects the output to
// file outputFile if it is not an empty string.
func run(args []string, outputFile string) string {
// Goddammit, Windows! Even this double nesting doesn't work sometimes. See
// the testdata/curlget.go program - the url needed to be base64 encoded
// since the escaping still wasn't sufficient.
//
// Explanation:
//
// https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
//
// The problem seems to be because we generate a bash script that calls
// another bash script, and I think something funky is going on when a
// `call` is issued inside bash, that the previous guide doesn't cover.
// There is some information here, which suggests replacing all % with %%,
// but although that solved the issue with the curlget test failure
// (TestTaskclusterProxy), it broke another that checks that env vars with
// funky characters can be properly encoded (TestWorkerLocation):
//
// https://www.robvanderwoude.com/files/testcallescapedstring_nt.txt
//
// So I've base64 encoded the URL arg of testdata/curlget.go, and leave
// this as it is for now, until we have a better idea what might be the
// perfect escaping sequence in the general case.
run := win32.CMDExeEscape(makeCmdLine(args))
if outputFile != "" {
run += ` > ` + syscall.EscapeArg(outputFile)
}
return run
}
// makeCmdLine builds a command line that can be passed to CreateProcess family of syscalls.
func makeCmdLine(args []string) string {
var s string
for _, v := range args {
if s != "" {
s += " "
}
s += syscall.EscapeArg(v)
}
return s
}
func copyTestdataFile(path string) []string {
return copyTestdataFileTo(path, path)
}
func copyTestdataFileTo(src, dest string) []string {
destFile := strings.Replace(dest, "/", "\\", -1)
sourceFile := filepath.Join(testdataDir, strings.Replace(src, "/", "\\", -1))
return []string{
run([]string{"if", "not", "exist", filepath.Dir(destFile), "mkdir", filepath.Dir(destFile)}, ""),
run([]string{"copy", sourceFile, destFile}, ""),
}
}
func singleCommandNoArgs(command string) []string {
return []string{command}
}