1# This file is part of Buildbot. Buildbot is free software: you can 2# redistribute it and/or modify it under the terms of the GNU General Public 3# License as published by the Free Software Foundation, version 2. 4# 5# This program is distributed in the hope that it will be useful, but WITHOUT 6# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 7# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 8# details. 9# 10# You should have received a copy of the GNU General Public License along with 11# this program; if not, write to the Free Software Foundation, Inc., 51 12# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 13# 14# Copyright Buildbot Team Members 15 16from parameterized import parameterized 17 18import mock 19 20from twisted.internet import defer 21from twisted.trial import unittest 22 23from buildbot.test.fake import fakemaster 24from buildbot.test.util.misc import TestReactorMixin 25from buildbot.util import service 26from buildbot.wamp import connector 27 28 29class FakeConfig: 30 def __init__(self, mq_dict): 31 self.mq = mq_dict 32 33 34class FakeService(service.AsyncMultiService): 35 name = "fakeWampService" 36 # Fake wamp service 37 # just call the maker on demand by the test 38 39 def __init__(self, url, realm, make, extra=None, 40 debug=False, debug_wamp=False, debug_app=False): 41 super().__init__() 42 self.make = make 43 self.extra = extra 44 45 def gotConnection(self): 46 self.make(None) 47 r = self.make(self) 48 r.publish = mock.Mock(spec=r.publish) 49 r.register = mock.Mock(spec=r.register) 50 r.subscribe = mock.Mock(spec=r.subscribe) 51 r.onJoin(None) 52 53 54class TestedWampConnector(connector.WampConnector): 55 serviceClass = FakeService 56 57 58class WampConnector(TestReactorMixin, unittest.TestCase): 59 60 @defer.inlineCallbacks 61 def setUp(self): 62 self.setUpTestReactor() 63 master = fakemaster.make_master(self) 64 self.connector = TestedWampConnector() 65 66 config = FakeConfig({'type': 'wamp', 'router_url': "wss://foo", 'realm': "bb"}) 67 68 yield self.connector.setServiceParent(master) 69 yield master.startService() 70 yield self.connector.reconfigServiceWithBuildbotConfig(config) 71 72 @defer.inlineCallbacks 73 def test_reconfig_same_config(self): 74 config = FakeConfig({'type': 'wamp', 'router_url': "wss://foo", 'realm': "bb"}) 75 yield self.connector.reconfigServiceWithBuildbotConfig(config) 76 77 @parameterized.expand([ 78 ('type', 'simple'), 79 ('router_url', 'wss://other-foo'), 80 ('realm', 'bb-other'), 81 ('wamp_debug_level', 'info'), 82 ]) 83 @defer.inlineCallbacks 84 def test_reconfig_does_not_allow_config_change(self, attr_name, attr_value): 85 mq_dict = {'type': 'wamp', 'router_url': "wss://foo", 'realm': "bb"} 86 mq_dict[attr_name] = attr_value 87 with self.assertRaises(ValueError, 88 msg="Cannot use different wamp settings when reconfiguring"): 89 yield self.connector.reconfigServiceWithBuildbotConfig(FakeConfig(mq_dict)) 90 91 @defer.inlineCallbacks 92 def test_startup(self): 93 d = self.connector.getService() 94 self.connector.app.gotConnection() 95 yield d 96 # 824 is the hardcoded masterid of fakemaster 97 self.connector.service.publish.assert_called_with( 98 "org.buildbot.824.connected") 99 100 @defer.inlineCallbacks 101 def test_subscribe(self): 102 d = self.connector.subscribe('callback', 'topic', 'options') 103 self.connector.app.gotConnection() 104 yield d 105 self.connector.service.subscribe.assert_called_with( 106 'callback', 'topic', 'options') 107 108 @defer.inlineCallbacks 109 def test_publish(self): 110 d = self.connector.publish('topic', 'data', 'options') 111 self.connector.app.gotConnection() 112 yield d 113 self.connector.service.publish.assert_called_with( 114 'topic', 'data', options='options') 115 116 @defer.inlineCallbacks 117 def test_OnLeave(self): 118 d = self.connector.getService() 119 self.connector.app.gotConnection() 120 yield d 121 self.assertTrue(self.connector.master.running) 122 self.connector.service.onLeave(None) 123 self.assertFalse(self.connector.master.running) 124