Merge lp:~rackspace-titan/nova/changes-since-lp837405 into lp:~hudson-openstack/nova/trunk

Proposed by Brian Waldon
Status: Merged
Approved by: Vish Ishaya
Approved revision: 1512
Merged at revision: 1521
Proposed branch: lp:~rackspace-titan/nova/changes-since-lp837405
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 157 lines (+55/-19)
5 files modified
nova/api/openstack/servers.py (+14/-12)
nova/db/sqlalchemy/api.py (+8/-4)
nova/tests/api/openstack/test_servers.py (+25/-0)
nova/tests/test_cloud.py (+5/-2)
nova/tests/test_db_api.py (+3/-1)
To merge this branch: bzr merge lp:~rackspace-titan/nova/changes-since-lp837405
Reviewer Review Type Date Requested Status
Vish Ishaya (community) Approve
Brian Lamar (community) Approve
Review via email: mp+73393@code.launchpad.net

Description of the change

- implements changes-since for servers resource
- default sort is now created_at desc for instances

To post a comment you must log in.
Revision history for this message
Brian Lamar (blamar) wrote :

Love it, seems pretty straight forward to me.

review: Approve
Revision history for this message
Vish Ishaya (vishvananda) wrote :

lgtm

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (131.6 KiB)

The attempt to merge lp:~rackspace-titan/nova/changes-since-lp837405 into lp:nova failed. Below is the output from the failed tests.

CreateserverextTest
    test_create_instance_with_duplicate_networks OK 0.31
    test_create_instance_with_duplicate_networks_xml OK 0.42
    test_create_instance_with_network_empty_fixed_ip OK 0.29
    test_create_instance_with_network_empty_fixed_ip_xml OK 0.29
    test_create_instance_with_network_invalid_id OK 0.44
    test_create_instance_with_network_invalid_id_xml OK 0.28
    test_create_instance_with_network_no_fixed_ip OK 0.29
    test_create_instance_with_network_no_fixed_ip_xml OK 0.43
    test_create_instance_with_network_no_id OK 0.28
    test_create_instance_with_network_no_id_xml OK 0.42
    test_create_instance_with_network_non_string_fixed_ip OK 0.28
    test_create_instance_with_no_networks OK 0.29
    test_create_instance_with_no_networks_xml OK 0.47
    test_create_instance_with_one_network OK 0.30
    test_create_instance_with_one_network_xml OK 0.29
    test_create_instance_with_two_networks OK 0.46
    test_create_instance_with_two_networks_xml OK 0.30
    test_create_instance_with_userdata OK 0.29
    test_create_instance_with_userdata_none OK 0.46
    test_create_instance_with_userdata_with_non_b64_content OK 0.29
FloatingIpTest
    test_add_associated_floating_ip_to_instance OK 0.35
    test_add_floating_ip_to_instance OK 0.45
    test_associate_floating_ip_to_instance_no_project_id OK 0.34
    test_associate_floating_ip_to_instance_wrong_project_id OK 0.48
    test_bad_address_param_in_add_floating_ip OK 0.31
    test_bad_address_param_in_remove_floating_ip OK 0.30
    test_floating_ip_allocate OK 0.48
    test_floating_ip_allocate_no_free_ips OK 0.30
    test_floating_ip_release OK 0.30
    test_floating_ip_show OK 0.43
    test_floating_ips_list OK 0.30
    test_missing_dict_param_in_add_floating_ip OK 0.30
    test_missing_dict_param_in_remove_floating_ip OK 0.43
    test_remove_floating_ip_from_instance OK 0.29
    test_show_associated_floating_ip OK 0.43
    test_translate_floating_ip_view OK 0.04
    test_translate_floating_ip_view_dict OK 0.02
KeypairsTest
    test_keypair_create OK 0.44
    test_keypair_delete OK 0.31
    test_keypair_import OK 0.59
    test_keypair_list OK 0.32
FixedIpTest
    test_add_...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/api/openstack/servers.py'
2--- nova/api/openstack/servers.py 2011-09-01 04:55:12 +0000
3+++ nova/api/openstack/servers.py 2011-09-01 15:23:36 +0000
4@@ -106,6 +106,14 @@
5 raise exception.InvalidInput(reason=reason)
6 search_opts['vm_state'] = state
7
8+ if 'changes-since' in search_opts:
9+ try:
10+ parsed = utils.parse_isotime(search_opts['changes-since'])
11+ except ValueError:
12+ msg = _('Invalid changes-since value')
13+ raise exc.HTTPBadRequest(explanation=msg)
14+ search_opts['changes-since'] = parsed
15+
16 # By default, compute's get_all() will return deleted instances.
17 # If an admin hasn't specified a 'deleted' search option, we need
18 # to filter out deleted instances by setting the filter ourselves.
19@@ -113,23 +121,17 @@
20 # should return recently deleted images according to the API spec.
21
22 if 'deleted' not in search_opts:
23- # Admin hasn't specified deleted filter
24 if 'changes-since' not in search_opts:
25- # No 'changes-since', so we need to find non-deleted servers
26+ # No 'changes-since', so we only want non-deleted servers
27 search_opts['deleted'] = False
28- else:
29- # This is the default, but just in case..
30- search_opts['deleted'] = True
31-
32- instance_list = self.compute_api.get_all(
33- context, search_opts=search_opts)
34-
35- # FIXME(comstud): 'changes-since' is not fully implemented. Where
36- # should this be filtered?
37+
38+ instance_list = self.compute_api.get_all(context,
39+ search_opts=search_opts)
40
41 limited_list = self._limit_items(instance_list, req)
42 servers = [self._build_view(req, inst, is_detail)['server']
43- for inst in limited_list]
44+ for inst in limited_list]
45+
46 return dict(servers=servers)
47
48 @scheduler_api.redirect_handler
49
50=== modified file 'nova/db/sqlalchemy/api.py'
51--- nova/db/sqlalchemy/api.py 2011-08-31 23:07:29 +0000
52+++ nova/db/sqlalchemy/api.py 2011-09-01 15:23:36 +0000
53@@ -36,6 +36,7 @@
54 from sqlalchemy.orm import joinedload
55 from sqlalchemy.orm import joinedload_all
56 from sqlalchemy.sql import func
57+from sqlalchemy.sql.expression import desc
58 from sqlalchemy.sql.expression import literal_column
59
60 FLAGS = flags.FLAGS
61@@ -1250,12 +1251,17 @@
62 options(joinedload_all('fixed_ips.network')).\
63 options(joinedload('metadata')).\
64 options(joinedload('instance_type')).\
65- filter_by(deleted=can_read_deleted(context))
66+ order_by(desc(models.Instance.created_at))
67
68 # Make a copy of the filters dictionary to use going forward, as we'll
69 # be modifying it and we shouldn't affect the caller's use of it.
70 filters = filters.copy()
71
72+ if 'changes-since' in filters:
73+ changes_since = filters['changes-since']
74+ query_prefix = query_prefix.\
75+ filter(models.Instance.updated_at > changes_since)
76+
77 if not context.is_admin:
78 # If we're not admin context, add appropriate filter..
79 if context.project_id:
80@@ -1277,9 +1283,7 @@
81 query_prefix = _exact_match_filter(query_prefix, filter_name,
82 filters.pop(filter_name))
83
84- instances = query_prefix.\
85- filter_by(deleted=can_read_deleted(context)).\
86- all()
87+ instances = query_prefix.all()
88
89 if not instances:
90 return []
91
92=== modified file 'nova/tests/api/openstack/test_servers.py'
93--- nova/tests/api/openstack/test_servers.py 2011-09-01 04:55:12 +0000
94+++ nova/tests/api/openstack/test_servers.py 2011-09-01 15:23:36 +0000
95@@ -1265,6 +1265,31 @@
96 self.assertEqual(len(servers), 1)
97 self.assertEqual(servers[0]['id'], 100)
98
99+ def test_get_servers_allows_changes_since_v1_1(self):
100+ def fake_get_all(compute_self, context, search_opts=None):
101+ self.assertNotEqual(search_opts, None)
102+ self.assertTrue('changes-since' in search_opts)
103+ changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1)
104+ self.assertEqual(search_opts['changes-since'], changes_since)
105+ self.assertTrue('deleted' not in search_opts)
106+ return [stub_instance(100)]
107+
108+ self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
109+
110+ params = 'changes-since=2011-01-24T17:08:01Z'
111+ req = webob.Request.blank('/v1.1/fake/servers?%s' % params)
112+ res = req.get_response(fakes.wsgi_app())
113+ self.assertEqual(res.status_int, 200)
114+ servers = json.loads(res.body)['servers']
115+ self.assertEqual(len(servers), 1)
116+ self.assertEqual(servers[0]['id'], 100)
117+
118+ def test_get_servers_allows_changes_since_bad_value_v1_1(self):
119+ params = 'changes-since=asdf'
120+ req = webob.Request.blank('/v1.1/fake/servers?%s' % params)
121+ res = req.get_response(fakes.wsgi_app())
122+ self.assertEqual(res.status_int, 400)
123+
124 def test_get_servers_unknown_or_admin_options1(self):
125 """Test getting servers by admin-only or unknown options.
126 This tests when admin_api is off. Make sure the admin and
127
128=== modified file 'nova/tests/test_cloud.py'
129--- nova/tests/test_cloud.py 2011-09-01 14:02:02 +0000
130+++ nova/tests/test_cloud.py 2011-09-01 15:23:36 +0000
131@@ -486,8 +486,11 @@
132 inst2 = db.instance_create(self.context, args2)
133 db.instance_destroy(self.context, inst1.id)
134 result = self.cloud.describe_instances(self.context)
135- result = result['reservationSet'][0]['instancesSet']
136- self.assertEqual(result[0]['instanceId'],
137+ result1 = result['reservationSet'][0]['instancesSet']
138+ self.assertEqual(result1[0]['instanceId'],
139+ ec2utils.id_to_ec2_id(inst1.id))
140+ result2 = result['reservationSet'][1]['instancesSet']
141+ self.assertEqual(result2[0]['instanceId'],
142 ec2utils.id_to_ec2_id(inst2.id))
143
144 def _block_device_mapping_create(self, instance_id, mappings):
145
146=== modified file 'nova/tests/test_db_api.py'
147--- nova/tests/test_db_api.py 2011-08-18 21:57:52 +0000
148+++ nova/tests/test_db_api.py 2011-09-01 15:23:36 +0000
149@@ -91,5 +91,7 @@
150 inst2 = db.instance_create(self.context, args2)
151 db.instance_destroy(self.context, inst1.id)
152 result = db.instance_get_all_by_filters(self.context.elevated(), {})
153- self.assertEqual(1, len(result))
154+ self.assertEqual(2, len(result))
155 self.assertEqual(result[0].id, inst2.id)
156+ self.assertEqual(result[1].id, inst1.id)
157+ self.assertTrue(result[1].deleted)