1
from landscape.ui.tests.helpers import (
2
ConfigurationProxyHelper, FakeGSettings, dbus_test_should_skip,
3
dbus_skip_message, gobject_skip_message, got_gobject_introspection)
5
if got_gobject_introspection:
6
from landscape.ui.model.configuration.uisettings import UISettings
7
import landscape.ui.model.configuration.state
8
from landscape.ui.model.configuration.state import (
9
ConfigurationModel, StateError, VirginState, InitialisedState,
10
ModifiedState, MANAGEMENT_TYPE, HOSTED, LOCAL, HOSTED_LANDSCAPE_HOST,
11
LANDSCAPE_HOST, COMPUTER_TITLE, ExitedState)
12
from landscape.ui.model.configuration.mechanism import (
13
PermissionDeniedByPolicy)
14
from landscape.ui.constants import (
15
CANONICAL_MANAGED, LOCAL_MANAGED, NOT_MANAGED)
18
from landscape.tests.helpers import LandscapeTest
21
class AuthenticationFailureTest(LandscapeTest):
23
Test that an authentication failure is handled correctly in the
24
L{ConfigurationModel}.
26
helpers = [ConfigurationProxyHelper]
29
self.config_string = ""
30
self.default_data = {"management-type": "canonical",
32
"hosted-landscape-host": "",
33
"hosted-account-name": "",
34
"hosted-password": "",
35
"local-landscape-host": "",
36
"local-account-name": "",
38
landscape.ui.model.configuration.state.DEFAULT_DATA[COMPUTER_TITLE] \
40
super(AuthenticationFailureTest, self).setUp()
42
def test_failed_authentication(self):
44
Test that load returns False when authentication fails.
47
def fake_faily_load(arglist):
49
This simulates what you see if you click "Cancel" or give the wrong
50
credentials 3 times when L{PolicyKit} challenges you.
52
raise PermissionDeniedByPolicy()
54
def fake_exit_method():
56
Avoid raising a L{SystemExit} exception.
59
self.mechanism.load = fake_faily_load
60
settings = FakeGSettings(data=self.default_data)
61
uisettings = UISettings(settings)
62
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
63
self.assertFalse(model.load_data(asynchronous=False,
64
exit_method=fake_exit_method))
65
self.assertTrue(isinstance(model.get_state(), ExitedState))
67
if not got_gobject_introspection:
68
skip = gobject_skip_message
71
class ConfigurationModelTest(LandscapeTest):
73
Test the internal data handling of the L{ConfigurationModel} without
74
loading external data.
77
helpers = [ConfigurationProxyHelper]
80
self.config_string = ""
81
self.default_data = {"management-type": "canonical",
83
"hosted-landscape-host": "",
84
"hosted-account-name": "",
85
"hosted-password": "",
86
"local-landscape-host": "",
87
"local-account-name": "",
89
landscape.ui.model.configuration.state.DEFAULT_DATA[COMPUTER_TITLE] \
91
super(ConfigurationModelTest, self).setUp()
95
Test that L{get} correctly extracts data from the internal data storage
96
of the L{ConfigurationState}s associated with a L{ConfigurationModel}.
98
settings = FakeGSettings(data=self.default_data)
99
uisettings = UISettings(settings)
100
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
101
state = model.get_state()
102
self.assertEqual(NOT_MANAGED, state.get(MANAGEMENT_TYPE))
103
self.assertEqual(HOSTED_LANDSCAPE_HOST,
104
state.get(HOSTED, LANDSCAPE_HOST))
105
self.assertRaises(TypeError, state.get, MANAGEMENT_TYPE, HOSTED,
107
self.assertRaises(KeyError, state.get, LANDSCAPE_HOST)
108
self.assertRaises(KeyError, state.get, MANAGEMENT_TYPE, LANDSCAPE_HOST)
112
Test that L{set} correctly sets data in the internal data storage of
113
the L{ConfigurationState}s associated with a L{ConfigurationModel}.
115
settings = FakeGSettings(data=self.default_data)
116
uisettings = UISettings(settings)
117
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
118
state = model.get_state()
119
state.set(MANAGEMENT_TYPE, NOT_MANAGED)
120
self.assertEqual(NOT_MANAGED, state.get(MANAGEMENT_TYPE))
121
state.set(MANAGEMENT_TYPE, CANONICAL_MANAGED)
122
self.assertEqual(CANONICAL_MANAGED, state.get(MANAGEMENT_TYPE))
123
state.set(MANAGEMENT_TYPE, LOCAL_MANAGED)
124
self.assertEqual(LOCAL_MANAGED, state.get(MANAGEMENT_TYPE))
125
self.assertEqual("", state.get(LOCAL, LANDSCAPE_HOST))
126
state.set(LOCAL, LANDSCAPE_HOST, "goodison.park")
127
self.assertEqual("goodison.park", state.get(LOCAL, LANDSCAPE_HOST))
129
def test_virginal(self):
131
Test that the L{ConfigurationModel} is created with default data. This
132
should be managed via L{VirginState} (hence the name), but this should
133
not be exposed and is not explicitly tested here (see
134
L{StateTransitionTest}).
136
settings = FakeGSettings(data=self.default_data)
137
uisettings = UISettings(settings)
138
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
139
self.assertEqual(NOT_MANAGED, model.management_type)
140
self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
141
self.assertEqual("bound.to.lose", model.computer_title)
142
self.assertEqual("", model.local_landscape_host)
143
self.assertEqual("", model.hosted_account_name)
144
self.assertEqual("standalone", model.local_account_name)
145
self.assertEqual("", model.hosted_password)
147
def test_is_hosted_property(self):
149
Test we can use the L{is_hosted} property to set and get that data on
150
the current L{ConfigurationState}.
152
settings = FakeGSettings(data=self.default_data)
153
uisettings = UISettings(settings)
154
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
156
self.assertEqual(CANONICAL_MANAGED, model.management_type)
157
model.management_type = LOCAL_MANAGED
158
self.assertEqual(LOCAL_MANAGED, model.management_type)
159
model.management_type = NOT_MANAGED
160
self.assertEqual(NOT_MANAGED, model.management_type)
162
def test_computer_title_property(self):
164
Test that we can use the L{computer_title} property to set and get that
165
data on the current L{ConfigurationState}.
167
settings = FakeGSettings(data=self.default_data)
168
uisettings = UISettings(settings)
169
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
171
self.assertEqual("bound.to.lose", model.computer_title)
172
model.computer_title = "bound.to.win"
173
self.assertEqual("bound.to.win", model.computer_title)
175
def test_hosted_landscape_host_property(self):
177
Test we can use the L{hosted_landscape_host} property to set and get
178
that data on the current L{ConfigurationState}.
180
settings = FakeGSettings(data=self.default_data)
181
uisettings = UISettings(settings)
182
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
183
self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
184
self.assertRaises(AttributeError, setattr, model,
185
"hosted_landscape_host", "foo")
187
def test_hosted_account_name_property(self):
189
Test we can use the L{hosted_account_name} property to set and get
190
that data on the current L{ConfigurationState}.
192
settings = FakeGSettings(data=self.default_data)
193
uisettings = UISettings(settings)
194
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
195
self.assertEqual("", model.hosted_account_name)
196
model.hosted_account_name = "foo"
197
self.assertEqual("foo", model.hosted_account_name)
199
def test_hosted_password_property(self):
201
Test we can use the L{hosted_password} property to set and get
202
that data on the current L{ConfigurationState}.
204
settings = FakeGSettings(data=self.default_data)
205
uisettings = UISettings(settings)
206
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
207
self.assertEqual("", model.hosted_password)
208
model.hosted_password = "foo"
209
self.assertEqual("foo", model.hosted_password)
211
def test_local_landscape_host_property(self):
213
Test we can use the L{local_landscape_host} property to set and get
214
that data on the current L{ConfigurationState}.
216
settings = FakeGSettings(data=self.default_data)
217
uisettings = UISettings(settings)
218
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
219
self.assertEqual("", model.local_landscape_host)
220
model.local_landscape_host = "foo"
221
self.assertEqual("foo", model.local_landscape_host)
223
def test_local_account_name_property(self):
225
Test we can use the L{local_account_name} property to set and get
226
that data on the current L{ConfigurationState}.
228
settings = FakeGSettings(data=self.default_data)
229
uisettings = UISettings(settings)
230
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
231
self.assertEqual("standalone", model.local_account_name)
232
model.local_account_name = "foo"
233
self.assertEqual("foo", model.local_account_name)
235
def test_local_password_property(self):
237
Test we can use the L{local_password} property to set and get
238
that data on the current L{ConfigurationState}.
240
settings = FakeGSettings(data=self.default_data)
241
uisettings = UISettings(settings)
242
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
243
self.assertEqual("", model.local_password)
244
model.local_password = "foo"
245
self.assertEqual("foo", model.local_password)
249
Test that we can cause the mechanism to exit.
251
settings = FakeGSettings(data=self.default_data)
252
uisettings = UISettings(settings)
253
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
254
self.assertRaises(SystemExit, model.exit, asynchronous=False)
256
if not got_gobject_introspection:
257
skip = gobject_skip_message
258
elif dbus_test_should_skip:
259
skip = dbus_skip_message
262
class ConfigurationModelHostedTest(LandscapeTest):
264
Test the L{ConfigurationModel} is correctly initialised when the live
265
configuration is set for a hosted account.
267
Note the multilayer data loading:
269
1. Internal state is defaulted.
270
2. UISettings data is loaded.
271
3. Live configuration is loaded.
274
helpers = [ConfigurationProxyHelper]
276
default_data = {"management-type": "canonical",
277
"computer-title": "bound.to.lose",
278
"hosted-landscape-host": "landscape.canonical.com",
279
"hosted-account-name": "Sparklehorse",
280
"hosted-password": "Vivadixiesubmarinetransmissionplot",
281
"local-landscape-host": "the.local.machine",
282
"local-account-name": "CrazyHorse",
283
"local-password": "RustNeverSleeps"}
286
self.config_string = "[client]\n" \
287
"data_path = /var/lib/landscape/client/\n" \
288
"http_proxy = http://proxy.localdomain:3192\n" \
290
"url = https://landscape.canonical.com/message-system\n" \
291
"account_name = foo\n" \
292
"registration_password = boink\n" \
293
"computer_title = baz\n" \
294
"https_proxy = https://proxy.localdomain:6192\n" \
295
"ping_url = http://landscape.canonical.com/ping\n"
297
super(ConfigurationModelHostedTest, self).setUp()
299
def test_initialised_hosted(self):
301
Test the L{ConfigurationModel} is correctly initialised from a proxy
302
and defaults with hosted data.
304
settings = FakeGSettings(data=self.default_data)
305
uisettings = UISettings(settings)
306
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
308
self.assertEqual(CANONICAL_MANAGED, model.management_type)
309
self.assertEqual("landscape.canonical.com",
310
model.hosted_landscape_host)
311
self.assertEqual("the.local.machine", model.local_landscape_host)
312
self.assertEqual("foo", model.hosted_account_name)
313
self.assertEqual("CrazyHorse", model.local_account_name)
314
self.assertEqual("boink", model.hosted_password)
316
if not got_gobject_introspection:
317
skip = gobject_skip_message
318
elif dbus_test_should_skip:
319
skip = dbus_skip_message
322
class ConfigurationModelLocalTest(LandscapeTest):
324
helpers = [ConfigurationProxyHelper]
326
default_data = {"management-type": "LDS",
327
"computer-title": "bound.to.lose",
328
"hosted-landscape-host": "landscape.canonical.com",
329
"hosted-account-name": "Sparklehorse",
330
"hosted-password": "Vivadixiesubmarinetransmissionplot",
331
"local-landscape-host": "the.local.machine",
332
"local-account-name": "CrazyHorse",
333
"local-password": "RustNeverSleeps"}
336
self.config_string = "[client]\n" \
337
"data_path = /var/lib/landscape/client/\n" \
338
"http_proxy = http://proxy.localdomain:3192\n" \
340
"url = https://landscape.localdomain/message-system\n" \
341
"account_name = foo\n" \
342
"registration_password = boink\n" \
343
"computer_title = baz\n" \
345
"ping_url = http://landscape.localdomain/ping\n"
347
super(ConfigurationModelLocalTest, self).setUp()
349
def test_initialised_local(self):
351
Test the L{ConfigurationModel} is correctly initialised from a proxy
352
and defaults with local data.
354
settings = FakeGSettings(data=self.default_data)
355
uisettings = UISettings(settings)
356
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
358
self.assertEqual(LOCAL_MANAGED, model.management_type)
359
self.assertEqual("landscape.canonical.com",
360
model.hosted_landscape_host)
361
self.assertEqual("landscape.localdomain", model.local_landscape_host)
362
self.assertEqual("Sparklehorse", model.hosted_account_name)
363
self.assertEqual("foo", model.local_account_name)
364
self.assertEqual("Vivadixiesubmarinetransmissionplot",
365
model.hosted_password)
367
if not got_gobject_introspection:
368
skip = gobject_skip_message
369
elif dbus_test_should_skip:
370
skip = dbus_skip_message
373
class StateTransitionTest(LandscapeTest):
375
Test that we make the correct state transitions when taking actions on the
376
L{ConfigurationModel}.
379
helpers = [ConfigurationProxyHelper]
382
self.config_string = ""
383
self.default_data = {
384
"management-type": "canonical",
385
"computer-title": "bound.to.lose",
386
"hosted-landscape-host": "landscape.canonical.com",
387
"hosted-account-name": "Sparklehorse",
388
"hosted-password": "Vivadixiesubmarinetransmissionplot",
389
"local-landscape-host": "the.local.machine",
390
"local-account-name": "CrazyHorse",
391
"local-password": "RustNeverSleeps"}
392
super(StateTransitionTest, self).setUp()
394
def test_load_data_transitions(self):
396
Test that the L{ConfigurationModel} correctly changes state as we call
399
settings = FakeGSettings(data=self.default_data)
400
uisettings = UISettings(settings)
401
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
402
self.assertTrue(isinstance(model.get_state(), VirginState))
404
self.assertTrue(isinstance(model.get_state(), InitialisedState))
405
initialised = model.get_state()
407
self.assertTrue(isinstance(model.get_state(), InitialisedState))
408
self.assertIs(initialised, model.get_state())
410
def test_modifying_a_virgin_raises(self):
412
Test that attempting a L{modify} a L{ConfigurationModel} in
413
L{VirginState} raises a L{StateError}.
415
settings = FakeGSettings(data=self.default_data)
416
uisettings = UISettings(settings)
417
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
418
self.assertRaises(StateError, model.modify)
420
def test_initialised_state_is_modifiable(self):
422
Test that the L{ConfigurationModel} transitions to L{ModifiedState}
423
whenever L{modify} is called on it in L{InitialisedState}.
425
settings = FakeGSettings(data=self.default_data)
426
uisettings = UISettings(settings)
427
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
429
self.assertEqual(CANONICAL_MANAGED, model.management_type)
430
model.management_type = LOCAL_MANAGED
431
self.assertEqual(LOCAL_MANAGED, model.management_type)
433
self.assertTrue(isinstance(model.get_state(), ModifiedState))
434
self.assertEqual(LOCAL_MANAGED, model.management_type)
436
def test_modified_state_is_modifiable(self):
438
Test that the L{ConfigurationModel} transitions to L{ModifiedState}
439
whenever L{modify} is called on it in L{ModifiedState}.
441
settings = FakeGSettings(data=self.default_data)
442
uisettings = UISettings(settings)
443
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
446
self.assertTrue(isinstance(model.get_state(), ModifiedState))
448
self.assertTrue(isinstance(model.get_state(), ModifiedState))
450
def test_reverting_a_virgin_raises(self):
452
Test that calling L{revert} on a L{ConfigurationModel} in
453
L{VirginState} raises a L{StateError}.
455
settings = FakeGSettings(data=self.default_data)
456
uisettings = UISettings(settings)
457
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
458
self.assertRaises(StateError, model.revert)
460
def test_initialiased_state_is_unrevertable(self):
462
Test that calling L{revert} on a L{ConfigurationModel} in
463
L{InitialisedState} raises a L{StateError}.
465
settings = FakeGSettings(data=self.default_data)
466
uisettings = UISettings(settings)
467
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
469
self.assertRaises(StateError, model.revert)
471
def test_modified_state_is_revertable(self):
473
Test that a L{ConfigurationModel} in L{ModifiedState} can be
474
transitioned via L{revert} to L{InitialisedState}.
476
settings = FakeGSettings(data=self.default_data)
477
uisettings = UISettings(settings)
478
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
482
self.assertTrue(isinstance(model.get_state(), InitialisedState))
484
def test_reverting_reverts_data(self):
486
Test that transitioning via L{revert} causes the original
487
L{InitialisedState} to be restored.
489
settings = FakeGSettings(data=self.default_data)
490
uisettings = UISettings(settings)
491
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
493
self.assertEqual(HOSTED_LANDSCAPE_HOST, model.hosted_landscape_host)
494
self.assertEqual("CrazyHorse", model.local_account_name)
495
model.local_account_name = "bar"
497
self.assertEqual("bar", model.local_account_name)
499
self.assertTrue(isinstance(model.get_state(), InitialisedState))
500
self.assertEqual("CrazyHorse", model.local_account_name)
502
def test_persisting_a_virgin_raises(self):
504
Test that a L{ConfigurationModel} in L{VirginState} will raise a
505
L{StateError} when you attempt to transition it with L{persist}.
507
settings = FakeGSettings(data=self.default_data)
508
uisettings = UISettings(settings)
509
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
510
self.assertRaises(StateError, model.persist)
512
def test_persisting_initialised_state_raises(self):
514
Test that a L{ConfigurationModel} in L{IntialisedState} will raise a
515
L{StateError} when you attempt to transition it with L{persist}.
517
settings = FakeGSettings(data=self.default_data)
518
uisettings = UISettings(settings)
519
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
521
self.assertRaises(StateError, model.persist)
523
def test_persisting_modified_is_allowed(self):
525
Test that a L{ConfigurationModel} in L{ModifiedState} will allow itself
526
to be transitioned with L{persist}.
528
settings = FakeGSettings(data=self.default_data)
529
uisettings = UISettings(settings)
530
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
534
self.assertTrue(isinstance(model.get_state(), InitialisedState))
536
def test_persisting_saves_data_to_uisettings(self):
537
settings = FakeGSettings(data=self.default_data)
538
uisettings = UISettings(settings)
539
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
541
self.assertEqual(CANONICAL_MANAGED, uisettings.get_management_type())
542
self.assertEqual("Sparklehorse", uisettings.get_hosted_account_name())
543
self.assertEqual("Vivadixiesubmarinetransmissionplot",
544
uisettings.get_hosted_password())
545
self.assertEqual("the.local.machine",
546
uisettings.get_local_landscape_host())
547
self.assertEqual("CrazyHorse", uisettings.get_local_account_name())
548
self.assertEqual("RustNeverSleeps", uisettings.get_local_password())
549
model.management_type = LOCAL_MANAGED
550
model.hosted_account_name = "ThomasPaine"
551
model.hosted_password = "TheAgeOfReason"
552
model.local_landscape_host = "another.local.machine"
553
model.local_account_name = "ThomasHobbes"
554
model.local_password = "TheLeviathan"
556
self.assertTrue(isinstance(model.get_state(), ModifiedState))
558
self.assertTrue(isinstance(model.get_state(), InitialisedState))
559
self.assertEqual(LOCAL_MANAGED, uisettings.get_management_type())
560
self.assertEqual("ThomasPaine", uisettings.get_hosted_account_name())
561
self.assertEqual("TheAgeOfReason", uisettings.get_hosted_password())
562
self.assertEqual("another.local.machine",
563
uisettings.get_local_landscape_host())
564
self.assertEqual("ThomasHobbes", uisettings.get_local_account_name())
565
self.assertEqual("TheLeviathan", uisettings.get_local_password())
567
def test_any_transition_on_exited_state_raises(self):
569
Test that we cannot transition the L{ExitedState} at all.
574
This just avoids raising L{exceptions.SysExit} during __init__.
577
state = ExitedState(None, None, None, exit_method=fake_exit)
578
self.assertRaises(StateError, state.load_data)
579
self.assertRaises(StateError, state.modify)
580
self.assertRaises(StateError, state.persist)
581
self.assertRaises(StateError, state.revert)
583
if not got_gobject_introspection:
584
skip = gobject_skip_message
585
elif dbus_test_should_skip:
586
skip = dbus_skip_message
589
class StateTransitionWithExistingConfigTest(LandscapeTest):
591
Test that we handle existing configuration data correctly when
592
transitioning through L{ConfigurationModel} states.
595
helpers = [ConfigurationProxyHelper]
598
self.config_string = (
600
"data_path = /var/lib/landscape/client/\n"
601
"http_proxy = http://proxy.localdomain:3192\n"
603
"url = https://landscape.canonical.com/message-system\n"
604
"account_name = Sparklehorse\n"
605
"registration_password = Vivadixiesubmarinetransmissionplot\n"
606
"computer_title = baz\n"
607
"https_proxy = https://proxy.localdomain:6192\n"
608
"ping_url = http://landscape.canonical.com/ping\n")
609
self.default_data = {
610
"management-type": "canonical",
611
"computer-title": "bound.to.lose",
612
"hosted-landscape-host": "landscape.canonical.com",
613
"hosted-account-name": "Sparklehorse",
614
"hosted-password": "Vivadixiesubmarinetransmissionplot",
615
"local-landscape-host": "the.local.machine",
616
"local-account-name": "CrazyHorse",
617
"local-password": "RustNeverSleeps"}
618
super(StateTransitionWithExistingConfigTest, self).setUp()
620
def test_persisting_saves_data_to_proxy(self):
621
settings = FakeGSettings(data=self.default_data)
622
uisettings = UISettings(settings)
623
model = ConfigurationModel(proxy=self.proxy, uisettings=uisettings)
625
self.assertEqual("Sparklehorse", self.proxy.account_name)
626
self.assertEqual("Vivadixiesubmarinetransmissionplot",
627
self.proxy.registration_password)
628
model.management_type = LOCAL_MANAGED
629
model.local_account_name = "ThomasPaine"
630
model.local_password = "TheAgeOfReason"
632
self.assertTrue(isinstance(model.get_state(), ModifiedState))
634
self.assertTrue(isinstance(model.get_state(), InitialisedState))
635
self.assertEqual(LOCAL_MANAGED, model.management_type)
636
self.assertEqual("https://the.local.machine/message-system",
638
self.assertEqual("http://the.local.machine/ping", self.proxy.ping_url)
639
self.assertEqual("ThomasPaine", self.proxy.account_name)
640
self.assertEqual("TheAgeOfReason", self.proxy.registration_password)
642
if not got_gobject_introspection:
643
skip = gobject_skip_message
644
elif dbus_test_should_skip:
645
skip = dbus_skip_message