def _setup_cells(self): """Setup a normal cellsv2 environment. This sets up the CellDatabase fixture with two cells, one cell0 and one normal cell. CellMappings are created for both so that cells-aware code can find those two databases. """ celldbs = nova_fixtures.CellDatabases() celldbs.add_cell_database(objects.CellMapping.CELL0_UUID) celldbs.add_cell_database(uuids.cell1, default=True) self.useFixture(celldbs) ctxt = context.get_context() fake_transport = 'fake://nowhere/' c0 = objects.CellMapping( context=ctxt, uuid=objects.CellMapping.CELL0_UUID, name='cell0', transport_url=fake_transport, database_connection=objects.CellMapping.CELL0_UUID) c0.create() c1 = objects.CellMapping( context=ctxt, uuid=uuids.cell1, name=CELL1_NAME, transport_url=fake_transport, database_connection=uuids.cell1) c1.create() self.cell_mappings = {cm.name: cm for cm in (c0, c1)}
def setUp(self): super(ComputeHostAPIMultiCellTestCase, self).setUp() self.host_api = compute_api.HostAPI() self.useFixture(nova_fixtures.Database(database='api')) celldbs = nova_fixtures.CellDatabases() celldbs.add_cell_database(objects.CellMapping.CELL0_UUID) celldbs.add_cell_database(uuids.cell1, default=True) celldbs.add_cell_database(uuids.cell2) self.useFixture(celldbs) self.ctxt = context.get_admin_context() cell0 = objects.CellMapping( context=self.ctxt, uuid=objects.CellMapping.CELL0_UUID, database_connection=objects.CellMapping.CELL0_UUID, transport_url='none:///') cell0.create() cell1 = objects.CellMapping(context=self.ctxt, uuid=uuids.cell1, database_connection=uuids.cell1, transport_url='none:///') cell1.create() cell2 = objects.CellMapping(context=self.ctxt, uuid=uuids.cell2, database_connection=uuids.cell2, transport_url='none:///') cell2.create() self.cell_mappings = (cell0, cell1, cell2)
def test_populate_user_id_instance_get_fail(self, mock_inst_get): cells = [] celldbs = fixtures.CellDatabases() # Create two cell databases and map them for uuid in (uuidsentinel.cell1, uuidsentinel.cell2): cm = cell_mapping.CellMapping(context=self.context, uuid=uuid, database_connection=uuid, transport_url='fake://') cm.create() cells.append(cm) celldbs.add_cell_database(uuid) self.useFixture(celldbs) # Create one instance per cell for cell in cells: with context.target_cell(self.context, cell) as cctxt: inst = instance.Instance( cctxt, project_id=self.context.project_id, user_id=self.context.user_id) inst.create() create_mapping(project_id=self.context.project_id, user_id=None, cell_id=cell.id, instance_uuid=inst.uuid) # Simulate the first cell is down/has some error mock_inst_get.side_effect = [test.TestingException(), instance.InstanceList(objects=[inst])] found, done = instance_mapping.populate_user_id(self.context, 1000) # Verify we continue to the next cell when a down/error cell is # encountered. self.assertEqual(2, found) self.assertEqual(1, done)
def setUp(self): super(CellDatabasesTestCase, self).setUp() self.useFixture(nova_fixtures.Database(database='api')) fix = nova_fixtures.CellDatabases() fix.add_cell_database('blah') fix.add_cell_database('wat') self.useFixture(fix)
def setUp(self): super(QuotaTestCase, self).setUp() self.useFixture(nova_fixtures.SpawnIsSynchronousFixture()) self.useFixture(nova_fixtures.Database(database='api')) fix = nova_fixtures.CellDatabases() fix.add_cell_database('cell1') fix.add_cell_database('cell2') self.useFixture(fix)
def setUp(self): super(CellDatabasesTestCase, self).setUp() self.useFixture(nova_fixtures.Database(database='api')) fix = nova_fixtures.CellDatabases() fix.add_cell_database('cell0') fix.add_cell_database('cell1') fix.add_cell_database('cell2') self.useFixture(fix) self.context = context.RequestContext('fake-user', 'fake-project')
def _setup_cells(self): # NOTE(danms): Override the base class's cell setup so we can have two self.cells = fixtures.CellDatabases() self.cells.add_cell_database(uuidsentinel.cell1, default=True) self.cells.add_cell_database(uuidsentinel.cell2) self.useFixture(self.cells) cm = objects.CellMapping(context=self.context, uuid=uuidsentinel.cell1, name='cell1', transport_url='fake://nowhere/', database_connection=uuidsentinel.cell1) cm.create() cm = objects.CellMapping(context=self.context, uuid=uuidsentinel.cell2, name='cell2', transport_url='fake://nowhere/', database_connection=uuidsentinel.cell2) cm.create()
def _setup_cells(self): ctxt = context.get_admin_context() self.celldbs = fixtures.CellDatabases() cells = [] for uuid in (uuids.cell1, uuids.cell2, uuids.cell3): cm = objects.CellMapping(context=ctxt, uuid=uuid, database_connection=uuid, transport_url='fake://') cm.create() cells.append(cm) self.celldbs.add_cell_database(uuid) self.useFixture(self.celldbs) for cell in cells: for i in (1, 2, 3): # Make one host in each cell unmapped mapped = 0 if i == 2 else 1 host = 'host-%s-%i' % (cell.uuid, i) if mapped: hm = objects.HostMapping(context=ctxt, cell_mapping=cell, host=host) hm.create() with context.target_cell(ctxt, cell): cn = objects.ComputeNode(context=ctxt, vcpus=1, memory_mb=1, local_gb=1, vcpus_used=0, memory_mb_used=0, local_gb_used=0, hypervisor_type='danvm', hypervisor_version='1', cpu_info='foo', cpu_allocation_ratio=1.0, ram_allocation_ratio=1.0, disk_allocation_ratio=1.0, mapped=mapped, host=host) cn.create()
def setUp(self): super(ServerGroupTestV21, self).setUp() self._setup_controller() self.req = fakes.HTTPRequest.blank('') self.admin_req = fakes.HTTPRequest.blank('', use_admin_context=True) self.foo_req = fakes.HTTPRequest.blank('', project_id='foo') self.policy = self.useFixture(policy_fixture.RealPolicyFixture()) self.useFixture(fixtures.Database(database='api')) cells = fixtures.CellDatabases() cells.add_cell_database(uuidsentinel.cell1) cells.add_cell_database(uuidsentinel.cell2) self.useFixture(cells) ctxt = context.get_admin_context() self.cells = {} for uuid in (uuidsentinel.cell1, uuidsentinel.cell2): cm = objects.CellMapping(context=ctxt, uuid=uuid, database_connection=uuid, transport_url=uuid) cm.create() self.cells[cm.uuid] = cm
def _setup_cells(self): """Setup a normal cellsv2 environment. This sets up the CellDatabase fixture with two cells, one cell0 and one normal cell. CellMappings are created for both so that cells-aware code can find those two databases. """ celldbs = nova_fixtures.CellDatabases() ctxt = context.get_context() fake_transport = 'fake://nowhere/' c0 = objects.CellMapping( context=ctxt, uuid=objects.CellMapping.CELL0_UUID, name='cell0', transport_url=fake_transport, database_connection=objects.CellMapping.CELL0_UUID) c0.create() self.cell_mappings[c0.name] = c0 celldbs.add_cell_database(objects.CellMapping.CELL0_UUID) for x in range(self.NUMBER_OF_CELLS): name = 'cell%i' % (x + 1) uuid = getattr(uuids, name) cell = objects.CellMapping( context=ctxt, uuid=uuid, name=name, transport_url=fake_transport, database_connection=uuid) cell.create() self.cell_mappings[name] = cell # cell1 is the default cell celldbs.add_cell_database(uuid, default=(x == 0)) self.useFixture(celldbs)
def test_populate_user_id(self, mock_log_warning): cells = [] celldbs = fixtures.CellDatabases() # Create two cell databases and map them for uuid in (uuidsentinel.cell1, uuidsentinel.cell2): cm = cell_mapping.CellMapping(context=self.context, uuid=uuid, database_connection=uuid, transport_url='fake://') cm.create() cells.append(cm) celldbs.add_cell_database(uuid) self.useFixture(celldbs) # Create 5 instances per cell for cell in cells: for i in range(0, 5): with context.target_cell(self.context, cell) as cctxt: inst = instance.Instance( cctxt, project_id=self.context.project_id, user_id=self.context.user_id) inst.create() # Make every other mapping have a NULL user_id # Will be a total of four mappings with NULL user_id user_id = self.context.user_id if i % 2 == 0 else None create_mapping(project_id=self.context.project_id, user_id=user_id, cell_id=cell.id, instance_uuid=inst.uuid) # Create a SOFT_DELETED instance with a user_id=None instance mapping. # This should get migrated. with context.target_cell(self.context, cells[0]) as cctxt: inst = instance.Instance(cctxt, project_id=self.context.project_id, user_id=self.context.user_id, vm_state=vm_states.SOFT_DELETED) inst.create() create_mapping(project_id=self.context.project_id, user_id=None, cell_id=cells[0].id, instance_uuid=inst.uuid, queued_for_delete=True) # Create a deleted instance with a user_id=None instance mapping. # This should get migrated. with context.target_cell(self.context, cells[1]) as cctxt: inst = instance.Instance(cctxt, project_id=self.context.project_id, user_id=self.context.user_id) inst.create() inst.destroy() create_mapping(project_id=self.context.project_id, user_id=None, cell_id=cells[1].id, instance_uuid=inst.uuid, queued_for_delete=True) # Create an instance mapping for an instance not yet scheduled. It # should not get migrated because we won't know what user_id to use. unscheduled = create_mapping(project_id=self.context.project_id, user_id=None, cell_id=None) # Create two instance mappings for instances that no longer exist. # Example: residue from a manual cleanup or after a periodic compute # purge and before a database archive. This record should not get # migrated. nonexistent = [] for i in range(2): nonexistent.append( create_mapping(project_id=self.context.project_id, user_id=None, cell_id=cells[i].id, instance_uuid=uuidutils.generate_uuid())) # Create an instance mapping simulating a virtual interface migration # marker instance which has had map_instances run on it. # This should not be found by the migration. create_mapping(project_id=virtual_interface.FAKE_UUID, user_id=None) found, done = instance_mapping.populate_user_id(self.context, 2) # Two needed fixing, and honored the limit. self.assertEqual(2, found) self.assertEqual(2, done) found, done = instance_mapping.populate_user_id(self.context, 1000) # Only four left were fixable. The fifth instance found has no # cell and cannot be migrated yet. The 6th and 7th instances found have # no corresponding instance records and cannot be migrated. self.assertEqual(7, found) self.assertEqual(4, done) # Verify the orphaned instance mappings warning log message was only # emitted once. mock_log_warning.assert_called_once() # Check that we have only the expected number of records with # user_id set. We created 10 instances (5 per cell with 2 per cell # with NULL user_id), 1 SOFT_DELETED instance with NULL user_id, # 1 deleted instance with NULL user_id, and 1 not-yet-scheduled # instance with NULL user_id. # We expect 12 of them to have user_id set after migration (15 total, # with the not-yet-scheduled instance and the orphaned instance # mappings ignored). ims = instance_mapping.InstanceMappingList.get_by_project_id( self.context, self.context.project_id) self.assertEqual(12, len([im for im in ims if 'user_id' in im])) # Check that one instance mapping record (not yet scheduled) has not # been migrated by this script. # Check that two other instance mapping records (no longer existing # instances) have not been migrated by this script. self.assertEqual(15, len(ims)) # Set the cell and create the instance for the mapping without a cell, # then run the migration again. unscheduled = instance_mapping.InstanceMapping.get_by_instance_uuid( self.context, unscheduled['instance_uuid']) unscheduled.cell_mapping = cells[0] unscheduled.save() with context.target_cell(self.context, cells[0]) as cctxt: inst = instance.Instance(cctxt, uuid=unscheduled.instance_uuid, project_id=self.context.project_id, user_id=self.context.user_id) inst.create() found, done = instance_mapping.populate_user_id(self.context, 1000) # Should have found the not-yet-scheduled instance and the orphaned # instance mappings. self.assertEqual(3, found) # Should have only migrated the not-yet-schedule instance. self.assertEqual(1, done) # Delete the orphaned instance mapping (simulate manual cleanup by an # operator). for db_im in nonexistent: nonexist = instance_mapping.InstanceMapping.get_by_instance_uuid( self.context, db_im['instance_uuid']) nonexist.destroy() # Run the script one last time to make sure it finds nothing left to # migrate. found, done = instance_mapping.populate_user_id(self.context, 1000) self.assertEqual(0, found) self.assertEqual(0, done)
def test_populate_queued_for_delete(self): cells = [] celldbs = fixtures.CellDatabases() # Create two cell databases and map them for uuid in (uuidsentinel.cell1, uuidsentinel.cell2): cm = cell_mapping.CellMapping(context=self.context, uuid=uuid, database_connection=uuid, transport_url='fake://') cm.create() cells.append(cm) celldbs.add_cell_database(uuid) self.useFixture(celldbs) # Create 5 instances per cell, two deleted, one with matching # queued_for_delete in the instance mapping for cell in cells: for i in range(0, 5): # Instance 4 should be SOFT_DELETED vm_state = (vm_states.SOFT_DELETED if i == 4 else vm_states.ACTIVE) # Instance 2 should already be marked as queued_for_delete qfd = True if i == 2 else None with context.target_cell(self.context, cell) as cctxt: inst = instance.Instance( cctxt, vm_state=vm_state, project_id=self.context.project_id, user_id=self.context.user_id) inst.create() if i in (2, 3): # Instances 2 and 3 are hard-deleted inst.destroy() instance_mapping.InstanceMapping._create_in_db( self.context, { 'project_id': self.context.project_id, 'cell_id': cell.id, 'queued_for_delete': qfd, 'instance_uuid': inst.uuid }) done, total = instance_mapping.populate_queued_for_delete( self.context, 2) # First two needed fixing, and honored the limit self.assertEqual(2, done) self.assertEqual(2, total) done, total = instance_mapping.populate_queued_for_delete( self.context, 1000) # Last six included two that were already done, and spanned to the # next cell self.assertEqual(6, done) self.assertEqual(6, total) mappings = instance_mapping.InstanceMappingList.get_by_project_id( self.context, self.context.project_id) # Check that we have only the expected number of records with # True/False (which implies no NULL records). # Six deleted instances self.assertEqual( 6, len([im for im in mappings if im.queued_for_delete is True])) # Four non-deleted instances self.assertEqual( 4, len([im for im in mappings if im.queued_for_delete is False])) # Run it again to make sure we don't query the cell database for # instances if we didn't get any un-migrated mappings. with mock.patch('nova.objects.InstanceList.get_by_filters', new_callable=mock.NonCallableMock): done, total = instance_mapping.populate_queued_for_delete( self.context, 1000) self.assertEqual(0, done) self.assertEqual(0, total)