def testSubdivideInterruptAfterSave(self):
    self.mox.StubOutWithMock(model.Entity, 'bounding_box_fetch')
    self.mox.StubOutWithMock(taskqueue, 'add')
    dummy_url = object()
    self.stubs.Set(baker, '_GetBakerURL', lambda _: dummy_url)
    layer = model.Layer(name='a', world='earth', auto_managed=False)
    layer.put()
    mock_entity = self.mox.CreateMockAnything()
    mock_entity.key = lambda: mock_key
    mock_entity.baked = False
    mock_key = self.mox.CreateMockAnything()
    mock_key.id = lambda: 42

    @mox.Func
    def VerifyArgs(args):
      self.assertEqual(args['stage'], 'subdivide')
      self.assertEqual(args['retry_division'],
                       model.Division.all().get().key().id())
      self.assertEqual(args['retry_has_children'], '')
      return True

    ignore = mox.IgnoreArg()
    model.Entity.bounding_box_fetch(ignore, ignore, ignore).AndReturn(
        [mock_entity])
    mock_entity.put().AndRaise(db.Error)
    taskqueue.add(url=dummy_url, params=VerifyArgs)

    self.mox.ReplayAll()
    baker._Subdivide(layer, 0.0, 0.0, 0.0, 0.0, None, None, False)
  def testSubdivideRetrySuccess(self):
    self.mox.StubOutWithMock(baker, '_ScheduleSubdivideChildren')
    self.mox.StubOutWithMock(model.Entity, 'get_by_id')
    layer = model.Layer(name='a', world='earth', auto_managed=True)
    layer.put()
    mock_division = self.mox.CreateMock(model.Division)
    mock_division.entities = object()
    mock_division.north = 1
    mock_division.south = 2
    mock_division.east = 3
    mock_division.west = 4
    mock_entities = [self.mox.CreateMock(model.Entity) for _ in xrange(3)]
    mock_entities[0].baked = False
    mock_entities[1].baked = True
    mock_entities[2].baked = False

    model.Entity.get_by_id(mock_division.entities).AndReturn(mock_entities)
    mock_entities[0].put()
    mock_entities[2].put()
    mock_division.put()
    mock_division.GenerateKML()
    baker._ScheduleSubdivideChildren(layer, 1, 2, 3, 4, mock_division)

    self.mox.ReplayAll()
    baker._Subdivide(layer, None, None, None, None, None, mock_division, True)
    self.assertEqual(mock_entities[0].baked, True)
    self.assertEqual(mock_entities[1].baked, True)
    self.assertEqual(mock_entities[2].baked, True)
    self.assertEqual(mock_division.baked, True)
  def testSubdivideFreshSuccessWithMaximumResults(self):
    self.mox.StubOutWithMock(baker, '_ScheduleSubdivideChildren')
    self.mox.StubOutWithMock(model, 'Division')
    self.mox.StubOutWithMock(model.Entity, 'bounding_box_fetch')
    mock_layer = self.mox.CreateMock(model.Layer)
    mock_layer.division_set = self.mox.CreateMockAnything()
    mock_layer.entity_set = self.mox.CreateMockAnything()
    mock_layer.division_size = 41
    mock_division = self.mox.CreateMockAnything()
    mock_parent = self.mox.CreateMockAnything()
    max_results = int(41 * (1 + settings.DIVISION_SIZE_GROWTH_LIMIT)) + 1
    mock_entities = [self.mox.CreateMockAnything() for _ in xrange(max_results)]
    for mock_entity in mock_entities:
      mock_entity.baked = False
    mock_query = self.mox.CreateMockAnything()
    dummy_ordered_query = object()
    dummy_id = object()

    @mox.Func
    def VerifyBox(box):
      self.assertEqual(box.north, 4)
      self.assertEqual(box.south, 3)
      self.assertEqual(box.east, 2)
      self.assertEqual(box.west, 1)
      return True

    mock_layer.division_set.filter('north', 4).AndReturn(
        mock_layer.division_set)
    mock_layer.division_set.filter('south', 3).AndReturn(
        mock_layer.division_set)
    mock_layer.division_set.filter('east', 2).AndReturn(mock_layer.division_set)
    mock_layer.division_set.filter('west', 1).AndReturn(mock_layer.division_set)
    mock_layer.division_set.get().AndReturn(None)

    mock_layer.entity_set.filter('baked', None).AndReturn(mock_query)
    mock_query.order('-priority').AndReturn(dummy_ordered_query)
    model.Entity.bounding_box_fetch(
        dummy_ordered_query, VerifyBox, max_results).AndReturn(mock_entities)
    for mock_entity in mock_entities[:41]:
      mock_entity.key().AndReturn(mock_entity)
      mock_entity.id().AndReturn(dummy_id)
    dummy_ids = [dummy_id for _ in xrange(41)]
    model.Division(layer=mock_layer, north=4, south=3, east=2, west=1,
                   entities=dummy_ids, parent_division=mock_parent,
                   baked=False).AndReturn(mock_division)
    mock_division.put()
    for mock_entity in mock_entities[:41]:
      mock_entity.put()
    mock_parent.ClearCache()
    mock_division.put()
    mock_division.GenerateKML()
    baker._ScheduleSubdivideChildren(mock_layer, 4, 3, 2, 1, mock_division)

    self.mox.ReplayAll()
    baker._Subdivide(mock_layer, 4, 3, 2, 1, mock_parent, None, False)
    self.assertEqual(mock_entities[0].baked, True)
    self.assertEqual(mock_entities[1].baked, True)
    self.assertEqual(mock_entities[2].baked, True)
    self.assertEqual(mock_division.baked, True)
  def testSubdivideCancelRerun(self):
    self.mox.StubOutWithMock(taskqueue, 'add')
    mock_layer = self.mox.CreateMock(model.Layer)
    mock_layer.division_set = self.mox.CreateMockAnything()
    mock_query = self.mox.CreateMockAnything()

    mock_layer.division_set.filter('north', 1).AndReturn(mock_query)
    mock_query.filter('south', 2).AndReturn(mock_query)
    mock_query.filter('east', 3).AndReturn(mock_query)
    mock_query.filter('west', 4).AndReturn(mock_query)
    mock_query.get().AndReturn(object())

    self.mox.ReplayAll()
    baker._Subdivide(mock_layer, 1, 2, 3, 4, None, None, False)
  def testUpdate(self):
    self.mox.StubOutWithMock(baker, '_PrepareLayerForBaking')
    self.mox.StubOutWithMock(baker, '_CheckIfLayerIsDone')
    self.mox.StubOutWithMock(baker, '_Subdivide')
    self.mox.StubOutWithMock(model.Division, 'get_by_id')
    handler = baker.BakerApprentice()
    dummy_layer = object()
    dummy_parent = object()
    dummy_retry_division = object()

    baker._PrepareLayerForBaking(dummy_layer)

    baker._CheckIfLayerIsDone(dummy_layer)

    model.Division.get_by_id(123).AndReturn(dummy_parent)
    model.Division.get_by_id(456).AndReturn(dummy_retry_division)
    baker._Subdivide(dummy_layer, 1.23, 4.56, 7.89, 0.36,
                     dummy_parent, dummy_retry_division, False)

    self.mox.ReplayAll()

    handler.request = {'stage': 'invalid'}
    self.assertRaises(util.BadRequest, handler.Update, dummy_layer)

    handler.request = {'stage': 'setup'}
    handler.Update(dummy_layer)

    handler.request = {'stage': 'monitor'}
    handler.Update(dummy_layer)

    handler.request = {
        'stage': 'subdivide',
        'north': '1.23',
        'south': '4.56',
        'east': '7.89',
        'west': '0.36',
        'parent': '123',
        'retry_division': '456',
        'retry_has_children': '',
    }
    handler.Update(dummy_layer)