247
250
err = s.collection.FindId("1").One(&found)
248
251
c.Assert(found, gc.DeepEquals, doc)
254
func (s *txnSuite) TestRunFailureIntermittentUnexpectedMessage(c *gc.C) {
255
runner := jujutxn.NewRunner(jujutxn.RunnerParams{})
256
fake := &fakeRunner{errors: []error{errors.New("unexpected message")}}
257
jujutxn.SetRunnerFunc(runner, fake.new)
259
// Doesn't matter what this returns as long as it isn't an error.
260
buildTxn := func(attempt int) ([]txn.Op, error) {
264
err := runner.Run(buildTxn)
265
c.Check(err, gc.Equals, nil)
266
c.Check(tries, gc.Equals, 2)
269
func (s *txnSuite) TestRunFailureAlwaysUnexpectedMessage(c *gc.C) {
270
runner := jujutxn.NewRunner(jujutxn.RunnerParams{})
271
fake := &fakeRunner{errors: []error{
272
errors.New("unexpected message"),
273
errors.New("unexpected message"),
274
errors.New("unexpected message"),
275
errors.New("unexpected message"),
277
jujutxn.SetRunnerFunc(runner, fake.new)
279
// Doesn't matter what this returns as long as it isn't an error.
280
buildTxn := func(attempt int) ([]txn.Op, error) {
284
err := runner.Run(buildTxn)
285
c.Check(err, gc.ErrorMatches, "unexpected message")
286
c.Check(tries, gc.Equals, 3)
289
type fakeRunner struct {
294
// Since a new transaction runner is created each time the code
295
// is retried, we want to have a single source of errors, so make the
296
// fake a factory that returns itself.
297
func (f *fakeRunner) new() jujutxn.TxnRunner {
301
func (f *fakeRunner) Run([]txn.Op, bson.ObjectId, interface{}) error {
302
if len(f.errors) == 0 {
306
f.errors = f.errors[1:]