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 testScheduleSubdivideChildren(self):
    dummy_url = object()
    dummy_id = object()
    self.mox.StubOutWithMock(taskqueue, 'add')
    self.stubs.Set(baker, '_GetBakerURL', lambda _: dummy_url)
    mock_key = self.mox.CreateMockAnything()
    mock_key.id = lambda: dummy_id
    mock_parent = self.mox.CreateMock(model.Division)
    mock_parent.key = lambda: mock_key

    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 90, 'south': 0, 'east': 40, 'west': 10
    }).InAnyOrder(1)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -90, 'east': 40, 'west': 10
    }).InAnyOrder(1)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 90, 'south': 0, 'east': 10, 'west': -20
    }).InAnyOrder(1)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -90, 'east': 10, 'west': -20
    }).InAnyOrder(1)

    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 90, 'south': 45, 'east': 40, 'west': -20
    }).InAnyOrder(2)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 45, 'south': 0, 'east': 40, 'west': 10
    }).InAnyOrder(2)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 45, 'south': 0, 'east': 10, 'west': -20
    }).InAnyOrder(2)

    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -45, 'east': 40, 'west': 10
    }).InAnyOrder(3)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -45, 'east': 10, 'west': -20
    }).InAnyOrder(3)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': -45, 'south': -90, 'east': 40, 'west': -20
    }).InAnyOrder(3)

    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 40, 'south': 0, 'east': 90, 'west': 0
    }).InAnyOrder(4)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -40, 'east': 90, 'west': 0
    }).InAnyOrder(4)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 40, 'south': 0, 'east': 180, 'west': 90
    }).InAnyOrder(4)
    taskqueue.add(url=dummy_url, params={
        'stage': 'subdivide', 'parent': dummy_id,
        'north': 0, 'south': -40, 'east': 180, 'west': 90
    }).InAnyOrder(4)

    self.mox.ReplayAll()

    # Touches both poles; 4 slices.
    baker._ScheduleSubdivideChildren(object(), 90, -90, 40, -20, mock_parent)
    # Touches one pole; 3 slices.
    baker._ScheduleSubdivideChildren(object(), 90, 0, 40, -20, mock_parent)
    baker._ScheduleSubdivideChildren(object(), 0, -90, 40, -20, mock_parent)
    # Touches no poles; 4 slices.
    baker._ScheduleSubdivideChildren(object(), 40, -40, 180, 0, mock_parent)