~landscape/landscape-client/trunk

« back to all changes in this revision

Viewing changes to landscape/broker/tests/test_exchange.py

Merge landscape-config-dont-restart-twice [f=1376134] [r=benji,tealeg] [a=Free Ekanayaka]
This branch fixes two issues happening when switching a client
between servers.

1) Stop landscape-config from sending the reload_config() command to
   the broker, since the script has already restarted all services
   just a few moments before. This prevents the first exchange from
   happening without the monitor fully started, hence missing the
   server-uuid-change that the broker broadcasts and that the monitor
   is supposed to handle in order to clear the local hash-id map.

2) Make the Exchange downgrade the API server version currently in use
   if it gets a 404 from the server. This can happen for example if
   a client registered against a newer server is switched to an older
   server that doesn't support the same API version that the new one does.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
from landscape import CLIENT_API
2
2
from landscape.lib.persist import Persist
 
3
from landscape.lib.fetch import HTTPCodeError
3
4
from landscape.lib.hashlib import md5
4
5
from landscape.schema import Message, Int
5
6
from landscape.broker.config import BrokerConfiguration
14
15
from landscape.broker.server import BrokerServer
15
16
 
16
17
 
17
 
class RaisingTransport(object):
18
 
 
19
 
    def get_url(self2):
20
 
        return ""
21
 
 
22
 
    def exchange(self2, *args):
23
 
        raise RuntimeError("Failed to communicate.")
24
 
 
25
 
 
26
18
class MessageExchangeTest(LandscapeTest):
27
19
 
28
20
    helpers = [ExchangeHelper]
1005
997
            events.append(None)
1006
998
 
1007
999
        self.reactor.call_on("exchange-failed", failed_exchange)
1008
 
        self.exchanger._transport = RaisingTransport()
 
1000
        self.transport.responses.append(RuntimeError("Failed to communicate."))
1009
1001
        self.exchanger.exchange()
1010
1002
        self.assertEqual([None], events)
1011
1003
 
1012
 
    def test_error_exchanging_records_failure_in_message_store(self):
 
1004
    def test_wb_error_exchanging_records_failure_in_message_store(self):
1013
1005
        """
1014
1006
        If a traceback occurs whilst exchanging, the failure is recorded
1015
1007
        in the message store.
1016
1008
        """
1017
 
        mock_message_store = self.mocker.proxy(self.mstore)
1018
 
        mock_message_store.record_failure(MATCH(lambda x: type(x) is int))
1019
 
        self.mocker.result(None)
1020
 
        self.mocker.replay()
1021
 
 
1022
 
        exchanger = MessageExchange(
1023
 
            self.reactor, mock_message_store, RaisingTransport(),
1024
 
            self.identity, self.exchange_store, self.config)
1025
 
        exchanger.exchange()
 
1009
        self.reactor.advance(123)
 
1010
        self.transport.responses.append(RuntimeError("Failed to communicate."))
 
1011
        self.exchanger.exchange()
 
1012
        self.assertEqual(123, self.mstore._persist.get("first-failure-time"))
1026
1013
 
1027
1014
    def test_error_exchanging_marks_exchange_complete(self):
1028
1015
        """
1035
1022
            events.append(None)
1036
1023
 
1037
1024
        self.reactor.call_on("exchange-done", exchange_done)
1038
 
        self.exchanger._transport = RaisingTransport()
 
1025
        self.transport.responses.append(RuntimeError("Failed to communicate."))
1039
1026
        self.exchanger.exchange()
1040
1027
        self.assertEqual([None], events)
1041
1028
 
1043
1030
        """
1044
1031
        If a traceback occurs whilst exchanging, the failure is logged.
1045
1032
        """
1046
 
        self.exchanger._transport = RaisingTransport()
 
1033
        self.transport.responses.append(RuntimeError("Failed to communicate."))
1047
1034
        self.exchanger.exchange()
1048
1035
        self.assertIn("Message exchange failed.", self.logfile.getvalue())
1049
1036
 
 
1037
    def test_exchange_error_with_404_downgrades_server_api(self):
 
1038
        """
 
1039
        If we get a 404, we try to donwgrade our server API version.
 
1040
        """
 
1041
        self.mstore.set_server_api("3.3")
 
1042
        self.transport.responses.append(HTTPCodeError(404, ""))
 
1043
        self.exchanger.exchange()
 
1044
        self.assertEqual("3.2", self.mstore.get_server_api())
 
1045
 
1050
1046
 
1051
1047
class AcceptedTypesMessageExchangeTest(LandscapeTest):
1052
1048