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

Side by Side Diff: go/src/infra/appengine/test-results/frontend/upload_test.go

Issue 2250043002: test-results: package frontend: Add delete keys task queue (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@xx_5
Patch Set: (Rebase) Created 4 years, 4 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 | « go/src/infra/appengine/test-results/frontend/upload.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package frontend 1 package frontend
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "encoding/json"
6 "infra/appengine/test-results/model"
5 "io" 7 "io"
6 "io/ioutil" 8 "io/ioutil"
7 "mime/multipart" 9 "mime/multipart"
8 "net/http" 10 "net/http"
9 "net/http/httptest" 11 "net/http/httptest"
12 "net/url"
10 "os" 13 "os"
11 "path/filepath" 14 "path/filepath"
12 "testing" 15 "testing"
13 16
14 "golang.org/x/net/context" 17 "golang.org/x/net/context"
15 18
16 "github.com/luci/gae/impl/memory" 19 "github.com/luci/gae/impl/memory"
17 "github.com/luci/gae/service/datastore" 20 "github.com/luci/gae/service/datastore"
18 "github.com/luci/luci-go/server/router" 21 "github.com/luci/luci-go/server/router"
19 . "github.com/smartystreets/goconvey/convey" 22 . "github.com/smartystreets/goconvey/convey"
20 ) 23 )
21 24
22 func withTestingContext(c *router.Context, next router.Handler) { 25 func TestUploadAndGetHandlers(t *testing.T) {
26 » t.Parallel()
27
23 ctx := memory.Use(context.Background()) 28 ctx := memory.Use(context.Background())
24 » ds := datastore.Get(ctx) 29 » testFileIdx, err := datastore.FindAndParseIndexYAML(filepath.Join("testd ata"))
25 » testFileIdx, err := datastore.FindAndParseIndexYAML(filepath.Join("..", "model", "testdata"))
26 if err != nil { 30 if err != nil {
27 panic(err) 31 panic(err)
28 } 32 }
33 ds := datastore.Get(ctx)
29 ds.Testable().AddIndexes(testFileIdx...) 34 ds.Testable().AddIndexes(testFileIdx...)
30 ds.Testable().CatchupIndexes()
31 35
32 » c.Context = ctx 36 » withTestingContext := func(c *router.Context, next router.Handler) {
33 » next(c) 37 » » c.Context = ctx
34 } 38 » » ds.Testable().CatchupIndexes()
35 39 » » next(c)
36 func TestUpload(t *testing.T) { 40 » }
37 » t.Parallel()
38 41
39 r := router.New() 42 r := router.New()
40 mw := router.NewMiddlewareChain(withTestingContext) 43 mw := router.NewMiddlewareChain(withTestingContext)
44 r.GET("/testfile", mw.Extend(templatesMiddleware()), getHandler)
41 r.POST("/testfile/upload", mw.Extend(withParsedUploadForm), uploadHandle r) 45 r.POST("/testfile/upload", mw.Extend(withParsedUploadForm), uploadHandle r)
42 srv := httptest.NewServer(r) 46 srv := httptest.NewServer(r)
43 client := &http.Client{} 47 client := &http.Client{}
44 48
45 » Convey("upload", t, func() { 49 » Convey("Upload and Get handlers", t, func() {
46 » » Convey("no matching aggregate file in datastore", func() { 50 » » Convey("upload full_results.json", func() {
47 var buf bytes.Buffer 51 var buf bytes.Buffer
48 multi := multipart.NewWriter(&buf) 52 multi := multipart.NewWriter(&buf)
49 // Form files. 53 // Form files.
50 f, err := os.Open(filepath.Join("testdata", "full_result s_0.json")) 54 f, err := os.Open(filepath.Join("testdata", "full_result s_0.json"))
51 So(err, ShouldBeNil) 55 So(err, ShouldBeNil)
52 defer f.Close() 56 defer f.Close()
53 multiFile, err := multi.CreateFormFile("file", "full_res ults.json") 57 multiFile, err := multi.CreateFormFile("file", "full_res ults.json")
54 So(err, ShouldBeNil) 58 So(err, ShouldBeNil)
55 _, err = io.Copy(multiFile, f) 59 _, err = io.Copy(multiFile, f)
56 So(err, ShouldBeNil) 60 So(err, ShouldBeNil)
57 // Form fields. 61 // Form fields.
58 fields := []struct { 62 fields := []struct {
59 key, val string 63 key, val string
60 }{ 64 }{
61 {"master", "chromium.chromiumos"}, 65 {"master", "chromium.chromiumos"},
62 {"builder", "test-builder"}, 66 {"builder", "test-builder"},
63 » » » » {"test_type", "test-type"}, 67 » » » » {"testtype", "test-type"},
64 } 68 }
65 for _, field := range fields { 69 for _, field := range fields {
66 f, err := multi.CreateFormField(field.key) 70 f, err := multi.CreateFormField(field.key)
67 So(err, ShouldBeNil) 71 So(err, ShouldBeNil)
68 _, err = f.Write([]byte(field.val)) 72 _, err = f.Write([]byte(field.val))
69 So(err, ShouldBeNil) 73 So(err, ShouldBeNil)
70 } 74 }
71 multi.Close() 75 multi.Close()
72 76
73 req, err := http.NewRequest("POST", srv.URL+"/testfile/u pload", &buf) 77 req, err := http.NewRequest("POST", srv.URL+"/testfile/u pload", &buf)
74 So(err, ShouldBeNil) 78 So(err, ShouldBeNil)
75 req.Header.Set("Content-Type", multi.FormDataContentType ()) 79 req.Header.Set("Content-Type", multi.FormDataContentType ())
76 resp, err := client.Do(req) 80 resp, err := client.Do(req)
77 So(err, ShouldBeNil) 81 So(err, ShouldBeNil)
78 defer resp.Body.Close() 82 defer resp.Body.Close()
79 So(resp.StatusCode, ShouldEqual, http.StatusOK) 83 So(resp.StatusCode, ShouldEqual, http.StatusOK)
80 84
81 b, err := ioutil.ReadAll(resp.Body) 85 b, err := ioutil.ReadAll(resp.Body)
82 So(err, ShouldBeNil) 86 So(err, ShouldBeNil)
83 So(string(b), ShouldEqual, "OK") 87 So(string(b), ShouldEqual, "OK")
88
89 // Get results.json for uploaded full_results.json
90 req, err = http.NewRequest("GET", srv.URL+"/testfile?"+u rl.Values{
91 "master": {"chromium.chromiumos"},
92 "builder": {"test-builder"},
93 "testtype": {"test-type"},
94 "name": {"results.json"},
95 }.Encode(), nil)
96 So(err, ShouldBeNil)
97 resp, err = client.Do(req)
98 So(err, ShouldBeNil)
99 defer resp.Body.Close()
100 So(resp.StatusCode, ShouldEqual, http.StatusOK)
101
102 var aggr model.AggregateResult
103 So(json.NewDecoder(resp.Body).Decode(&aggr), ShouldBeNil )
104 So(aggr, ShouldResemble, model.AggregateResult{
105 Version: model.ResultsVersion,
106 Builder: "test-builder",
107 BuilderInfo: &model.BuilderInfo{
108 SecondsEpoch: []int64{1406123456},
109 BuildNumbers: []model.Number{123},
110 ChromeRevs: []string{"67890"},
111 Tests: model.AggregateTest{
112 "Test1.testproc1": &model.Aggreg ateTestLeaf{
113 Results: []model.Result Summary{{1, "Q"}},
114 Runtimes: []model.Runtim eSummary{{1, 1}},
115 },
116 },
117 FailuresByType: map[string][]int{
118 "FAIL": {0},
119 "PASS": {1},
120 "SKIP": {0},
121 },
122 FailureMap: model.FailureLongNames,
123 },
124 })
125
126 // Get test list JSON for uploaded full_results.json
127 req, err = http.NewRequest("GET", srv.URL+"/testfile?"+u rl.Values{
128 "master": {"chromium.chromiumos"},
129 "builder": {"test-builder"},
130 "testtype": {"test-type"},
131 "name": {"results.json"},
132 "testlistjson": {"1"},
133 }.Encode(), nil)
134 So(err, ShouldBeNil)
135 resp, err = client.Do(req)
136 So(err, ShouldBeNil)
137 defer resp.Body.Close()
138 So(resp.StatusCode, ShouldEqual, http.StatusOK)
139
140 b, err = ioutil.ReadAll(resp.Body)
141 So(err, ShouldBeNil)
142 So(resp.Header.Get("Content-Type"), ShouldContainSubstri ng, "application/json")
143 So(bytes.TrimSpace(b), ShouldResemble, []byte(`{"test-bu ilder":{"tests":{"Test1.testproc1":{}}}}`))
144
145 // HTML response
146 req, err = http.NewRequest("GET", srv.URL+"/testfile?"+u rl.Values{
147 "master": {"chromium.chromiumos"},
148 "builder": {"test-builder"},
149 "testtype": {"test-type"},
150 "name": {"full_results.json"},
151 }.Encode(), nil)
152 So(err, ShouldBeNil)
153 resp, err = client.Do(req)
154 So(err, ShouldBeNil)
155 defer resp.Body.Close()
156 So(resp.StatusCode, ShouldEqual, http.StatusOK)
157 So(resp.Header.Get("Content-Type"), ShouldContainSubstri ng, "text/html")
84 }) 158 })
85 }) 159 })
86 } 160 }
161
162 func TestUploadTestFile(t *testing.T) {
163 t.Parallel()
164
165 Convey("uploadTestFile", t, func() {
166 Convey("data too large to fit in single datastore blob", func() {
167 ctx := memory.Use(context.Background())
168 ctx = SetUploadParams(ctx, &UploadParams{
169 Master: "foo",
170 Builder: "bar",
171 TestType: "baz",
172 })
173 data, err := ioutil.ReadFile(filepath.Join("testdata", " full_results_0.json"))
174 So(err, ShouldBeNil)
175 data = bytes.TrimSpace(data)
176 So(uploadTestFile(ctx, bytes.NewReader(data), "full_resu lts.json"), ShouldBeNil)
177
178 Convey("get uploaded data", func() {
179 datastore.Get(ctx).Testable().CatchupIndexes()
180 q := datastore.NewQuery("TestFile")
181 q = q.Eq("master", "foo")
182 q = q.Eq("builder", "bar")
183 q = q.Eq("test_type", "baz")
184 q = q.Eq("name", "full_results.json")
185 tf, err := getFirstTestFile(ctx, q)
186 So(err, ShouldBeNil)
187
188 So(tf.GetData(ctx), ShouldBeNil)
189 b, err := ioutil.ReadAll(tf.Data)
190 So(err, ShouldBeNil)
191 So(bytes.TrimSpace(b), ShouldResemble, data)
192 })
193 })
194 })
195 }
196
197 func TestUpdateIncremental(t *testing.T) {
198 t.Parallel()
199
200 Convey("updateIncremental", t, func() {
201 Convey("simple: updates corresponding aggregate files", func() {
202 ctx := memory.Use(context.Background())
203 idx, err := datastore.FindAndParseIndexYAML(filepath.Joi n("testdata"))
204 So(err, ShouldBeNil)
205 ds := datastore.Get(ctx)
206 ds.Testable().AddIndexes(idx...)
207 ds.Testable().CatchupIndexes()
208
209 data, err := ioutil.ReadFile(filepath.Join("testdata", " results_0.json"))
210 So(err, ShouldBeNil)
211 var orig model.AggregateResult
212 So(json.Unmarshal(data, &orig), ShouldBeNil)
213 resultsTf := model.TestFile{
214 Name: "results.json",
215 Master: "chromium.swarm",
216 TestType: "content_unittests",
217 Builder: "Linux Swarm",
218 BuildNumber: -1,
219 Data: bytes.NewReader(data),
220 }
221 So(resultsTf.PutData(ctx), ShouldBeNil)
222 So(ds.Put(&resultsTf), ShouldBeNil)
223 ds.Testable().CatchupIndexes()
224
225 incr := model.AggregateResult{
226 Builder: "Linux Swarm",
227 BuilderInfo: &model.BuilderInfo{
228 BuildNumbers: []model.Number{7399},
229 },
230 }
231 So(updateIncremental(SetUploadParams(ctx, &UploadParams{
232 Master: "chromium.swarm",
233 TestType: "content_unittests",
234 Builder: "Linux Swarm",
235 }), &incr), ShouldBeNil)
236
237 Convey("updates without error", func() {
238 ds.Testable().CatchupIndexes()
239 q := datastore.NewQuery("TestFile")
240 q = q.Eq("master", "chromium.swarm")
241 q = q.Eq("test_type", "content_unittests")
242 q = q.Eq("builder", "Linux Swarm")
243 q = q.Eq("name", "results.json")
244 tf, err := getFirstTestFile(ctx, q)
245 So(err, ShouldBeNil)
246
247 So(tf.GetData(ctx), ShouldBeNil)
248 var updated model.AggregateResult
249 So(json.NewDecoder(tf.Data).Decode(&updated), Sh ouldBeNil)
250
251 // TODO(nishanths): also check `updated` ShouldR esemble `expected`.
252 })
253 })
254 })
255 }
OLDNEW
« no previous file with comments | « go/src/infra/appengine/test-results/frontend/upload.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698