~cloudbuilders/nova/os-keypair-integration

« back to all changes in this revision

Viewing changes to nova/tests/test_rpc_common.py

  • Committer: Vishvananda Ishaya
  • Date: 2011-09-01 04:55:12 UTC
  • mfrom: (1455.1.62 nova)
  • Revision ID: vishvananda@gmail.com-20110901045512-ndwp9nu3alwbnnj8
merge trunk, fix tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright 2010 United States Government as represented by the
 
4
# Administrator of the National Aeronautics and Space Administration.
 
5
# All Rights Reserved.
 
6
#
 
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
8
#    not use this file except in compliance with the License. You may obtain
 
9
#    a copy of the License at
 
10
#
 
11
#         http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
#    Unless required by applicable law or agreed to in writing, software
 
14
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
15
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
16
#    License for the specific language governing permissions and limitations
 
17
#    under the License.
 
18
"""
 
19
Unit Tests for remote procedure calls shared between all implementations
 
20
"""
 
21
 
 
22
from nova import context
 
23
from nova import log as logging
 
24
from nova.rpc.common import RemoteError
 
25
from nova import test
 
26
 
 
27
 
 
28
LOG = logging.getLogger('nova.tests.rpc')
 
29
 
 
30
 
 
31
class _BaseRpcTestCase(test.TestCase):
 
32
    def setUp(self):
 
33
        super(_BaseRpcTestCase, self).setUp()
 
34
        self.conn = self.rpc.create_connection(True)
 
35
        self.receiver = TestReceiver()
 
36
        self.conn.create_consumer('test', self.receiver, False)
 
37
        self.conn.consume_in_thread()
 
38
        self.context = context.get_admin_context()
 
39
 
 
40
    def tearDown(self):
 
41
        self.conn.close()
 
42
        super(_BaseRpcTestCase, self).tearDown()
 
43
 
 
44
    def test_call_succeed(self):
 
45
        value = 42
 
46
        result = self.rpc.call(self.context, 'test', {"method": "echo",
 
47
                                                 "args": {"value": value}})
 
48
        self.assertEqual(value, result)
 
49
 
 
50
    def test_call_succeed_despite_multiple_returns(self):
 
51
        value = 42
 
52
        result = self.rpc.call(self.context, 'test',
 
53
                {"method": "echo_three_times",
 
54
                 "args": {"value": value}})
 
55
        self.assertEqual(value + 2, result)
 
56
 
 
57
    def test_call_succeed_despite_multiple_returns_yield(self):
 
58
        value = 42
 
59
        result = self.rpc.call(self.context, 'test',
 
60
                          {"method": "echo_three_times_yield",
 
61
                           "args": {"value": value}})
 
62
        self.assertEqual(value + 2, result)
 
63
 
 
64
    def test_multicall_succeed_once(self):
 
65
        value = 42
 
66
        result = self.rpc.multicall(self.context,
 
67
                              'test',
 
68
                              {"method": "echo",
 
69
                               "args": {"value": value}})
 
70
        for i, x in enumerate(result):
 
71
            if i > 0:
 
72
                self.fail('should only receive one response')
 
73
            self.assertEqual(value + i, x)
 
74
 
 
75
    def test_multicall_succeed_three_times(self):
 
76
        value = 42
 
77
        result = self.rpc.multicall(self.context,
 
78
                              'test',
 
79
                              {"method": "echo_three_times",
 
80
                               "args": {"value": value}})
 
81
        for i, x in enumerate(result):
 
82
            self.assertEqual(value + i, x)
 
83
 
 
84
    def test_multicall_succeed_three_times_yield(self):
 
85
        value = 42
 
86
        result = self.rpc.multicall(self.context,
 
87
                              'test',
 
88
                              {"method": "echo_three_times_yield",
 
89
                               "args": {"value": value}})
 
90
        for i, x in enumerate(result):
 
91
            self.assertEqual(value + i, x)
 
92
 
 
93
    def test_context_passed(self):
 
94
        """Makes sure a context is passed through rpc call."""
 
95
        value = 42
 
96
        result = self.rpc.call(self.context,
 
97
                          'test', {"method": "context",
 
98
                                   "args": {"value": value}})
 
99
        self.assertEqual(self.context.to_dict(), result)
 
100
 
 
101
    def test_call_exception(self):
 
102
        """Test that exception gets passed back properly.
 
103
 
 
104
        rpc.call returns a RemoteError object.  The value of the
 
105
        exception is converted to a string, so we convert it back
 
106
        to an int in the test.
 
107
 
 
108
        """
 
109
        value = 42
 
110
        self.assertRaises(RemoteError,
 
111
                          self.rpc.call,
 
112
                          self.context,
 
113
                          'test',
 
114
                          {"method": "fail",
 
115
                           "args": {"value": value}})
 
116
        try:
 
117
            self.rpc.call(self.context,
 
118
                     'test',
 
119
                     {"method": "fail",
 
120
                      "args": {"value": value}})
 
121
            self.fail("should have thrown RemoteError")
 
122
        except RemoteError as exc:
 
123
            self.assertEqual(int(exc.value), value)
 
124
 
 
125
    def test_nested_calls(self):
 
126
        """Test that we can do an rpc.call inside another call."""
 
127
        class Nested(object):
 
128
            @staticmethod
 
129
            def echo(context, queue, value):
 
130
                """Calls echo in the passed queue"""
 
131
                LOG.debug(_("Nested received %(queue)s, %(value)s")
 
132
                        % locals())
 
133
                # TODO: so, it will replay the context and use the same REQID?
 
134
                # that's bizarre.
 
135
                ret = self.rpc.call(context,
 
136
                               queue,
 
137
                               {"method": "echo",
 
138
                                "args": {"value": value}})
 
139
                LOG.debug(_("Nested return %s"), ret)
 
140
                return value
 
141
 
 
142
        nested = Nested()
 
143
        conn = self.rpc.create_connection(True)
 
144
        conn.create_consumer('nested', nested, False)
 
145
        conn.consume_in_thread()
 
146
        value = 42
 
147
        result = self.rpc.call(self.context,
 
148
                          'nested', {"method": "echo",
 
149
                                     "args": {"queue": "test",
 
150
                                              "value": value}})
 
151
        conn.close()
 
152
        self.assertEqual(value, result)
 
153
 
 
154
 
 
155
class TestReceiver(object):
 
156
    """Simple Proxy class so the consumer has methods to call.
 
157
 
 
158
    Uses static methods because we aren't actually storing any state.
 
159
 
 
160
    """
 
161
 
 
162
    @staticmethod
 
163
    def echo(context, value):
 
164
        """Simply returns whatever value is sent in."""
 
165
        LOG.debug(_("Received %s"), value)
 
166
        return value
 
167
 
 
168
    @staticmethod
 
169
    def context(context, value):
 
170
        """Returns dictionary version of context."""
 
171
        LOG.debug(_("Received %s"), context)
 
172
        return context.to_dict()
 
173
 
 
174
    @staticmethod
 
175
    def echo_three_times(context, value):
 
176
        context.reply(value)
 
177
        context.reply(value + 1)
 
178
        context.reply(value + 2)
 
179
 
 
180
    @staticmethod
 
181
    def echo_three_times_yield(context, value):
 
182
        yield value
 
183
        yield value + 1
 
184
        yield value + 2
 
185
 
 
186
    @staticmethod
 
187
    def fail(context, value):
 
188
        """Raises an exception with the value sent in."""
 
189
        raise Exception(value)