1
from twisted.internet.defer import fail
3
from landscape.lib.persist import Persist
4
from landscape.lib.dbus_util import get_object
6
from landscape.monitor.monitor import MonitorPluginRegistry
7
from landscape.monitor.usermonitor import UserMonitor, UserMonitorDBusObject
8
from landscape.manager.usermanager import UserManagerDBusObject
9
from landscape.user.tests.helpers import FakeUserProvider
10
from landscape.tests.helpers import LandscapeIsolatedTest
11
from landscape.tests.helpers import MakePathHelper, RemoteBrokerHelper
12
from landscape.tests.mocker import ANY
15
class UserMonitorTest(LandscapeIsolatedTest):
17
helpers = [MakePathHelper, RemoteBrokerHelper]
20
super(UserMonitorTest, self).setUp()
21
self.persist = Persist()
22
self.monitor = MonitorPluginRegistry(
23
self.broker_service.reactor, self.remote,
24
self.broker_service.config, self.broker_service.bus,
26
self.shadow_file = self.make_path("""\
27
jdoe:$1$xFlQvTqe$cBtrNEDOIKMy/BuJoUdeG0:13348:0:99999:7:::
28
psmith:!:13348:0:99999:7:::
29
sbarnes:$1$q7sz09uw$q.A3526M/SHu8vUb.Jo1A/:13349:0:99999:7:::
32
self.service = UserManagerDBusObject(self.broker_service.bus,
33
shadow_file=self.shadow_file)
35
def test_constants(self):
37
L{UserMonitor.persist_name} and
38
L{UserMonitor.run_interval} need to be present for
39
L{Plugin} to work properly.
41
plugin = UserMonitor(FakeUserProvider())
42
self.assertEquals(plugin.persist_name, "users")
43
self.assertEquals(plugin.run_interval, 3600)
45
def test_wb_resynchronize_event(self):
47
When a C{resynchronize} event occurs any cached L{UserChange}
48
snapshots should be cleared.
50
def resynchronize_complete(result, plugin):
51
persist = plugin._persist
52
self.assertTrue(persist.get("users"))
53
self.assertTrue(persist.get("groups"))
54
self.monitor.reactor.fire("resynchronize")
55
self.assertFalse(persist.get("users"))
56
self.assertFalse(persist.get("groups"))
58
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
59
groups = [("webdev", "x", 1000, ["jdoe"])]
60
self.broker_service.message_store.set_accepted_types(["users"])
61
provider = FakeUserProvider(users=users, groups=groups)
62
plugin = UserMonitor(provider=provider)
63
self.monitor.add(plugin)
64
deferred = plugin.run()
65
deferred.addCallback(resynchronize_complete, plugin)
70
The L{UserMonitor} should have message run which should enqueue a
71
message with a diff-like representation of changes since the last
74
def got_result(result):
76
self.broker_service.message_store.get_pending_messages(),
77
[{"create-group-members": {u"webdev":[u"jdoe"]},
78
"create-groups": [{"gid": 1000, "name": u"webdev"}],
79
"create-users": [{"enabled": True, "home-phone": None,
80
"location": None, "name": u"JD",
81
"primary-gid": 1000, "uid": 1000,
82
"username": u"jdoe", "work-phone": None}],
85
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
86
groups = [("webdev", "x", 1000, ["jdoe"])]
87
provider = FakeUserProvider(users=users, groups=groups)
88
plugin = UserMonitor(provider=provider)
89
self.monitor.add(plugin)
90
self.broker_service.message_store.set_accepted_types(["users"])
92
result.addCallback(got_result)
95
def test_run_interval(self):
97
L{UserMonitor.register} calls the C{register} method on it's
98
super class, which sets up a looping call to run the plugin
99
every L{UserMonitor.run_interval} seconds.
101
provider = FakeUserProvider(users=[], groups=[])
102
plugin = UserMonitor(provider=provider)
104
mock_plugin = self.mocker.patch(plugin)
109
self.monitor.add(plugin)
110
self.broker_service.message_store.set_accepted_types(["users"])
111
self.monitor.reactor.advance(plugin.run_interval*5)
113
def test_run_with_operation_id(self):
115
The L{UserMonitor} should have message run which should enqueue a
116
message with a diff-like representation of changes since the last
119
def got_result(result):
121
self.broker_service.message_store.get_pending_messages(),
122
[{"create-group-members": {u"webdev":[u"jdoe"]},
123
"create-groups": [{"gid": 1000, "name": u"webdev"}],
124
"create-users": [{"enabled": True, "home-phone": None,
125
"location": None, "name": u"JD",
126
"primary-gid": 1000, "uid": 1000,
127
"username": u"jdoe", "work-phone": None}],
128
"operation-id": 1001,
132
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
133
groups = [("webdev", "x", 1000, ["jdoe"])]
134
provider = FakeUserProvider(users=users, groups=groups)
136
plugin = UserMonitor(provider=provider)
137
self.monitor.add(plugin)
138
self.broker_service.message_store.set_accepted_types(["users"])
139
result = plugin.run(1001)
140
result.addCallback(got_result)
143
def test_detect_changes(self):
144
def got_result(result):
146
self.broker_service.message_store.get_pending_messages(),
147
[{"create-group-members": {u"webdev":[u"jdoe"]},
148
"create-groups": [{"gid": 1000, "name": u"webdev"}],
149
"create-users": [{"enabled": True, "home-phone": None,
150
"location": None, "name": u"JD",
151
"primary-gid": 1000, "uid": 1000,
152
"username": u"jdoe", "work-phone": None}],
155
self.broker_service.message_store.set_accepted_types(["users"])
156
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
157
groups = [("webdev", "x", 1000, ["jdoe"])]
158
provider = FakeUserProvider(users=users, groups=groups)
160
plugin = UserMonitor(provider=provider)
161
self.monitor.add(plugin)
162
remote_service = get_object(self.broker_service.bus,
163
UserMonitorDBusObject.bus_name, UserMonitorDBusObject.object_path)
164
result = remote_service.detect_changes()
165
result.addCallback(got_result)
168
def test_detect_changes_with_operation_id(self):
170
The L{UserMonitor} should expose a remote
171
C{remote_run} method which should call the remote
173
def got_result(result):
175
self.broker_service.message_store.get_pending_messages(),
176
[{"create-group-members": {u"webdev":[u"jdoe"]},
177
"create-groups": [{"gid": 1000, "name": u"webdev"}],
178
"create-users": [{"enabled": True, "home-phone": None,
179
"location": None, "name": u"JD",
180
"primary-gid": 1000, "uid": 1000,
181
"username": u"jdoe", "work-phone": None}],
182
"operation-id": 1001,
185
self.broker_service.message_store.set_accepted_types(["users"])
186
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
187
groups = [("webdev", "x", 1000, ["jdoe"])]
188
provider = FakeUserProvider(users=users, groups=groups)
190
plugin = UserMonitor(provider=provider)
191
self.monitor.add(plugin)
193
remote_service = get_object(self.broker_service.bus,
194
UserMonitorDBusObject.bus_name, UserMonitorDBusObject.object_path)
195
result = remote_service.detect_changes(1001)
196
result.addCallback(got_result)
199
def test_no_message_if_not_accepted(self):
201
Don't add any messages at all if the broker isn't currently
202
accepting their type.
204
def got_result(result):
205
mstore = self.broker_service.message_store
206
self.assertMessages(list(mstore.get_pending_messages()), [])
207
mstore.set_accepted_types(["users"])
208
self.assertMessages(list(mstore.get_pending_messages()), [])
210
self.broker_service.message_store.set_accepted_types([])
211
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
212
groups = [("webdev", "x", 1000, ["jdoe"])]
213
provider = FakeUserProvider(users=users, groups=groups)
215
plugin = UserMonitor(provider=provider)
216
self.monitor.add(plugin)
217
remote_service = get_object(self.broker_service.bus,
218
UserMonitorDBusObject.bus_name, UserMonitorDBusObject.object_path)
219
result = remote_service.detect_changes(1001)
220
result.addCallback(got_result)
223
def test_call_on_accepted(self):
224
def got_result(result):
225
mstore = self.broker_service.message_store
226
self.assertMessages(mstore.get_pending_messages(),
227
[{"create-group-members": {u"webdev":[u"jdoe"]},
228
"create-groups": [{"gid": 1000, "name": u"webdev"}],
229
"create-users": [{"enabled": True, "home-phone": None,
230
"location": None, "name": u"JD",
231
"primary-gid": 1000, "uid": 1000,
232
"username": u"jdoe", "work-phone": None}],
235
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
236
groups = [("webdev", "x", 1000, ["jdoe"])]
237
provider = FakeUserProvider(users=users, groups=groups)
239
plugin = UserMonitor(provider=provider)
240
self.monitor.add(plugin)
242
self.broker_service.message_store.set_accepted_types(["users"])
243
result = self.broker_service.reactor.fire(
244
("message-type-acceptance-changed", "users"), True)
245
result = [x for x in result if x][0]
246
result.addCallback(got_result)
249
def test_do_not_persist_changes_when_send_message_fails(self):
251
When the plugin is run it persists data that it uses on
252
subsequent checks to calculate the delta to send. It should
253
only persist data when the broker confirms that the message
254
sent by the plugin has been sent.
256
self.log_helper.ignore_errors(RuntimeError)
257
def got_result(result):
258
persist = plugin._persist
259
mstore = self.broker_service.message_store
260
self.assertMessages(mstore.get_pending_messages(), [])
261
self.assertFalse(persist.get("users"))
262
self.assertFalse(persist.get("groups"))
264
self.broker_service.message_store.set_accepted_types(["users"])
265
broker_mock = self.mocker.replace(self.monitor.broker)
266
broker_mock.send_message(ANY, urgent=True)
267
self.mocker.result(fail(RuntimeError()))
270
users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")]
271
groups = [("webdev", "x", 1000, ["jdoe"])]
272
provider = FakeUserProvider(users=users, groups=groups)
273
plugin = UserMonitor(provider=provider)
274
self.monitor.add(plugin)
275
remote_service = get_object(self.broker_service.bus,
276
UserMonitorDBusObject.bus_name, UserMonitorDBusObject.object_path)
277
result = remote_service.detect_changes(1001)
278
result.addCallback(got_result)