~hudson-openstack/nova/trunk

« back to all changes in this revision

Viewing changes to nova/tests/api/openstack/contrib/test_simple_tenant_usage.py

  • Committer: Tarmac
  • Author(s): Vishvananda Ishaya, Anthony Young
  • Date: 2011-09-01 00:16:34 UTC
  • mfrom: (1468.3.13 os-simple-usage)
  • Revision ID: tarmac-20110901001634-bb3whyoipqxc60k5
Simple usage extension for nova.  Uses db to calculate tenant_usage for specified time periods.

Methods:
    * index: return a list of tenant_usages, with option of incuding detailed server_usage
    * show: returns a specific tenant_usage object

tenant_usage object:
    * tenant_usage.total_memory_mb_usage: sum of memory_mb * hours for all instances in tenant for this period
    * tenant_usage.total_local_gb_usage: sum of local_gb * hours for all instances in tenant for this period
    * tenant_usage.total_vcpus_usage: sum of vcpus * hours for all instances in tenant for this period
    * tenant_usage.total_hours: sum of all instance hours for this period
    * tenant_usage.server_usages: A detailed list of server_usages, which describe the usage of a specific server

For larger instances db tables, indexes on instance.launched_at and instance.terminated_at should significantly help performance.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright 2011 OpenStack LLC.
 
4
# All Rights Reserved.
 
5
#
 
6
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
7
#    not use this file except in compliance with the License. You may obtain
 
8
#    a copy of the License at
 
9
#
 
10
#         http://www.apache.org/licenses/LICENSE-2.0
 
11
#
 
12
#    Unless required by applicable law or agreed to in writing, software
 
13
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
14
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
15
#    License for the specific language governing permissions and limitations
 
16
#    under the License.
 
17
 
 
18
import datetime
 
19
import json
 
20
import webob
 
21
 
 
22
from nova import context
 
23
from nova import flags
 
24
from nova import test
 
25
from nova.compute import api
 
26
from nova.tests.api.openstack import fakes
 
27
 
 
28
 
 
29
FLAGS = flags.FLAGS
 
30
 
 
31
SERVERS = 5
 
32
TENANTS = 2
 
33
HOURS = 24
 
34
LOCAL_GB = 10
 
35
MEMORY_MB = 1024
 
36
VCPUS = 2
 
37
STOP = datetime.datetime.utcnow()
 
38
START = STOP - datetime.timedelta(hours=HOURS)
 
39
 
 
40
 
 
41
def fake_instance_type_get(self, context, instance_type_id):
 
42
    return {'id': 1,
 
43
            'vcpus': VCPUS,
 
44
            'local_gb': LOCAL_GB,
 
45
            'memory_mb': MEMORY_MB,
 
46
            'name':
 
47
            'fakeflavor'}
 
48
 
 
49
 
 
50
def get_fake_db_instance(start, end, instance_id, tenant_id):
 
51
    return  {'id': instance_id,
 
52
             'image_ref': '1',
 
53
             'project_id': tenant_id,
 
54
             'user_id': 'fakeuser',
 
55
             'display_name': 'name',
 
56
             'state_description': 'state',
 
57
             'instance_type_id': 1,
 
58
             'launched_at': start,
 
59
             'terminated_at': end}
 
60
 
 
61
 
 
62
def fake_instance_get_active_by_window(self, context, begin, end, project_id):
 
63
            return [get_fake_db_instance(START,
 
64
                                         STOP,
 
65
                                         x,
 
66
                                         "faketenant_%s" % (x / SERVERS))
 
67
                                         for x in xrange(TENANTS * SERVERS)]
 
68
 
 
69
 
 
70
class SimpleTenantUsageTest(test.TestCase):
 
71
    def setUp(self):
 
72
        super(SimpleTenantUsageTest, self).setUp()
 
73
        self.stubs.Set(api.API, "get_instance_type",
 
74
                       fake_instance_type_get)
 
75
        self.stubs.Set(api.API, "get_active_by_window",
 
76
                       fake_instance_get_active_by_window)
 
77
        self.admin_context = context.RequestContext('fakeadmin_0',
 
78
                                                    'faketenant_0',
 
79
                                                    is_admin=True)
 
80
        self.user_context = context.RequestContext('fakeadmin_0',
 
81
                                                   'faketenant_0',
 
82
                                                    is_admin=False)
 
83
        self.alt_user_context = context.RequestContext('fakeadmin_0',
 
84
                                                      'faketenant_1',
 
85
                                                       is_admin=False)
 
86
        FLAGS.allow_admin_api = True
 
87
 
 
88
    def test_verify_index(self):
 
89
        req = webob.Request.blank(
 
90
                    '/v1.1/123/os-simple-tenant-usage?start=%s&end=%s' %
 
91
                    (START.isoformat(), STOP.isoformat()))
 
92
        req.method = "GET"
 
93
        req.headers["content-type"] = "application/json"
 
94
 
 
95
        res = req.get_response(fakes.wsgi_app(
 
96
                               fake_auth_context=self.admin_context))
 
97
 
 
98
        self.assertEqual(res.status_int, 200)
 
99
        res_dict = json.loads(res.body)
 
100
        usages = res_dict['tenant_usages']
 
101
        from nova import log as logging
 
102
        logging.warn(usages)
 
103
        for i in xrange(TENANTS):
 
104
            self.assertEqual(int(usages[i]['total_hours']),
 
105
                             SERVERS * HOURS)
 
106
            self.assertEqual(int(usages[i]['total_local_gb_usage']),
 
107
                             SERVERS * LOCAL_GB * HOURS)
 
108
            self.assertEqual(int(usages[i]['total_memory_mb_usage']),
 
109
                             SERVERS * MEMORY_MB * HOURS)
 
110
            self.assertEqual(int(usages[i]['total_vcpus_usage']),
 
111
                             SERVERS * VCPUS * HOURS)
 
112
            self.assertFalse(usages[i].get('server_usages'))
 
113
 
 
114
    def test_verify_detailed_index(self):
 
115
        req = webob.Request.blank(
 
116
                    '/v1.1/123/os-simple-tenant-usage?'
 
117
                    'detailed=1&start=%s&end=%s' %
 
118
                    (START.isoformat(), STOP.isoformat()))
 
119
        req.method = "GET"
 
120
        req.headers["content-type"] = "application/json"
 
121
 
 
122
        res = req.get_response(fakes.wsgi_app(
 
123
                               fake_auth_context=self.admin_context))
 
124
        self.assertEqual(res.status_int, 200)
 
125
        res_dict = json.loads(res.body)
 
126
        usages = res_dict['tenant_usages']
 
127
        for i in xrange(TENANTS):
 
128
            servers = usages[i]['server_usages']
 
129
            for j in xrange(SERVERS):
 
130
                self.assertEqual(int(servers[j]['hours']), HOURS)
 
131
 
 
132
    def test_verify_index_fails_for_nonadmin(self):
 
133
        req = webob.Request.blank(
 
134
                    '/v1.1/123/os-simple-tenant-usage?'
 
135
                    'detailed=1&start=%s&end=%s' %
 
136
                    (START.isoformat(), STOP.isoformat()))
 
137
        req.method = "GET"
 
138
        req.headers["content-type"] = "application/json"
 
139
 
 
140
        res = req.get_response(fakes.wsgi_app())
 
141
        self.assertEqual(res.status_int, 403)
 
142
 
 
143
    def test_verify_show(self):
 
144
        req = webob.Request.blank(
 
145
                  '/v1.1/faketenant_0/os-simple-tenant-usage/'
 
146
                  'faketenant_0?start=%s&end=%s' %
 
147
                  (START.isoformat(), STOP.isoformat()))
 
148
        req.method = "GET"
 
149
        req.headers["content-type"] = "application/json"
 
150
 
 
151
        res = req.get_response(fakes.wsgi_app(
 
152
                               fake_auth_context=self.user_context))
 
153
        self.assertEqual(res.status_int, 200)
 
154
        res_dict = json.loads(res.body)
 
155
 
 
156
        usage = res_dict['tenant_usage']
 
157
        servers = usage['server_usages']
 
158
        self.assertEqual(len(usage['server_usages']), SERVERS)
 
159
        for j in xrange(SERVERS):
 
160
            self.assertEqual(int(servers[j]['hours']), HOURS)
 
161
 
 
162
    def test_verify_show_cant_view_other_tenant(self):
 
163
        req = webob.Request.blank(
 
164
                  '/v1.1/faketenant_1/os-simple-tenant-usage/'
 
165
                  'faketenant_0?start=%s&end=%s' %
 
166
                  (START.isoformat(), STOP.isoformat()))
 
167
        req.method = "GET"
 
168
        req.headers["content-type"] = "application/json"
 
169
 
 
170
        res = req.get_response(fakes.wsgi_app(
 
171
                               fake_auth_context=self.alt_user_context))
 
172
        self.assertEqual(res.status_int, 403)