1
from dbus import DBusException
3
from twisted.internet.defer import Deferred
5
from landscape.schema import Message, InvalidError, String, List, Dict
6
from landscape.broker.remote import (FakeRemoteBroker,
7
DBusSignalToReactorTransmitter)
8
from landscape.tests.helpers import (LandscapeIsolatedTest, LandscapeTest,
9
ExchangeHelper, RemoteBrokerHelper)
10
from landscape.reactor import FakeReactor
13
class RemoteBrokerTestsMixin(object):
14
"""Test cases for testing L{RemoteBroker}-like objects."""
17
super(RemoteBrokerTestsMixin, self).setUp()
18
self.mstore.add_schema(Message("empty", {}))
19
self.mstore.set_accepted_types(["empty"])
21
def test_send_message(self):
23
self.exchanger.exchange()
24
done = self.get_remote().send_message({"type": "empty"})
26
self.assertMessages(self.mstore.get_pending_messages(),
28
self.assertFalse(self.exchanger.is_urgent())
29
return done.addCallback(got_result)
31
def test_send_message_containing_string_remains_as_string(self):
33
Strings in messages should not be converted to unicode.
35
This is a regression test related to the fact that strings by default
36
are sent as unicode with dbus. We must send our bytes unmolested.
39
self.exchanger.exchange()
40
self.mstore.add_schema(Message("data", {"data": String()}))
41
self.mstore.set_accepted_types(["data"])
43
msg = {"type": "data", "data": "foo"}
44
done = self.get_remote().send_message(msg)
46
messages = self.mstore.get_pending_messages()
47
# By now, the assertion already happened in the schema system -
48
# String() does not allow unicode objects. Let's just do a sanity
50
self.assertMessages(messages, [msg])
51
return done.addCallback(got_result)
53
def test_send_complex_data_in_messages(self):
55
self.exchanger.exchange()
56
self.mstore.add_schema(
57
Message("data", {"data": List(Dict(String(), String()))}))
58
self.mstore.set_accepted_types(["data"])
60
msg = {"type": "data", "data": [{"foo": "bar"}]}
61
done = self.get_remote().send_message(msg)
63
messages = self.mstore.get_pending_messages()
64
self.assertMessages(messages, [msg])
65
return done.addCallback(got_result)
67
def test_send_message_urgent(self):
69
Sending a message with the urgent flag should schedule an
73
self.exchanger.exchange()
74
self.assertFalse(self.exchanger.is_urgent())
75
done = self.get_remote().send_message({"type": "empty"}, urgent=True)
77
self.assertMessages(self.mstore.get_pending_messages(),
79
self.assertTrue(self.exchanger.is_urgent())
80
return done.addCallback(got_result)
82
def test_send_bad_schema(self):
83
self.log_helper.ignore_errors(InvalidError)
84
done = self.get_remote().send_message({"type": "empty", "data": "data"})
85
return self.assertFailure(done, InvalidError)
88
class FakeRemoteBrokerTests(RemoteBrokerTestsMixin, LandscapeTest):
89
"""Tests for L{FakeRemoteBroker}."""
91
helpers = [ExchangeHelper]
94
return FakeRemoteBroker(self.exchanger, self.mstore)
97
class RemoteBrokerTests(RemoteBrokerTestsMixin, LandscapeIsolatedTest):
98
"""Tests for L{RemoteBroker}."""
100
helpers = [RemoteBrokerHelper]
104
return self.broker_service.message_store
108
return self.broker_service.exchanger
110
def get_remote(self):
112
Return a real L{RemoteBroker} object that will talk to a
113
L{BrokerDBusObject} over DBus.
117
def test_unknown_errors_will_errback(self):
119
The errback is invoked when an unknown error is raised during
122
self.log_helper.ignore_errors(AssertionError)
123
self.log_helper.ignore_errors(KeyError)
124
result = self.get_remote().send_message({"no-type": "none"})
125
self.assertFailure(result, DBusException)
126
def got_result(exception):
127
self.assertTrue("AssertionError" in str(exception))
128
result.addCallback(got_result)
132
def assertTransmitterActive(test_case, deployment_broker, target_reactor):
134
Make sure that there is a dbus message -> reactor event transmitter
137
The return value of this function should be returned from your test.
139
The common failure mode of this test is timing out. :-(
141
@param test_case: C{self}, most likely
142
@param deployment_broker: C{self.broker_service} if you are using the
143
L{RemoteBrokerHelper}.
144
@param target_reactor: A reactor which should have the
145
L{DBusSignalToReactorTransmitter} installed on it.
148
target_reactor.call_on("resynchronize", lambda: result.callback(None))
150
# *Kind* of reach into some guts to broadcast a message DBUS signal.
151
msg = {"type": "foo", "data": "whatever"}
152
deployment_broker.reactor.fire("resynchronize-clients")
157
class MessageDBusSignalToReactorTransmitterTests(LandscapeIsolatedTest):
159
helpers = [RemoteBrokerHelper]
161
def test_resynchronize(self):
163
A 'resynchronize' DBUS signal should be translated to a 'resynchronize'
166
reactor = FakeReactor()
167
DBusSignalToReactorTransmitter(self.broker_service.bus, reactor)
169
reactor.call_on("resynchronize", lambda: result.callback(None))
170
self.broker_service.reactor.fire("resynchronize-clients")
172
test_resynchronize.timeout = 4
174
def test_message_type_acceptance_changed(self):
176
A 'message-type-acceptance-changed' DBUS signal should be
177
translated to a 'message-type-acceptance-changed' reactor
180
reactor = FakeReactor()
181
DBusSignalToReactorTransmitter(self.broker_service.bus, reactor)
183
reactor.call_on(("message-type-acceptance-changed", u"some-type"),
185
result.addCallback(self.assertEquals, True)
186
self.broker_service.reactor.fire("message-type-acceptance-changed",
189
test_message_type_acceptance_changed.timeout = 4
191
def test_message_type_acceptance_changed_to_false(self):
193
A 'message-type-acceptance-changed' DBUS signal should be
194
translated to a 'message-type-acceptance-changed' reactor
197
reactor = FakeReactor()
198
DBusSignalToReactorTransmitter(self.broker_service.bus, reactor)
200
reactor.call_on(("message-type-acceptance-changed", u"some-type"),
202
result.addCallback(self.assertEquals, False)
203
self.broker_service.reactor.fire("message-type-acceptance-changed",
206
test_message_type_acceptance_changed.timeout = 4