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

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

Issue 2251623002: test-results: Get handler cleanup (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@x_3
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
OLDNEW
1 package frontend 1 package frontend
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "encoding/json" 5 "encoding/json"
6 "fmt" 6 "fmt"
7 "infra/appengine/test-results/model" 7 "infra/appengine/test-results/model"
8 "io" 8 "io"
9 "net/http" 9 "net/http"
10 "regexp" 10 "regexp"
(...skipping 17 matching lines...) Expand all
28 httpTimeFormat = time.RFC1123 28 httpTimeFormat = time.RFC1123
29 29
30 // httpNoTZTimeFormat is httpTimeFormat with the timezone removed. 30 // httpNoTZTimeFormat is httpTimeFormat with the timezone removed.
31 httpNoTZTimeFormat = "Mon, 02 Jan 2006 15:04:05" 31 httpNoTZTimeFormat = "Mon, 02 Jan 2006 15:04:05"
32 ) 32 )
33 33
34 // callbackNameRx matches start of strings that look like 34 // callbackNameRx matches start of strings that look like
35 // JavaScript function names. Not a comprehensive solution. 35 // JavaScript function names. Not a comprehensive solution.
36 var callbackNameRx = regexp.MustCompile(`^[A-Za-z0-9_]+$`) 36 var callbackNameRx = regexp.MustCompile(`^[A-Za-z0-9_]+$`)
37 37
38 // GetHandler is the HTTP handler for GET /testfile requests. 38 // getHandler is the HTTP handler for GET /testfile requests.
39 func GetHandler(ctx *router.Context) { 39 func getHandler(ctx *router.Context) {
40 c, w, r := ctx.Context, ctx.Writer, ctx.Request 40 c, w, r := ctx.Context, ctx.Writer, ctx.Request
41 if err := r.ParseForm(); err != nil { 41 if err := r.ParseForm(); err != nil {
42 http.Error(w, err.Error(), http.StatusInternalServerError) 42 http.Error(w, err.Error(), http.StatusInternalServerError)
43 logging.Errorf(c, "failed to parse form: %v", err) 43 logging.Errorf(c, "failed to parse form: %v", err)
44 return 44 return
45 } 45 }
46 46
47 params, err := NewURLParams(r.Form) 47 params, err := NewURLParams(r.Form)
48 if err != nil { 48 if err != nil {
49 e := fmt.Sprintf("failed to parse URL parameters: %+v: %v", para ms, err) 49 e := fmt.Sprintf("failed to parse URL parameters: %+v: %v", para ms, err)
(...skipping 18 matching lines...) Expand all
68 68
69 key, err := datastore.NewKeyEncoded(params.Key) 69 key, err := datastore.NewKeyEncoded(params.Key)
70 if err != nil { 70 if err != nil {
71 http.Error(w, err.Error(), http.StatusBadRequest) 71 http.Error(w, err.Error(), http.StatusBadRequest)
72 logging.Errorf(c, "failed to encode key: %v: %v", key, err) 72 logging.Errorf(c, "failed to encode key: %v: %v", key, err)
73 return 73 return
74 } 74 }
75 75
76 tf := model.TestFile{ID: key.IntID()} 76 tf := model.TestFile{ID: key.IntID()}
77 77
78 » if err := datastore.Get(c).Get(&tf); err == datastore.ErrNoSuchEntity { 78 » if err := datastore.Get(c).Get(&tf); err != nil {
79 » » http.Error(w, err.Error(), http.StatusNotFound) 79 » » if err == datastore.ErrNoSuchEntity {
80 » » logging.Errorf(c, "TestFile with ID %v not found: %v", key.IntID (), err) 80 » » » http.Error(w, err.Error(), http.StatusNotFound)
81 » » return 81 » » » logging.Errorf(c, "TestFile with ID %v not found: %v", k ey.IntID(), err)
82 » } else if err != nil { 82 » » » return
83 » » }
83 http.Error(w, err.Error(), http.StatusInternalServerError) 84 http.Error(w, err.Error(), http.StatusInternalServerError)
84 logging.Errorf(c, "failed to get TestFile with ID %v: %v", key.I ntID(), err) 85 logging.Errorf(c, "failed to get TestFile with ID %v: %v", key.I ntID(), err)
85 return 86 return
86 } 87 }
87 88
88 modTime, err := time.Parse(r.Header.Get("If-Modified-Since"), httpTimeFo rmat) 89 modTime, err := time.Parse(r.Header.Get("If-Modified-Since"), httpTimeFo rmat)
89 if err == nil && !tf.LastMod.After(modTime) { 90 if err == nil && !tf.LastMod.After(modTime) {
90 w.WriteHeader(http.StatusNotModified) 91 w.WriteHeader(http.StatusNotModified)
91 return 92 return
92 } 93 }
(...skipping 15 matching lines...) Expand all
108 logging.Errorf(c, "GetAll failed for query: %+v: %v", q, err) 109 logging.Errorf(c, "GetAll failed for query: %+v: %v", q, err)
109 return 110 return
110 } 111 }
111 if len(testFiles) == 0 { 112 if len(testFiles) == 0 {
112 e := fmt.Sprintf("no TestFile found for query: %+v", q) 113 e := fmt.Sprintf("no TestFile found for query: %+v", q)
113 http.Error(w, e, http.StatusNotFound) 114 http.Error(w, e, http.StatusNotFound)
114 logging.Errorf(c, e) 115 logging.Errorf(c, e)
115 return 116 return
116 } 117 }
117 118
118 args := templates.Args{
119 "Master": params.Master,
120 "Builder": params.Builder,
121 "TestType": params.TestType,
122 "BuildNumber": params.BuildNumber,
123 "Name": params.Name,
124 "Files": testFiles,
125 }
126
127 if params.Callback != "" { 119 if params.Callback != "" {
128 b, err := keysJSON(c, testFiles) 120 b, err := keysJSON(c, testFiles)
129 if err != nil { 121 if err != nil {
130 http.Error(w, err.Error(), http.StatusInternalServerErro r) 122 http.Error(w, err.Error(), http.StatusInternalServerErro r)
131 logging.Errorf(c, "failed to create callback JSON: %v: % v", testFiles, err) 123 logging.Errorf(c, "failed to create callback JSON: %v: % v", testFiles, err)
132 return 124 return
133 } 125 }
134 respondJSON(c, w, bytes.NewReader(b), testFiles[0].LastMod, para ms.Callback) 126 respondJSON(c, w, bytes.NewReader(b), testFiles[0].LastMod, para ms.Callback)
135 return 127 return
136 } 128 }
137 129
138 » templates.MustRender(c, w, "pages/showfilelist.html", args) 130 » templates.MustRender(c, w, "pages/showfilelist.html", templates.Args{
131 » » "Master": params.Master,
132 » » "Builder": params.Builder,
133 » » "TestType": params.TestType,
134 » » "BuildNumber": params.BuildNumber,
135 » » "Name": params.Name,
136 » » "Files": testFiles,
137 » })
139 } 138 }
140 139
141 func keysJSON(c context.Context, tfiles []*model.TestFile) ([]byte, error) { 140 func keysJSON(c context.Context, tfiles []*model.TestFile) ([]byte, error) {
142 type K struct { 141 type K struct {
143 Key string `json:"key"` 142 Key string `json:"key"`
144 } 143 }
145 keys := make([]K, len(tfiles)) 144 keys := make([]K, len(tfiles))
146 for i, tf := range tfiles { 145 for i, tf := range tfiles {
147 keys[i] = K{datastore.Get(c).KeyForObj(tf).Encode()} 146 keys[i] = K{datastore.Get(c).KeyForObj(tf).Encode()}
148 } 147 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 http.Error(w, err.Error(), http.StatusInternalServerErro r) 213 http.Error(w, err.Error(), http.StatusInternalServerErro r)
215 logging.Errorf(c, "failed to clean test results JSON: %v ", err) 214 logging.Errorf(c, "failed to clean test results JSON: %v ", err)
216 return 215 return
217 } 216 }
218 aggr := model.AggregateResult{Builder: params.Builder} 217 aggr := model.AggregateResult{Builder: params.Builder}
219 if err := json.NewDecoder(data).Decode(&aggr); err != nil { 218 if err := json.NewDecoder(data).Decode(&aggr); err != nil {
220 http.Error(w, err.Error(), http.StatusInternalServerErro r) 219 http.Error(w, err.Error(), http.StatusInternalServerErro r)
221 logging.Errorf(c, "failed to unmarshal test results JSON : %+v: %v", data, err) 220 logging.Errorf(c, "failed to unmarshal test results JSON : %+v: %v", data, err)
222 return 221 return
223 } 222 }
223
224 tl := aggr.ToTestList() 224 tl := aggr.ToTestList()
225 » » buf := &bytes.Buffer{} 225 » » buf := bytes.Buffer{}
226 » » if err := json.NewEncoder(buf).Encode(&tl); err != nil { 226 » » if err := json.NewEncoder(&buf).Encode(&tl); err != nil {
227 http.Error(w, err.Error(), http.StatusInternalServerErro r) 227 http.Error(w, err.Error(), http.StatusInternalServerErro r)
228 logging.Errorf(c, "failed to marshal test list JSON: %+v , %v", aggr.Tests, err) 228 logging.Errorf(c, "failed to marshal test list JSON: %+v , %v", aggr.Tests, err)
229 return 229 return
230 } 230 }
231 » » finalData = buf 231 » » finalData = &buf
232 } 232 }
233 233
234 respondJSON(c, w, finalData, tf.LastMod, params.Callback) 234 respondJSON(c, w, finalData, tf.LastMod, params.Callback)
235 } 235 }
236 236
237 // ErrNoMatches is returned when a query returns 0 entities. 237 // ErrNoMatches is returned when a query returns 0 entities.
238 type ErrNoMatches string 238 type ErrNoMatches string
239 239
240 func (e ErrNoMatches) Error() string { 240 func (e ErrNoMatches) Error() string {
241 return string(e) 241 return string(e)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 } 273 }
274 } 274 }
275 275
276 // wrapCallback returns an io.Reader that wraps the data in r in a 276 // wrapCallback returns an io.Reader that wraps the data in r in a
277 // JavaScript-style function call with the supplied name as the function name. 277 // JavaScript-style function call with the supplied name as the function name.
278 func wrapCallback(r io.Reader, name string) io.Reader { 278 func wrapCallback(r io.Reader, name string) io.Reader {
279 start := bytes.NewReader([]byte(name + "(")) 279 start := bytes.NewReader([]byte(name + "("))
280 end := bytes.NewReader([]byte(");")) 280 end := bytes.NewReader([]byte(");"))
281 return io.MultiReader(start, r, end) 281 return io.MultiReader(start, r, end)
282 } 282 }
OLDNEW
« no previous file with comments | « go/src/infra/appengine/test-results/frontend/builders.go ('k') | go/src/infra/appengine/test-results/frontend/get_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698