forked from taskcluster/taskcluster
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper_broken_on_docker_test.go
171 lines (156 loc) · 5.99 KB
/
helper_broken_on_docker_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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//go:build !docker
package main
import (
"crypto/sha256"
"encoding/hex"
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/taskcluster/httpbackoff/v3"
tcclient "github.com/taskcluster/taskcluster/v47/clients/client-go"
"github.com/taskcluster/taskcluster/v47/clients/client-go/tcqueue"
)
func checkSHA256(t *testing.T, sha256Hex string, file string) {
hasher := sha256.New()
f, err := os.Open(file)
if err != nil {
t.Fatal(err)
}
defer f.Close()
if _, err := io.Copy(hasher, f); err != nil {
t.Fatal(err)
}
if actualSHA256Hex := hex.EncodeToString(hasher.Sum(nil)); actualSHA256Hex != sha256Hex {
t.Errorf("Expected file %v to have SHA256 %v but it was %v", file, sha256Hex, actualSHA256Hex)
}
}
func CancelTask(t *testing.T) (td *tcqueue.TaskDefinitionRequest, payload GenericWorkerPayload) {
// resolvetask is a go binary; source is in resolvetask subdirectory, binary is built in CI
// but if running test manually, you may need to explicitly build it first.
command := singleCommandNoArgs("resolvetask")
payload = GenericWorkerPayload{
Command: command,
MaxRunTime: 300,
}
fullCreds := config.Credentials()
td = testTask(t)
tempCreds, err := fullCreds.CreateNamedTemporaryCredentials("project/taskcluster:generic-worker-tester/"+t.Name(), time.Minute, "queue:cancel-task:"+td.SchedulerID+"/"+td.TaskGroupID+"/*")
if err != nil {
t.Fatalf("%v", err)
}
payload.Env = map[string]string{
"TASKCLUSTER_CLIENT_ID": tempCreds.ClientID,
"TASKCLUSTER_ACCESS_TOKEN": tempCreds.AccessToken,
"TASKCLUSTER_CERTIFICATE": tempCreds.Certificate,
"TASKCLUSTER_ROOT_URL": config.RootURL,
}
for _, envVar := range []string{
"PATH",
"GOPATH",
"GOROOT",
} {
if v, exists := os.LookupEnv(envVar); exists {
payload.Env[envVar] = v
}
}
return
}
type ArtifactTraits struct {
Extracts []string
ContentType string
ContentEncoding string
Expires tcclient.Time
}
type ExpectedArtifacts map[string]ArtifactTraits
func (expectedArtifacts ExpectedArtifacts) Validate(t *testing.T, taskID string, run int) {
queue := serviceFactory.Queue(nil, config.RootURL)
artifacts, err := queue.ListArtifacts(taskID, strconv.Itoa(run), "", "")
if err != nil {
t.Fatalf("Error listing artifacts: %v", err)
}
actualArtifacts := make(map[string]struct {
ContentType string `json:"contentType"`
Expires tcclient.Time `json:"expires"`
Name string `json:"name"`
StorageType string `json:"storageType"`
}, len(artifacts.Artifacts))
for _, actualArtifact := range artifacts.Artifacts {
actualArtifacts[actualArtifact.Name] = actualArtifact
}
for artifact, expected := range expectedArtifacts {
if actual, ok := actualArtifacts[artifact]; ok {
// link artifacts do not have content types
if actual.StorageType != "link" {
if actual.ContentType != expected.ContentType {
t.Errorf("Artifact %s should have mime type '%v' but has '%s'", artifact, expected.ContentType, actual.ContentType)
}
}
if !time.Time(expected.Expires).IsZero() {
if actual.Expires.String() != expected.Expires.String() {
t.Errorf("Artifact %s should have expiry '%s' but has '%s'", artifact, expected.Expires, actual.Expires)
}
}
} else {
t.Errorf("Artifact '%s' not created", artifact)
}
b, rawResp, resp, url := getArtifactContentWithResponses(t, taskID, artifact)
defer resp.Body.Close()
for _, requiredSubstring := range expected.Extracts {
if !strings.Contains(string(b), requiredSubstring) {
t.Errorf("Artifact '%s': Could not find substring %q in '%s'", artifact, requiredSubstring, string(b))
}
}
if actualContentEncoding := rawResp.Header.Get("Content-Encoding"); actualContentEncoding != expected.ContentEncoding {
t.Fatalf("Expected Content-Encoding %q but got Content-Encoding %q for artifact %q from url %v", expected.ContentEncoding, actualContentEncoding, artifact, url)
}
if actualContentType := resp.Header.Get("Content-Type"); actualContentType != expected.ContentType {
t.Fatalf("Content-Type in Signed URL %v response (%v) does not match Content-Type of artifact (%v)", url, actualContentType, expected.ContentType)
}
}
}
// getArtifactContentWithResponses downloads the given artifact, failing the
// test if this is not possible. It returns responses for both a "raw" fetch
// (without compression) and a fetch potentially automatically decoding any
// content-encoding. This only works for S3 artifacts, and is only used to
// test content-encoding.
func getArtifactContentWithResponses(t *testing.T, taskID string, artifact string) ([]byte, *http.Response, *http.Response, *url.URL) {
queue := serviceFactory.Queue(config.Credentials(), config.RootURL)
url, err := queue.GetLatestArtifact_SignedURL(taskID, artifact, 10*time.Minute)
if err != nil {
t.Fatalf("Error trying to fetch artifacts from Amazon...\n%s", err)
}
t.Logf("Getting from url %v", url.String())
// need to do this so Content-Encoding header isn't swallowed by Go for test later on
tr := &http.Transport{
DisableCompression: true,
}
client := &http.Client{Transport: tr}
rawResp, _, err := httpbackoff.ClientGet(client, url.String())
if err != nil {
t.Fatalf("Error trying to fetch decompressed artifact from signed URL %s ...\n%s", url.String(), err)
}
resp, _, err := httpbackoff.Get(url.String())
if err != nil {
t.Fatalf("Error trying to fetch artifact from signed URL %s ...\n%s", url.String(), err)
}
b, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Error trying to read response body of artifact from signed URL %s ...\n%s", url.String(), err)
}
return b, rawResp, resp, url
}
// getArtifactContent downloads the given artifact's content,
// failing the test if this is not possible.
func getArtifactContent(t *testing.T, taskID string, artifact string) []byte {
queue := serviceFactory.Queue(config.Credentials(), config.RootURL)
buf, _, _, err := queue.DownloadArtifactToBuf(taskID, -1, artifact)
if err != nil {
t.Fatalf("Error trying to fetch artifact:\n%e", err)
}
return buf
}