Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package tumble | 5 package tumble |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "net/http" | 9 "net/http" |
| 10 "net/http/httptest" | 10 "net/http/httptest" |
| 11 "os" | 11 "os" |
| 12 "strings" | 12 "strings" |
| 13 "time" | 13 "time" |
| 14 | 14 |
| 15 "github.com/julienschmidt/httprouter" | 15 "github.com/julienschmidt/httprouter" |
| 16 "github.com/luci/gae/impl/memory" | 16 "github.com/luci/gae/impl/memory" |
| 17 "github.com/luci/gae/service/datastore" | 17 "github.com/luci/gae/service/datastore" |
| 18 "github.com/luci/gae/service/taskqueue" | 18 "github.com/luci/gae/service/taskqueue" |
| 19 "github.com/luci/luci-go/common/clock" | 19 "github.com/luci/luci-go/common/clock" |
| 20 "github.com/luci/luci-go/common/clock/testclock" | 20 "github.com/luci/luci-go/common/clock/testclock" |
| 21 "github.com/luci/luci-go/common/cryptorand" | 21 "github.com/luci/luci-go/common/cryptorand" |
| 22 "github.com/luci/luci-go/common/logging" | 22 "github.com/luci/luci-go/common/logging" |
| 23 "github.com/luci/luci-go/common/logging/memlogger" | 23 "github.com/luci/luci-go/common/logging/memlogger" |
| 24 "github.com/luci/luci-go/server/router" | |
| 24 "github.com/luci/luci-go/server/settings" | 25 "github.com/luci/luci-go/server/settings" |
| 25 "golang.org/x/net/context" | 26 "golang.org/x/net/context" |
| 26 ) | 27 ) |
| 27 | 28 |
| 28 // Testing is a high-level testing object for testing applications that use | 29 // Testing is a high-level testing object for testing applications that use |
| 29 // tumble. | 30 // tumble. |
| 30 type Testing struct { | 31 type Testing struct { |
| 31 Service | 32 Service |
| 32 } | 33 } |
| 33 | 34 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 for _, tsk := range tsks { | 111 for _, tsk := range tsks { |
| 111 logging.Debugf(c, "found task: %v", tsk) | 112 logging.Debugf(c, "found task: %v", tsk) |
| 112 if tsk.ETA.After(clk.Now().UTC()) { | 113 if tsk.ETA.After(clk.Now().UTC()) { |
| 113 logging.Infof(c, "skipping task: ETA(%s): %s", tsk.ETA, tsk.Path) | 114 logging.Infof(c, "skipping task: ETA(%s): %s", tsk.ETA, tsk.Path) |
| 114 continue | 115 continue |
| 115 } | 116 } |
| 116 toks := strings.Split(tsk.Path, "/") | 117 toks := strings.Split(tsk.Path, "/") |
| 117 | 118 |
| 118 // Process the shard until a success or hard failure. | 119 // Process the shard until a success or hard failure. |
| 119 retryHTTP(c, func(rec *httptest.ResponseRecorder) { | 120 retryHTTP(c, func(rec *httptest.ResponseRecorder) { |
| 120 » » » t.ProcessShardHandler(c, rec, &http.Request{ | 121 » » » t.ProcessShardHandler(&router.Context{ |
| 121 » » » » Header: http.Header{"X-AppEngine-QueueName": []s tring{baseName}}, | 122 » » » » Context: c, |
| 122 » » » }, httprouter.Params{ | 123 » » » » Writer: rec, |
| 123 » » » » {Key: "shard_id", Value: toks[4]}, | 124 » » » » Request: &http.Request{ |
| 124 » » » » {Key: "timestamp", Value: toks[6]}, | 125 » » » » » Header: http.Header{"X-AppEngine-QueueNa me": []string{baseName}}, |
| 126 » » » » }, | |
| 127 » » » » Params: httprouter.Params{ | |
| 128 » » » » » {Key: "shard_id", Value: toks[4]}, | |
| 129 » » » » » {Key: "timestamp", Value: toks[6]}, | |
| 130 » » » » }, | |
| 125 }) | 131 }) |
| 126 }) | 132 }) |
| 127 | 133 |
| 128 if err := tq.Delete(tsk, baseName); err != nil { | 134 if err := tq.Delete(tsk, baseName); err != nil { |
| 129 panic(fmt.Errorf("Deleting task failed: %s", err)) | 135 panic(fmt.Errorf("Deleting task failed: %s", err)) |
| 130 } | 136 } |
| 131 ret++ | 137 ret++ |
| 132 } | 138 } |
| 133 return ret | 139 return ret |
| 134 } | 140 } |
| 135 | 141 |
| 136 // FireAllTasks will force all tumble shards to run in the future. | 142 // FireAllTasks will force all tumble shards to run in the future. |
| 137 func (t *Testing) FireAllTasks(c context.Context) { | 143 func (t *Testing) FireAllTasks(c context.Context) { |
| 138 retryHTTP(c, func(rec *httptest.ResponseRecorder) { | 144 retryHTTP(c, func(rec *httptest.ResponseRecorder) { |
| 139 // Fire all tasks until a success or hard failure. | 145 // Fire all tasks until a success or hard failure. |
| 140 » » t.FireAllTasksHandler(c, rec, &http.Request{ | 146 » » t.FireAllTasksHandler(&router.Context{ |
| 141 » » » Header: http.Header{"X-Appengine-Cron": []string{"true"} }, | 147 » » » Context: c, |
| 142 » » }, nil) | 148 » » » Writer: rec, |
| 149 » » » Request: &http.Request{ | |
| 150 » » » » Header: http.Header{"X-Appengine-Cron": []string {"true"}}, | |
| 151 » » » }, | |
| 152 » » » Params: nil, | |
|
iannucci
2016/06/13 19:23:29
can omit nil-initializers for structs.
| |
| 153 » » }) | |
| 143 }) | 154 }) |
| 144 } | 155 } |
| 145 | 156 |
| 146 // AdvanceTime advances the test clock enough so that Iterate will be able to | 157 // AdvanceTime advances the test clock enough so that Iterate will be able to |
| 147 // pick up tasks in the task queue. | 158 // pick up tasks in the task queue. |
| 148 func (t *Testing) AdvanceTime(c context.Context) { | 159 func (t *Testing) AdvanceTime(c context.Context) { |
| 149 clk := clock.Get(c).(testclock.TestClock) | 160 clk := clock.Get(c).(testclock.TestClock) |
| 150 cfg := t.GetConfig(c) | 161 cfg := t.GetConfig(c) |
| 151 toAdd := time.Duration(cfg.TemporalMinDelay) + time.Duration(cfg.Tempora lRoundFactor) + time.Second | 162 toAdd := time.Duration(cfg.TemporalMinDelay) + time.Duration(cfg.Tempora lRoundFactor) + time.Second |
| 152 logging.Infof(c, "adding %s to %s", toAdd, clk.Now().UTC()) | 163 logging.Infof(c, "adding %s to %s", toAdd, clk.Now().UTC()) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 lmsg := logging.Get(c).(*memlogger.MemLogger).Me ssages() | 211 lmsg := logging.Get(c).(*memlogger.MemLogger).Me ssages() |
| 201 panic(fmt.Errorf("HTTP non-transient error: %s: %#v", err, lmsg)) | 212 panic(fmt.Errorf("HTTP non-transient error: %s: %#v", err, lmsg)) |
| 202 } | 213 } |
| 203 logging.WithError(err).Warningf(c, "Transient error enco untered, retrying.") | 214 logging.WithError(err).Warningf(c, "Transient error enco untered, retrying.") |
| 204 | 215 |
| 205 default: | 216 default: |
| 206 panic(fmt.Errorf("HTTP error %d (%s): %s", rec.Code, htt p.StatusText(rec.Code), rec.Body.String())) | 217 panic(fmt.Errorf("HTTP error %d (%s): %s", rec.Code, htt p.StatusText(rec.Code), rec.Body.String())) |
| 207 } | 218 } |
| 208 } | 219 } |
| 209 } | 220 } |
| OLD | NEW |