def setUp(self): super(SimpleTenantUsageControllerTest, self).setUp() self.controller = simple_tenant_usage.SimpleTenantUsageController() class FakeComputeAPI: def get_instance_type(self, context, flavor_type): if flavor_type == 1: return flavors.get_default_flavor() else: raise exception.InstanceTypeNotFound(flavor_type) self.compute_api = FakeComputeAPI() self.context = None now = datetime.datetime.now() self.baseinst = dict(display_name='foo', launched_at=now - datetime.timedelta(1), terminated_at=now, instance_type_id=1, vm_state='deleted', deleted=0) basetype = flavors.get_default_flavor() sys_meta = utils.dict_to_metadata( flavors.save_flavor_info({}, basetype)) self.baseinst['system_metadata'] = sys_meta self.basetype = flavors.extract_flavor(self.baseinst)
class SimpleTenantUsageControllerTestV21(test.TestCase): controller = simple_tenant_usage_v21.SimpleTenantUsageController() def setUp(self): super(SimpleTenantUsageControllerTestV21, self).setUp() self.context = context.RequestContext('fakeuser', 'fake-project') self.baseinst = get_fake_db_instance(START, STOP, instance_id=1, tenant_id=self.context.project_id, vm_state=vm_states.DELETED) # convert the fake instance dict to an object self.inst_obj = objects.Instance._from_db_object( self.context, objects.Instance(), self.baseinst) def test_get_flavor_from_sys_meta(self): # Non-deleted instances get their type information from their # system_metadata with mock.patch.object(db, 'instance_get_by_uuid', return_value=self.baseinst): flavor = self.controller._get_flavor(self.context, self.inst_obj, {}) self.assertEqual(objects.Flavor, type(flavor)) self.assertEqual(FAKE_INST_TYPE['id'], flavor.id) def test_get_flavor_from_non_deleted_with_id_fails(self): # If an instance is not deleted and missing type information from # system_metadata, then that's a bug self.inst_obj.system_metadata = {} self.assertRaises(exception.NotFound, self.controller._get_flavor, self.context, self.inst_obj, {}) @mock.patch('nova.objects.Instance.get_flavor', side_effect=exception.NotFound()) def test_get_flavor_from_deleted_with_notfound(self, fake_get_flavor): self.inst_obj.deleted = 1 flavor = self.controller._get_flavor(self.context, self.inst_obj, {}) self.assertEqual(objects.Flavor, type(flavor)) self.assertEqual(FAKE_INST_TYPE['id'], flavor.id) def test_get_flavor_from_deleted_with_id(self): # Deleted instances may not have type info in system_metadata, # so verify that they get their type from a lookup of their # instance_type_id self.inst_obj.system_metadata = {} self.inst_obj.deleted = 1 flavor = self.controller._get_flavor(self.context, self.inst_obj, {}) self.assertEqual(objects.Flavor, type(flavor)) self.assertEqual(FAKE_INST_TYPE['id'], flavor.id) def test_get_flavor_from_deleted_with_id_of_deleted(self): # Verify the legacy behavior of instance_type_id pointing to a # missing type being non-fatal self.inst_obj.system_metadata = {} self.inst_obj.deleted = 1 self.inst_obj.instance_type_id = 99 flavor = self.controller._get_flavor(self.context, self.inst_obj, {}) self.assertIsNone(flavor)
def setUp(self): super(SimpleTenantUsageControllerTest, self).setUp() self.controller = simple_tenant_usage.SimpleTenantUsageController() self.context = context.RequestContext('fakeuser', 'fake-project') self.baseinst = get_fake_db_instance(START, STOP, instance_id=1, tenant_id=self.context.project_id, vm_state=vm_states.DELETED) # convert the fake instance dict to an object self.inst_obj = instance_obj.Instance._from_db_object( self.context, instance_obj.Instance(), self.baseinst)
class SimpleTenantUsageTestV21(test.TestCase): policy_rule_prefix = "os_compute_api:os-simple-tenant-usage" controller = simple_tenant_usage_v21.SimpleTenantUsageController() def setUp(self): super(SimpleTenantUsageTestV21, self).setUp() self.admin_context = context.RequestContext('fakeadmin_0', 'faketenant_0', is_admin=True) self.user_context = context.RequestContext('fakeadmin_0', 'faketenant_0', is_admin=False) self.alt_user_context = context.RequestContext('fakeadmin_0', 'faketenant_1', is_admin=False) def _test_verify_index(self, start, stop): req = fakes.HTTPRequest.blank('?start=%s&end=%s' % (start.isoformat(), stop.isoformat())) req.environ['nova.context'] = self.admin_context res_dict = self.controller.index(req) usages = res_dict['tenant_usages'] for i in xrange(TENANTS): self.assertEqual(int(usages[i]['total_hours']), SERVERS * HOURS) self.assertEqual(int(usages[i]['total_local_gb_usage']), SERVERS * (ROOT_GB + EPHEMERAL_GB) * HOURS) self.assertEqual(int(usages[i]['total_memory_mb_usage']), SERVERS * MEMORY_MB * HOURS) self.assertEqual(int(usages[i]['total_vcpus_usage']), SERVERS * VCPUS * HOURS) self.assertFalse(usages[i].get('server_usages')) def test_verify_index(self): self._test_verify_index(START, STOP) def test_verify_index_future_end_time(self): future = NOW + datetime.timedelta(hours=HOURS) self._test_verify_index(START, future) def test_verify_show(self): self._test_verify_show(START, STOP) def test_verify_show_future_end_time(self): future = NOW + datetime.timedelta(hours=HOURS) self._test_verify_show(START, future) def _get_tenant_usages(self, detailed=''): req = fakes.HTTPRequest.blank( '?detailed=%s&start=%s&end=%s' % (detailed, START.isoformat(), STOP.isoformat())) req.environ['nova.context'] = self.admin_context # Make sure that get_active_by_window_joined is only called with # expected_attrs=['system_metadata']. orig_get_active_by_window_joined = ( objects.InstanceList.get_active_by_window_joined) def fake_get_active_by_window_joined(context, begin, end=None, project_id=None, host=None, expected_attrs=None, use_slave=False): self.assertEqual(['system_metadata'], expected_attrs) return orig_get_active_by_window_joined(context, begin, end, project_id, host, expected_attrs, use_slave) with mock.patch.object(objects.InstanceList, 'get_active_by_window_joined', side_effect=fake_get_active_by_window_joined): res_dict = self.controller.index(req) return res_dict['tenant_usages'] def test_verify_detailed_index(self): usages = self._get_tenant_usages('1') for i in xrange(TENANTS): servers = usages[i]['server_usages'] for j in xrange(SERVERS): self.assertEqual(int(servers[j]['hours']), HOURS) def test_verify_simple_index(self): usages = self._get_tenant_usages(detailed='0') for i in xrange(TENANTS): self.assertIsNone(usages[i].get('server_usages')) def test_verify_simple_index_empty_param(self): # NOTE(lzyeval): 'detailed=&start=..&end=..' usages = self._get_tenant_usages() for i in xrange(TENANTS): self.assertIsNone(usages[i].get('server_usages')) def _test_verify_show(self, start, stop): tenant_id = 1 req = fakes.HTTPRequest.blank('?start=%s&end=%s' % (start.isoformat(), stop.isoformat())) req.environ['nova.context'] = self.user_context res_dict = self.controller.show(req, tenant_id) usage = res_dict['tenant_usage'] servers = usage['server_usages'] self.assertEqual(len(usage['server_usages']), TENANTS * SERVERS) uuids = [ '00000000-0000-0000-0000-00000000000000%02d' % x for x in xrange(SERVERS) ] for j in xrange(SERVERS): delta = STOP - START uptime = delta.days * 24 * 3600 + delta.seconds self.assertEqual(int(servers[j]['uptime']), uptime) self.assertEqual(int(servers[j]['hours']), HOURS) self.assertIn(servers[j]['instance_id'], uuids) def test_verify_show_cannot_view_other_tenant(self): req = fakes.HTTPRequest.blank('?start=%s&end=%s' % (START.isoformat(), STOP.isoformat())) req.environ['nova.context'] = self.alt_user_context rules = { self.policy_rule_prefix + ":show": common_policy.parse_rule([["role:admin"], ["project_id:%(project_id)s"]]) } policy.set_rules(rules) try: self.assertRaises(exception.PolicyNotAuthorized, self.controller.show, req, 'faketenant_0') finally: policy.reset() def test_get_tenants_usage_with_bad_start_date(self): future = NOW + datetime.timedelta(hours=HOURS) req = fakes.HTTPRequest.blank('?start=%s&end=%s' % (future.isoformat(), NOW.isoformat())) req.environ['nova.context'] = self.user_context self.assertRaises(webob.exc.HTTPBadRequest, self.controller.show, req, 'faketenant_0') def test_get_tenants_usage_with_invalid_start_date(self): req = fakes.HTTPRequest.blank('?start=%s&end=%s' % ("xxxx", NOW.isoformat())) req.environ['nova.context'] = self.user_context self.assertRaises(webob.exc.HTTPBadRequest, self.controller.show, req, 'faketenant_0') def _test_get_tenants_usage_with_one_date(self, date_url_param): req = fakes.HTTPRequest.blank('?%s' % date_url_param) req.environ['nova.context'] = self.user_context res = self.controller.show(req, 'faketenant_0') self.assertIn('tenant_usage', res) def test_get_tenants_usage_with_no_start_date(self): self._test_get_tenants_usage_with_one_date( 'end=%s' % (NOW + datetime.timedelta(5)).isoformat()) def test_get_tenants_usage_with_no_end_date(self): self._test_get_tenants_usage_with_one_date( 'start=%s' % (NOW - datetime.timedelta(5)).isoformat())