29
31
def check_persist_property(self, attr, persist_name):
31
self.assertEquals(getattr(self.identity, attr), None,
32
"%r attribute should default to None, not %r" %
33
(attr, getattr(self.identity, attr)))
33
self.assertEqual(getattr(self.identity, attr), None,
34
"%r attribute should default to None, not %r" %
35
(attr, getattr(self.identity, attr)))
34
36
setattr(self.identity, attr, value)
35
self.assertEquals(getattr(self.identity, attr), value,
36
"%r attribute should be %r, not %r" %
37
(attr, value, getattr(self.identity, attr)))
37
self.assertEqual(getattr(self.identity, attr), value,
38
"%r attribute should be %r, not %r" %
39
(attr, value, getattr(self.identity, attr)))
39
41
self.persist.get(persist_name), value,
40
42
"%r not set to %r in persist" % (persist_name, value))
42
44
def check_config_property(self, attr):
44
46
setattr(self.config, attr, value)
45
self.assertEquals(getattr(self.identity, attr), value,
46
"%r attribute should be %r, not %r" %
47
(attr, value, getattr(self.identity, attr)))
47
self.assertEqual(getattr(self.identity, attr), value,
48
"%r attribute should be %r, not %r" %
49
(attr, value, getattr(self.identity, attr)))
49
51
def test_secure_id(self):
50
52
self.check_persist_property("secure_id",
89
91
self.exchanger.handle_message(
90
92
{"type": "set-id", "id": "abc", "insecure-id": "def"})
91
self.assertEquals(self.identity.secure_id, "abc")
92
self.assertEquals(self.identity.insecure_id, "def")
93
self.assertEqual(self.identity.secure_id, "abc")
94
self.assertEqual(self.identity.insecure_id, "def")
94
96
def test_registration_done_event(self):
107
109
self.identity.insecure_id = "old_id"
108
110
self.mstore.set_accepted_types(["register"])
109
111
self.exchanger.handle_message({"type": "unknown-id"})
110
self.assertEquals(self.identity.secure_id, None)
111
self.assertEquals(self.identity.insecure_id, None)
112
self.assertEqual(self.identity.secure_id, None)
113
self.assertEqual(self.identity.insecure_id, None)
113
115
def test_should_register(self):
114
116
self.mstore.set_accepted_types(["register"])
153
155
"registration_password": None,
154
156
"hostname": "ooga.local",
156
self.assertEquals(self.logfile.getvalue().strip(),
157
"INFO: Queueing message to register with account "
158
"'account_name' without a password.")
158
self.assertEqual(self.logfile.getvalue().strip(),
159
"INFO: Queueing message to register with account "
160
"'account_name' without a password.")
160
162
def test_queue_message_on_exchange_with_password(self):
161
163
"""If a registration password is available, we pass it on!"""
171
173
"registration_password": "SEKRET",
172
174
"hostname": "ooga.local",
174
self.assertEquals(self.logfile.getvalue().strip(),
175
"INFO: Queueing message to register with account "
176
"'account_name' with a password.")
176
self.assertEqual(self.logfile.getvalue().strip(),
177
"INFO: Queueing message to register with account "
178
"'account_name' with a password.")
178
180
def test_queue_message_on_exchange_with_tags(self):
193
195
"registration_password": "SEKRET",
194
196
"hostname": "ooga.local",
195
197
"tags": u"computer,tag"}])
196
self.assertEquals(self.logfile.getvalue().strip(),
197
"INFO: Queueing message to register with account "
198
"'account_name' and tags computer,tag "
198
self.assertEqual(self.logfile.getvalue().strip(),
199
"INFO: Queueing message to register with account "
200
"'account_name' and tags computer,tag "
201
203
def test_queue_message_on_exchange_with_invalid_tags(self):
218
220
"registration_password": "SEKRET",
219
221
"hostname": "ooga.local",
221
self.assertEquals(self.logfile.getvalue().strip(),
222
"ERROR: Invalid tags provided for cloud "
224
"INFO: Queueing message to register with account "
225
"'account_name' with a password.")
223
self.assertEqual(self.logfile.getvalue().strip(),
224
"ERROR: Invalid tags provided for cloud "
226
"INFO: Queueing message to register with account "
227
"'account_name' with a password.")
227
229
def test_queue_message_on_exchange_with_unicode_tags(self):
243
245
"registration_password": "SEKRET",
244
246
"hostname": "ooga.local",
245
247
"tags": u"prova\N{LATIN SMALL LETTER J WITH CIRCUMFLEX}o"}])
246
self.assertEquals(self.logfile.getvalue().strip(),
247
"INFO: Queueing message to register with account "
248
"'account_name' and tags prova\xc4\xb5o "
248
self.assertEqual(self.logfile.getvalue().strip(),
249
"INFO: Queueing message to register with account "
250
"'account_name' and tags prova\xc4\xb5o "
251
253
def test_queueing_registration_message_resets_message_store(self):
260
262
self.config.account_name = "account_name"
261
263
self.reactor.fire("pre-exchange")
262
264
messages = self.mstore.get_pending_messages()
263
self.assertEquals(len(messages), 1)
264
self.assertEquals(messages[0]["type"], "register")
265
self.assertEqual(len(messages), 1)
266
self.assertEqual(messages[0]["type"], "register")
266
268
def test_no_message_when_should_register_is_false(self):
267
269
"""If we already have a secure id, do not queue a register message.
314
316
self.identity.secure_id = "foo"
315
317
self.identity.insecure_id = "bar"
316
318
self.handler.register()
317
self.assertEquals(self.identity.secure_id, None)
318
self.assertEquals(self.identity.insecure_id, None)
319
self.assertEqual(self.identity.secure_id, None)
320
self.assertEqual(self.identity.insecure_id, None)
320
322
def test_register_calls_urgent_exchange(self):
321
323
exchanger_mock = self.mocker.patch(self.exchanger)
341
343
self.exchanger.handle_message(
342
344
{"type": "set-id", "id": "abc", "insecure-id": "def"})
344
self.assertEquals(calls, [1])
346
self.assertEqual(calls, [1])
346
348
# Doing it again to ensure that the deferred isn't called twice.
347
349
self.exchanger.handle_message(
348
350
{"type": "set-id", "id": "abc", "insecure-id": "def"})
350
self.assertEquals(calls, [1])
352
self.assertEqual(calls, [1])
352
self.assertEquals(self.logfile.getvalue(), "")
354
self.assertEqual(self.logfile.getvalue(), "")
354
356
def test_resynchronize_fired_when_registration_done(self):
366
368
self.exchanger.handle_message(
367
369
{"type": "set-id", "id": "abc", "insecure-id": "def"})
369
self.assertEquals(results, [True])
371
self.assertEqual(results, [True])
371
373
def test_register_deferred_called_on_failed(self):
372
374
# We don't want informational messages.
386
388
self.exchanger.handle_message(
387
389
{"type": "registration", "info": "unknown-account"})
389
self.assertEquals(calls, [1])
391
self.assertEqual(calls, [1])
391
393
# Doing it again to ensure that the deferred isn't called twice.
392
394
self.exchanger.handle_message(
393
395
{"type": "registration", "info": "unknown-account"})
395
self.assertEquals(calls, [1])
397
self.assertEqual(calls, [1])
397
self.assertEquals(self.logfile.getvalue(), "")
399
self.assertEqual(self.logfile.getvalue(), "")
399
401
def test_exchange_done_calls_exchange(self):
400
402
exchanger_mock = self.mocker.patch(self.exchanger)
454
456
def get_user_data(self, otps=None,
455
457
exchange_url="https://example.com/message-system",
456
ping_url="http://example.com/ping"):
458
ping_url="http://example.com/ping",
459
ssl_ca_certificate=None):
459
return {"otps": otps, "exchange-url": exchange_url,
460
"ping-url": ping_url}
462
user_data = {"otps": otps, "exchange-url": exchange_url,
463
"ping-url": ping_url}
464
if ssl_ca_certificate is not None:
465
user_data["ssl-ca-certificate"] = ssl_ca_certificate
462
468
def prepare_query_results(
463
469
self, user_data=None, instance_key="key1", launch_index=0,
464
470
local_hostname="ooga.local", public_hostname="ooga.amazon.com",
465
471
reservation_key=u"res1", ramdisk_key=u"ram1", kernel_key=u"kernel1",
466
image_key=u"image1"):
472
image_key=u"image1", ssl_ca_certificate=None):
467
473
if user_data is None:
468
user_data = self.get_user_data()
474
user_data = self.get_user_data(
475
ssl_ca_certificate=ssl_ca_certificate)
469
476
if not isinstance(user_data, Exception):
470
477
user_data = dumps(user_data)
471
478
api_base = "http://169.254.169.254/latest"
537
544
self.reactor.fire("run")
539
546
# And the metadata returned determines the URLs that are used
540
self.assertEquals(self.transport.get_url(),
541
"https://example.com/message-system")
542
self.assertEquals(self.pinger.get_url(),
543
"http://example.com/ping")
544
# Let's make sure those values were written back to the config file
547
self.assertEqual(self.transport.get_url(),
548
"https://example.com/message-system")
549
self.assertEqual(self.pinger.get_url(),
550
"http://example.com/ping")
551
# Lets make sure those values were written back to the config file
545
552
new_config = BrokerConfiguration()
546
553
new_config.load_configuration_file(self.config_filename)
547
self.assertEquals(new_config.url, "https://example.com/message-system")
548
self.assertEquals(new_config.ping_url, "http://example.com/ping")
554
self.assertEqual(new_config.url, "https://example.com/message-system")
555
self.assertEqual(new_config.ping_url, "http://example.com/ping")
550
557
# Okay! Exchange should cause the registration to happen.
551
558
self.exchanger.exchange()
552
559
# This *should* be asynchronous, but I think a billion tests are
553
560
# written like this
554
self.assertEquals(len(self.transport.payloads), 1)
561
self.assertEqual(len(self.transport.payloads), 1)
555
562
self.assertMessages(
556
563
self.transport.payloads[0]["messages"],
557
564
[self.get_expected_cloud_message(tags=u"server,london")])
569
576
# metadata is fetched and stored at reactor startup:
570
577
self.reactor.fire("run")
571
578
self.exchanger.exchange()
572
self.assertEquals(len(self.transport.payloads), 1)
579
self.assertEqual(len(self.transport.payloads), 1)
573
580
self.assertMessages(self.transport.payloads[0]["messages"],
574
581
[self.get_expected_cloud_message(tags=None)])
575
self.assertEquals(self.logfile.getvalue().strip(),
576
"ERROR: Invalid tags provided for cloud "
578
"INFO: Queueing message to register with OTP\n "
579
"INFO: Starting message exchange with "
580
"https://example.com/message-system.\n "
581
"INFO: Message exchange completed in 0.00s.")
582
self.assertEqual(self.logfile.getvalue().strip(),
583
"ERROR: Invalid tags provided for cloud "
585
"INFO: Queueing message to register with OTP\n "
586
"INFO: Starting message exchange with "
587
"https://example.com/message-system.\n "
588
"INFO: Message exchange completed in 0.00s.")
590
def test_cloud_registration_with_ssl_ca_certificate(self):
592
If we have an SSL certificate CA included in the user-data, this should
593
be written out, and the configuration updated to reflect this.
595
key_filename = os.path.join(self.config.data_path,
596
"%s.ssl_public_key" % os.path.basename(self.config_filename))
598
print_text_mock = self.mocker.replace(print_text)
599
print_text_mock("Writing SSL CA certificate to %s..." %
602
self.prepare_query_results(ssl_ca_certificate=u"1234567890")
603
self.prepare_cloud_registration(tags=u"server,london")
604
# metadata is fetched and stored at reactor startup:
605
self.reactor.fire("run")
606
# And the metadata returned determines the URLs that are used
607
self.assertEqual("https://example.com/message-system",
608
self.transport.get_url())
609
self.assertEqual(key_filename, self.transport.pubkey)
610
self.assertEqual("http://example.com/ping",
611
self.pinger.get_url())
612
# Let's make sure those values were written back to the config file
613
new_config = BrokerConfiguration()
614
new_config.load_configuration_file(self.config_filename)
615
self.assertEqual("https://example.com/message-system", new_config.url)
616
self.assertEqual("http://example.com/ping", new_config.ping_url)
617
self.assertEqual(key_filename, new_config.ssl_public_key)
618
self.assertEqual("1234567890", open(key_filename, "r").read())
583
620
def test_wrong_user_data(self):
584
621
self.prepare_query_results(user_data="other stuff, not a bpickle")
642
679
self.reactor.fire("run")
643
680
self.exchanger.exchange()
645
self.assertEquals(len(self.transport.payloads), 1)
682
self.assertEqual(len(self.transport.payloads), 1)
646
683
self.assertMessages(self.transport.payloads[0]["messages"],
647
684
[self.get_expected_cloud_message(
649
686
account_name=u"onward",
650
687
registration_password=u"password",
651
688
tags=u"london,server")])
652
self.assertEquals(self.logfile.getvalue().strip(),
689
self.assertEqual(self.logfile.getvalue().strip(),
653
690
"INFO: Queueing message to register with account u'onward' and "
654
691
"tags london,server as an EC2 instance.\n "
655
692
"INFO: Starting message exchange with http://localhost:91919.\n "
673
710
self.reactor.fire("pre-exchange")
675
712
messages = self.mstore.get_pending_messages()
676
self.assertEquals(len(messages), 1)
677
self.assertEquals(messages[0]["type"], "register-cloud-vm")
713
self.assertEqual(len(messages), 1)
714
self.assertEqual(messages[0]["type"], "register-cloud-vm")
679
716
def test_cloud_registration_fetch_errors(self):
721
758
self.exchanger.exchange()
722
759
self.assertIn("HTTPCodeError: Server returned HTTP code 404",
723
760
self.logfile.getvalue())
724
self.assertEquals(len(self.transport.payloads), 1)
761
self.assertEqual(len(self.transport.payloads), 1)
725
762
self.assertMessages(self.transport.payloads[0]["messages"],
726
763
[self.get_expected_cloud_message(
741
778
self.exchanger.exchange()
742
779
self.assertIn("HTTPCodeError: Server returned HTTP code 404",
743
780
self.logfile.getvalue())
744
self.assertEquals(len(self.transport.payloads), 1)
781
self.assertEqual(len(self.transport.payloads), 1)
745
782
self.assertMessages(self.transport.payloads[0]["messages"],
746
783
[self.get_expected_cloud_message(
747
784
ramdisk_key=None)])
762
799
self.exchanger.exchange()
763
800
self.assertIn("HTTPCodeError: Server returned HTTP code 404",
764
801
self.logfile.getvalue())
765
self.assertEquals(len(self.transport.payloads), 1)
802
self.assertEqual(len(self.transport.payloads), 1)
766
803
self.assertMessages(self.transport.payloads[0]["messages"],
767
804
[{"type": "register",
768
805
"computer_title": u"whatever",