예제 #1
0
class MgrSyncTest(unittest.TestCase):
    def setUp(self):
        self.mgr_sync = MgrSync()
        self.mgr_sync.conn = MagicMock()

        self.fake_auth_token = "fake_token"
        mock_connection = MagicMock()
        mock_auth = MagicMock()
        mock_connection.auth = mock_auth
        mock_auth.login = MagicMock(return_value=self.fake_auth_token)
        self.mgr_sync.auth.connection = mock_connection

        self.mgr_sync.config.write = MagicMock()
        self.mgr_sync.__init__logger = MagicMock(
            return_value=logger.Logger(3, "tmp.log"))
        self.mgr_sync.conn.sync.master.hasMaster = MagicMock(
            return_value=False)

    def tearDown(self):
        if os.path.exists("tmp.log"):
            os.unlink("tmp.log")

    def test_should_write_a_logfile(self):
        """Should write a logfile when debugging is enabled"""

        self.assertTrue(os.path.isfile("tmp.log"))

    def test_should_handle_max_number_of_authentication_failures(self):
        def raise_maximum_number_of_authentication_failures(options):
            raise MaximumNumberOfAuthenticationFailures

        self.mgr_sync._process_user_request = MagicMock()
        self.mgr_sync._process_user_request.side_effect = raise_maximum_number_of_authentication_failures

        options = get_options("list channels".split())
        with ConsoleRecorder() as recorder:
            self.assertEqual(1, self.mgr_sync.run(options))
        self.assertEqual(['mgr-sync: Authentication failure'], recorder.stderr)

    def test_should_always_write_the_session_token_to_the_local_configuration(
            self):
        self.mgr_sync.config.token = "old token"
        self.mgr_sync.auth.user = '******'
        self.mgr_sync.auth.password = '******'
        self.mgr_sync._execute_xmlrpc_method = MagicMock(return_value=[])

        options = get_options("list channels".split())
        with ConsoleRecorder():
            self.assertEqual(0, self.mgr_sync.run(options))
        self.assertEqual(self.fake_auth_token, self.mgr_sync.config.token)

        self.mgr_sync.config.write.assert_called_once_with()
예제 #2
0
class ProductOperationsTest(unittest.TestCase):
    def setUp(self):
        self.mgr_sync = MgrSync()
        self.mgr_sync.log = self.mgr_sync.__init__logger = MagicMock(
            return_value=logger.Logger(3, "tmp.log"))
        self.mgr_sync.conn = MagicMock()
        self.fake_auth_token = "fake_token"
        self.mgr_sync.auth.token = MagicMock(return_value=self.fake_auth_token)
        self.mgr_sync.config.write = MagicMock()
        self.mgr_sync.conn.sync.master.hasMaster = MagicMock(
            return_value=False)

    def tearDown(self):
        if os.path.exists("tmp.log"):
            os.unlink("tmp.log")

    def _mock_iterator(self):
        '''
        Mock *called* iterator.

        :return:
        '''
        mocked_iter = MagicMock()
        for dummy_element in mocked_iter():
            pass
        return mocked_iter.mock_calls[-1]

    def test_list_emtpy_product(self):
        options = get_options("list product".split())
        stubbed_xmlrpm_call = MagicMock(return_value=[])
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        self.assertEqual(recorder.stdout, ["No products found."])

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_product(self):
        options = get_options("list product".split())
        stubbed_xmlrpm_call = MagicMock(return_value=[])
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        self.assertEqual(recorder.stdout, ["No products found."])

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_expand_enabled(self):
        """ Test listing products with expand enabled """

        options = get_options("list product -e".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_products_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] RES 4 (x86_64)
[ ] RES 4 (x86_64)
[ ] RES 5 (x86_64)
[ ] RES 6 (x86_64)
[ ] SUSE Linux Enterprise Desktop 11 SP2 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP2 (x86_64)
[ ] SUSE Linux Enterprise Desktop 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP1 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP1 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP2 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP2 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP3 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 10 SP3 (x86_64)
[I] SUSE Linux Enterprise Server 10 SP4 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 10 SP4 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP1 (x86_64)
  [ ] Novell Open Enterprise Server 2 11 (x86_64)
  [ ] SUSE Linux Enterprise High Availability Extension 11 SP1 (x86_64)
  [ ] SUSE Linux Enterprise Point of Service 11 SP1 (x86_64)
  [ ] SUSE Linux Enterprise Real Time 11 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP1 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP2 (x86_64)
  [ ] Novell Open Enterprise Server 2 11.1 (x86_64)
  [ ] SUSE Cloud 1.0 (x86_64)
  [ ] SUSE Lifecycle Management Server 1.3 (x86_64)
  [ ] SUSE Linux Enterprise High Availability Extension 11 SP2 (x86_64)
  [ ] SUSE Linux Enterprise Real Time 11 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP2 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP2 (x86_64)
  [ ] SUSE WebYaST 1.3 (x86_64)
[I] SUSE Linux Enterprise Server 11 SP3 (x86_64)
  [ ] Novell Open Enterprise Server 2 11.2 (x86_64)
  [ ] SUSE Cloud 2.0 (x86_64)
  [ ] SUSE Cloud 3 (x86_64)
  [ ] SUSE Linux Enterprise High Availability Extension 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Point of Service 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Real Time 11 (x86_64)
  [I] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP3 (x86_64)
  [ ] SUSE WebYaST 1.3 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP3 VMWare (x86_64)
  [ ] SUSE Linux Enterprise High Availability Extension 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP3 (x86_64)
  [ ] SUSE WebYaST 1.3 (x86_64)
[ ] SUSE Manager Proxy 1.2 (x86_64)
[ ] SUSE Manager Proxy 1.7 (x86_64)
[ ] SUSE Manager Proxy 2.1 (x86_64)
[ ] SUSE Manager Server 2.1 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products(self):
        """ Test listing products """

        options = get_options("list product".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_products_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] RES 4 (x86_64)
[ ] RES 4 (x86_64)
[ ] RES 5 (x86_64)
[ ] RES 6 (x86_64)
[ ] SUSE Linux Enterprise Desktop 11 SP2 (x86_64)
[ ] SUSE Linux Enterprise Desktop 11 SP3 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP1 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP2 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP3 (x86_64)
[ ] SUSE Linux Enterprise Server 10 SP3 (x86_64)
[I] SUSE Linux Enterprise Server 10 SP4 (x86_64)
  [ ] SUSE Linux Enterprise Software Development Kit 10 SP4 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP1 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP2 (x86_64)
[I] SUSE Linux Enterprise Server 11 SP3 (x86_64)
  [ ] Novell Open Enterprise Server 2 11.2 (x86_64)
  [ ] SUSE Cloud 2.0 (x86_64)
  [ ] SUSE Cloud 3 (x86_64)
  [ ] SUSE Linux Enterprise High Availability Extension 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Point of Service 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Real Time 11 (x86_64)
  [I] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
  [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP3 (x86_64)
  [ ] SUSE WebYaST 1.3 (x86_64)
[ ] SUSE Linux Enterprise Server 11 SP3 VMWare (x86_64)
[ ] SUSE Manager Proxy 1.2 (x86_64)
[ ] SUSE Manager Proxy 1.7 (x86_64)
[ ] SUSE Manager Proxy 2.1 (x86_64)
[ ] SUSE Manager Server 2.1 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_filtering(self):
        """ Test listing products with filtering"""

        options = get_options("list product --filter proxy".split())
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture('list_products.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] SUSE Manager Proxy 1.2 (x86_64)
[ ] SUSE Manager Proxy 1.7 (x86_64)
[ ] SUSE Manager Proxy 2.1 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_filtering(self):
        """ Test listing products with filtering"""

        options = get_options("list product --filter proxy".split())
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture('list_products.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] SUSE Manager Proxy 1.2 (x86_64)
[ ] SUSE Manager Proxy 1.7 (x86_64)
[ ] SUSE Manager Proxy 2.1 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_filtering(self):
        """ Test listing products with filtering"""

        options = get_options("list product --filter proxy".split())
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture('list_products.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] SUSE Manager Proxy 1.2 (x86_64)
[ ] SUSE Manager Proxy 1.7 (x86_64)
[ ] SUSE Manager Proxy 2.1 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_filtering_matches_also_children(self):
        """ Test listing products with filtering should match children even when
        their parent does not.
        """

        options = get_options("list product --filter cloud".split())
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture('list_products.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

[ ] SUSE Linux Enterprise Server 11 SP2 (x86_64)
  [ ] SUSE Cloud 1.0 (x86_64)
[I] SUSE Linux Enterprise Server 11 SP3 (x86_64)
  [ ] SUSE Cloud 2.0 (x86_64)
  [ ] SUSE Cloud 3 (x86_64)"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listProducts",
            self.fake_auth_token)

    def test_list_products_with_interactive_mode_enabled(self):
        """ Test listing products """

        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_products_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync._list_products(filter=None,
                                         show_interactive_numbers=True)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] RES 4 (x86_64)
002) [ ] RES 4 (x86_64)
003) [ ] RES 5 (x86_64)
004) [ ] RES 6 (x86_64)
005) [ ] SUSE Linux Enterprise Desktop 11 SP2 (x86_64)
006) [ ] SUSE Linux Enterprise Desktop 11 SP3 (x86_64)
007) [ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP1 (x86_64)
008) [ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP2 (x86_64)
009) [ ] SUSE Linux Enterprise Server 10 SP1 SAP AiO 11 SP3 (x86_64)
010) [ ] SUSE Linux Enterprise Server 10 SP3 (x86_64)
     [I] SUSE Linux Enterprise Server 10 SP4 (x86_64)
011)   [ ] SUSE Linux Enterprise Software Development Kit 10 SP4 (x86_64)
012) [ ] SUSE Linux Enterprise Server 11 SP1 (x86_64)
013) [ ] SUSE Linux Enterprise Server 11 SP2 (x86_64)
     [I] SUSE Linux Enterprise Server 11 SP3 (x86_64)
014)   [ ] Novell Open Enterprise Server 2 11.2 (x86_64)
015)   [ ] SUSE Cloud 2.0 (x86_64)
016)   [ ] SUSE Cloud 3 (x86_64)
017)   [ ] SUSE Linux Enterprise High Availability Extension 11 SP3 (x86_64)
018)   [ ] SUSE Linux Enterprise Point of Service 11 SP3 (x86_64)
019)   [ ] SUSE Linux Enterprise Real Time 11 (x86_64)
       [I] SUSE Linux Enterprise Software Development Kit 11 SP3 (x86_64)
020)   [ ] SUSE Linux Enterprise Subscription Management Tool 11 SP3 (x86_64)
021)   [ ] SUSE WebYaST 1.3 (x86_64)
022) [ ] SUSE Linux Enterprise Server 11 SP3 VMWare (x86_64)
023) [ ] SUSE Manager Proxy 1.2 (x86_64)
024) [ ] SUSE Manager Proxy 1.7 (x86_64)
025) [ ] SUSE Manager Proxy 2.1 (x86_64)
026) [ ] SUSE Manager Server 2.1 (x86_64)"""

        self.assertEqual(recorder.stdout, expected_output.split("\n"))

    def test_add_products_interactive_with_mirror(self):
        """ Test adding a product with all the required channels available. """
        mirror_url = "http://smt.suse.de"
        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options(
            "add product --from-mirror {0}".format(mirror_url).split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_product_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] RES 4 (x86_64)
Adding channels required by 'RES 4' product
'res4-as-suse-manager-tools-x86_64' depends on channel 'rhel-x86_64-as-4' which has not been added yet
Going to add 'rhel-x86_64-as-4'
Added 'rhel-x86_64-as-4' channel
Scheduling reposync for following channels:
- rhel-x86_64-as-4
Added 'res4-as-suse-manager-tools-x86_64' channel
Added 'rhel-x86_64-as-4' channel
Added 'res4-as-x86_64' channel
Scheduling reposync for following channels:
- res4-as-suse-manager-tools-x86_64
- rhel-x86_64-as-4
- res4-as-x86_64
Product successfully added"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_xmlrpc_calls = []
        mandatory_channels = [
            c for c in chosen_product.channels if not c.optional
        ]
        for channel in mandatory_channels:
            expected_xmlrpc_calls.append(
                call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                            "addChannels",
                                            self.fake_auth_token,
                                            channel.label, mirror_url))
            expected_xmlrpc_calls.append(self._mock_iterator())
            expected_xmlrpc_calls.append(
                call._execute_xmlrpc_method(
                    self.mgr_sync.conn.channel.software, "syncRepo",
                    self.fake_auth_token, channel.label))

    def test_add_products_interactive(self):
        """ Test adding a product with all the required channels available. """

        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options("add product".split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_product_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] RES 4 (x86_64)
Adding channels required by 'RES 4' product
'res4-as-suse-manager-tools-x86_64' depends on channel 'rhel-x86_64-as-4' which has not been added yet
Going to add 'rhel-x86_64-as-4'
Added 'rhel-x86_64-as-4' channel
Scheduling reposync for following channels:
- rhel-x86_64-as-4
Added 'res4-as-suse-manager-tools-x86_64' channel
Added 'rhel-x86_64-as-4' channel
Added 'res4-as-x86_64' channel
Scheduling reposync for following channels:
- res4-as-suse-manager-tools-x86_64
- rhel-x86_64-as-4
- res4-as-x86_64
Product successfully added"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        mandatory_channels = [
            channel for channel in chosen_product.channels
            if not channel.optional
        ]
        expected_xmlrpc_calls = [
            call(self.mgr_sync.conn.sync.content, "listChannels",
                 self.fake_auth_token),
            call(self.mgr_sync.conn.sync.content, "listChannels",
                 self.fake_auth_token),
            call(self.mgr_sync.conn.sync.content, "addChannels",
                 self.fake_auth_token, 'rhel-x86_64-as-4', ''),
            call(self.mgr_sync.conn.channel.software, "syncRepo",
                 self.fake_auth_token, ['rhel-x86_64-as-4']),
            call(self.mgr_sync.conn.sync.content, "addChannels",
                 self.fake_auth_token, 'res4-as-suse-manager-tools-x86_64',
                 ''),
            call(self.mgr_sync.conn.sync.content, "addChannels",
                 self.fake_auth_token, 'rhel-x86_64-as-4', ''),
            call(self.mgr_sync.conn.sync.content, "addChannels",
                 self.fake_auth_token, 'res4-as-x86_64', ''),
        ]
        expected_xmlrpc_calls.append(
            call(self.mgr_sync.conn.channel.software, "syncRepo",
                 self.fake_auth_token,
                 [channel.label for channel in mandatory_channels]))
        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_channel_interactive_child_with_parent_already_added(self):
        """Tests that if the parent is added at the beggining, depending
        child channels do not try or display the adding of the parent"""

        products = read_data_from_fixture('list_products.data')
        sled = next(
            p for p in products
            if p['friendly_name'] == 'SUSE Linux Enterprise Desktop 11 SP3'
            and p['arch'] == 'x86_64')

        options = get_options("add product".split())
        available_products = parse_products([sled], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        # the installed status is verified against the remote fetched
        # channels
        self.mgr_sync._fetch_remote_channels = MagicMock(return_value=dict(
            (c.label, c) for c in chosen_product.channels))

        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] SUSE Linux Enterprise Desktop 11 SP3 (x86_64)
Adding channels required by 'SUSE Linux Enterprise Desktop 11 SP3' product
Added 'sled11-sp3-pool-x86_64' channel
Added 'sles11-sp3-suse-manager-tools-x86_64-sled-sp3' channel
Added 'sled11-sp3-updates-x86_64' channel
Scheduling reposync for following channels:
- sled11-sp3-pool-x86_64
- sles11-sp3-suse-manager-tools-x86_64-sled-sp3
- sled11-sp3-updates-x86_64
Product successfully added"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_xmlrpc_calls = []
        mandatory_channels = [
            c for c in chosen_product.channels if not c.optional
        ]
        for channel in mandatory_channels:
            expected_xmlrpc_calls.append(
                call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                            "addChannels",
                                            self.fake_auth_token,
                                            channel.label, ''))
        expected_xmlrpc_calls.append(
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [c.label for c in mandatory_channels]))

        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_add_products_interactive_with_a_channel_already_installed(self):
        """ Test adding a product with one of the required channels
        already installed """

        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options("add product".split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        # the installed status is verified against the remote fetched
        # channels
        self.mgr_sync._fetch_remote_channels = MagicMock(return_value=dict(
            (c.label, c) for c in chosen_product.channels))

        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_product_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        # set the base channel as already installed
        for channel in chosen_product.channels:
            if channel.label == 'rhel-x86_64-as-4':
                channel.status = Channel.Status.INSTALLED
                channel_to_not_add = channel
                break

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] RES 4 (x86_64)
Adding channels required by 'RES 4' product
Added 'res4-as-suse-manager-tools-x86_64' channel
Channel 'rhel-x86_64-as-4' has already been added
Added 'res4-as-x86_64' channel
Scheduling reposync for following channels:
- res4-as-suse-manager-tools-x86_64
- rhel-x86_64-as-4
- res4-as-x86_64
Product successfully added"""
        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_xmlrpc_calls = []
        mandatory_channels = [
            c for c in chosen_product.channels if not c.optional
        ]
        for channel in mandatory_channels:
            if channel is not channel_to_not_add:
                expected_xmlrpc_calls.append(
                    call._execute_xmlrpc_method(
                        self.mgr_sync.conn.sync.content, "addChannels",
                        self.fake_auth_token, channel.label, ''))
        expected_xmlrpc_calls.append(
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [c.label for c in mandatory_channels]))

        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_add_products_interactive_with_a_required_channel_unavailable(
            self):
        """ Test should not be able to select an unavailable product """

        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options("add product".split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        # set the 1st required channel as already installed
        chosen_product.status = Product.Status.UNAVAILABLE

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask'
                   ) as mock_cli_ask:
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))
            self.assertFalse(mock_cli_ask.mock_calls)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

     [U] RES 4 (x86_64)
All the available products have already been installed, nothing to do"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        self.assertFalse(stubbed_xmlrpm_call.mock_calls)

    def test_all_available_products_are_already_installed(self):
        """ Test all the available products are already installed"""

        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options("add product".split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        # set the product as already installed
        chosen_product.status = Product.Status.INSTALLED

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                try:
                    self.mgr_sync.run(options)
                except SystemExit as ex:
                    self.assertEqual(0, ex.code)

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

     [I] RES 4 (x86_64)
All the available products have already been installed, nothing to do"""
        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        self.assertFalse(stubbed_xmlrpm_call.mock_calls)

    def test_add_products_with_an_optional_channel_unavailable(self):
        """ Test adding a product with an optional channel unavailable. """

        products = read_data_from_fixture('list_products_simplified.data')
        res4 = next(p for p in products
                    if p['friendly_name'] == 'RES 4' and p['arch'] == 'x86_64')
        options = get_options("add product".split())
        available_products = parse_products([res4], self.mgr_sync.log)
        chosen_product = available_products[0]
        self.mgr_sync._fetch_remote_products = MagicMock(
            return_value=available_products)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_product_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        # set the 1st required channel as optional and unavailable
        chosen_product.channels[0].optional = True
        chosen_product.channels[0].status = Channel.Status.UNAVAILABLE
        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_products.index(chosen_product) + 1)
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        expected_output = """Available Products:

(R) - recommended extension

Status:
  - [I] - product is installed
  - [ ] - product is not installed, but is available
  - [U] - product is unavailable

001) [ ] RES 4 (x86_64)
Adding channels required by 'RES 4' product
Added 'rhel-x86_64-as-4' channel
Added 'res4-as-x86_64' channel
Scheduling reposync for following channels:
- rhel-x86_64-as-4
- res4-as-x86_64
Product successfully added"""
        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_xmlrpc_calls = [
            call(self.mgr_sync.conn.sync.content, "listChannels",
                 self.fake_auth_token)
        ]
        mandatory_channels = [
            channel for channel in chosen_product.channels
            if not channel.optional
        ]

        for channel in mandatory_channels:
            expected_xmlrpc_calls.append(
                call(self.mgr_sync.conn.sync.content, "addChannels",
                     self.fake_auth_token, channel.label, ''))

        expected_xmlrpc_calls.append(
            call(self.mgr_sync.conn.channel.software, "syncRepo",
                 self.fake_auth_token,
                 [channel.label for channel in mandatory_channels]))

        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)
예제 #3
0
class CredentialOperationsTest(unittest.TestCase):

    def setUp(self):
        self.mgr_sync = MgrSync()
        self.mgr_sync.conn = MagicMock()
        self.mgr_sync.log = self.mgr_sync.__init__logger = MagicMock(
            return_value=logger.Logger(3, "tmp.log"))
        self.fake_auth_token = "fake_token"
        self.mgr_sync.auth.token = MagicMock(
            return_value=self.fake_auth_token)
        self.mgr_sync.config.write = MagicMock()
        self.mgr_sync.conn.sync.master.hasMaster = MagicMock(return_value=False)

    def tearDown(self):
        if os.path.exists("tmp.log"):
            os.unlink("tmp.log")

    def test_list_credentials_no_credentials(self):
        """ Test listing credentials with none present """
        options = get_options("list credentials".split())
        stubbed_xmlrpm_call = MagicMock(return_value=[])
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        self.assertEqual(recorder.stdout, ["No credentials found"])

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "listCredentials",
            self.fake_auth_token)

    def test_list_credentials(self):
        """ Test listing credentials """
        options = get_options("list credentials".split())
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture(
                'list_credentials.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Credentials:
foo (primary)
bar"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "listCredentials",
            self.fake_auth_token)

    def test_list_credentials_interactive(self):
        """ Test listing credentials when interactive mode is set """
        stubbed_xmlrpm_call = MagicMock(
            return_value=read_data_from_fixture("list_credentials.data"))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        credentials = []

        with ConsoleRecorder() as recorder:
            credentials = self.mgr_sync._list_credentials(show_interactive_numbers=True)
        expected_output = """Credentials:
01) foo (primary)
02) bar"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "listCredentials",
            self.fake_auth_token)

    def test_add_credentials_interactive(self):
        """ Test adding credentials interactively """
        options = get_options("add credentials".split())
        self.mgr_sync._fetch_credentials = MagicMock(
            return_value=read_data_from_fixture("list_credentials.data"))

        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.side_effect = ["foobar", "foo", "foo"]
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "addCredentials",
            self.fake_auth_token,
            "foobar",
            "foo",
            False)

        self.assertEqual(recorder.stdout, ["Successfully added credentials."])

    def test_add_credentials_non_interactive(self):
        """ Test adding credentials non-interactively """
        options = get_options("add credentials foobar foo".split())
        self.mgr_sync._fetch_credentials = MagicMock(
            return_value=read_data_from_fixture("list_credentials.data"))

        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "addCredentials",
            self.fake_auth_token,
            "foobar",
            "foo",
            False)

    def test_delete_credentials_interactive(self):
        """ Test deleting credentials interactively """
        options = get_options("delete credentials".split())
        self.mgr_sync._fetch_credentials = MagicMock(
            return_value=read_data_from_fixture("list_credentials.data"))

        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.side_effect = ["1", "y"]
            with ConsoleRecorder() as recorder:
                self.assertEqual(0, self.mgr_sync.run(options))

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "deleteCredentials",
            self.fake_auth_token,
            "foo")

        self.assertEqual([recorder.stdout[-1]], ["Successfully deleted credentials: foo"])

    def test_delete_credentials_non_interactive(self):
        """ Test deleting credentials non-interactively """
        options = get_options("delete credentials foo".split())
        self.mgr_sync._fetch_credentials = MagicMock(
            return_value=read_data_from_fixture("list_credentials.data"))
        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content,
            "deleteCredentials",
            self.fake_auth_token,
            "foo")

        self.assertEqual(recorder.stdout, ["Successfully deleted credentials: foo"])
예제 #4
0
class ChannelOperationsTest(unittest.TestCase):
    def setUp(self):
        self.maxDiff = 100
        self.mgr_sync = MgrSync()
        self.mgr_sync.log = self.mgr_sync.__init__logger = MagicMock(
            return_value=logger.Logger(3, "tmp.log"))
        self.mgr_sync.conn = MagicMock()
        self.fake_auth_token = "fake_token"
        self.mgr_sync.auth.token = MagicMock(return_value=self.fake_auth_token)
        self.mgr_sync.config.write = MagicMock()
        self.mgr_sync.conn.sync.master.hasMaster = MagicMock(
            return_value=False)

    def tearDown(self):
        if os.path.exists("tmp.log"):
            os.unlink("tmp.log")

    def _mock_iterator(self):
        '''
        Mock *called* iterator.

        :return:
        '''
        mocked_iter = MagicMock()
        for dummy_element in mocked_iter():
            pass
        return mocked_iter.mock_calls[-1]

    def test_list_channels_no_channels(self):
        options = get_options("list channels".split())
        stubbed_xmlrpm_call = MagicMock(return_value=[])
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        self.assertEqual(recorder.stdout, ["No channels found."])

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels(self):
        """ Testing list channel output """
        options = get_options("list channel".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

[ ] RHEL i386 AS 4 RES 4 [rhel-i386-as-4]
[ ] RHEL x86_64 AS 4 RES 4 [rhel-x86_64-as-4]
[I] SLES10-SP4-Pool for x86_64 SUSE Linux Enterprise Server 10 SP4 x86_64 [sles10-sp4-pool-x86_64]
    [ ] SLE10-SDK-SP4-Pool for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-pool-x86_64]
    [I] SLE10-SDK-SP4-Updates for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-updates-x86_64]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels_compact_mode_enabled(self):
        """ Testing list channel output """
        options = get_options("list channel -c".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

[ ] rhel-i386-as-4
[ ] rhel-x86_64-as-4
[I] sles10-sp4-pool-x86_64
    [ ] sle10-sdk-sp4-pool-x86_64
    [I] sle10-sdk-sp4-updates-x86_64"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels_expand_enabled(self):
        """ Testing list channel output when expand option is toggled """
        options = get_options("list channel -e".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Available Channels (full):


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

[ ] RHEL i386 AS 4 RES 4 [rhel-i386-as-4]
    [ ] RES4 AS for i386 RES 4 [res4-as-i386]
[ ] RHEL x86_64 AS 4 RES 4 [rhel-x86_64-as-4]
    [ ] RES4 AS SUSE-Manager-Tools x86_64 SUSE-Manager-Tools [res4-as-suse-manager-tools-x86_64]
    [ ] RES4 AS for x86_64 RES 4 [res4-as-x86_64]
[I] SLES10-SP4-Pool for x86_64 SUSE Linux Enterprise Server 10 SP4 x86_64 [sles10-sp4-pool-x86_64]
    [ ] SLE10-SDK-SP4-Pool for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-pool-x86_64]
    [I] SLE10-SDK-SP4-Updates for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-updates-x86_64]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels_filter_set(self):
        """ Testing list channel output when a filter is set """
        options = get_options("list channel --filter rhel".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

[ ] RHEL i386 AS 4 RES 4 [rhel-i386-as-4]
[ ] RHEL x86_64 AS 4 RES 4 [rhel-x86_64-as-4]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels_filter_show_parent_when_child_matches(self):
        """ Testing list channel output when a filter is set.  Should show the
        parent even if it does not match the filter as long as one of his
        children match the filter.
        """

        options = get_options("list channel --filter update".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

[I] SLES10-SP4-Pool for x86_64 SUSE Linux Enterprise Server 10 SP4 x86_64 [sles10-sp4-pool-x86_64]
    [I] SLE10-SDK-SP4-Updates for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-updates-x86_64]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

    def test_list_channels_interactive(self):
        """ Test listing channels when interactive more is set """
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        available_channels = []
        with ConsoleRecorder() as recorder:
            available_channels = self.mgr_sync._list_channels(
                expand=False,
                filter=None,
                no_optionals=True,
                show_interactive_numbers=True,
                only_installed=False)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

  1) [ ] RHEL i386 AS 4 RES 4 [rhel-i386-as-4]
  2) [ ] RHEL x86_64 AS 4 RES 4 [rhel-x86_64-as-4]
     [I] SLES10-SP4-Pool for x86_64 SUSE Linux Enterprise Server 10 SP4 x86_64 [sles10-sp4-pool-x86_64]
      3) [ ] SLE10-SDK-SP4-Pool for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-pool-x86_64]
         [I] SLE10-SDK-SP4-Updates for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-updates-x86_64]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

        self.assertEqual([
            'rhel-i386-as-4', 'rhel-x86_64-as-4', 'sle10-sdk-sp4-pool-x86_64'
        ], available_channels)

    def test_list_installed_only_channels_interactive(self):
        """ Test listing channels when interactive more is set """
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        available_channels = []
        with ConsoleRecorder() as recorder:
            available_channels = self.mgr_sync._list_channels(
                expand=False,
                filter=None,
                no_optionals=True,
                show_interactive_numbers=True,
                only_installed=True)
        expected_output = """Available Channels:


Status:
  - [I] - channel is installed
  - [ ] - channel is not installed, but is available
  - [U] - channel is unavailable

  1) [I] SLES10-SP4-Pool for x86_64 SUSE Linux Enterprise Server 10 SP4 x86_64 [sles10-sp4-pool-x86_64]
      2) [I] SLE10-SDK-SP4-Updates for x86_64 SUSE Linux Enterprise Software Development Kit 10 SP4 Software Development Kit [sle10-sdk-sp4-updates-x86_64]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        stubbed_xmlrpm_call.assert_called_once_with(
            self.mgr_sync.conn.sync.content, "listChannels",
            self.fake_auth_token)

        self.assertEqual(
            ['sles10-sp4-pool-x86_64', 'sle10-sdk-sp4-updates-x86_64'],
            available_channels)

    def test_add_available_base_channel_with_mirror(self):
        """ Test adding an available base channel"""
        mirror_url = "http://smt.suse.de"
        channel = "rhel-i386-as-4"
        options = get_options("add channel {0} --from-mirror {1}".format(
            channel, mirror_url).split())

        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))

        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        expected_xmlrpc_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "addChannels", self.fake_auth_token,
                                        channel, mirror_url),
            self._mock_iterator(),
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [channel])
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

        expected_output = [
            "Adding '{0}' channel".format(channel),
            "Scheduling reposync for '{0}' channel".format(channel)
        ]

    def test_add_available_base_channel(self):
        """ Test adding an available base channel"""

        channel = "rhel-i386-as-4"
        options = get_options("add channel {0}".format(channel).split())

        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        expected_xmlrpc_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "addChannels", self.fake_auth_token,
                                        channel, ''),
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [channel])
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

        expected_output = [
            "Added '{0}' channel".format(channel),
            "Scheduling reposync for following channels:",
            "- {0}".format(channel)
        ]
        self.assertEqual(expected_output, recorder.stdout)

    def test_add_available_channel_with_available_base_channel(self):
        """ Test adding an available channel whose parent is available.

        Should add both of them."""

        base_channel = "rhel-i386-es-4"
        channel = "res4-es-i386"
        options = get_options("add channel {0}".format(channel).split())

        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))

        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))
        expected_xmlrpc_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "addChannels", self.fake_auth_token,
                                        base_channel, ''),
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [base_channel]),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "addChannels", self.fake_auth_token,
                                        channel, ''),
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [channel])
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

        expected_output = """'res4-es-i386' depends on channel 'rhel-i386-es-4' which has not been added yet
Going to add 'rhel-i386-es-4'
Added 'rhel-i386-es-4' channel
Scheduling reposync for following channels:
- rhel-i386-es-4
Added 'res4-es-i386' channel
Scheduling reposync for following channels:
- res4-es-i386"""
        self.assertEqual(expected_output.split("\n"), recorder.stdout)

    def test_add_already_installed_channel(self):
        """Test adding an already added channel.

        Should only trigger the reposync for the channel"""

        channel = "sles11-sp3-pool-x86_64"
        options = get_options("add channel {0}".format(channel).split())

        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))

        stubbed_xmlrpm_call = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        expected_xmlrpc_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.channel.software,
                                        "syncRepo", self.fake_auth_token,
                                        [channel])
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

        expected_output = [
            "Channel '{0}' has already been added".format(channel),
            "Scheduling reposync for following channels:",
            "- {0}".format(channel)
        ]
        self.assertEqual(expected_output, recorder.stdout)

    def test_add_unavailable_base_channel(self):
        """Test adding an unavailable base channel

        Should refuse to perform the operation, print to stderr and exit with
        an error code"""

        options = get_options(
            "add channel sles11-sp3-vmware-pool-i586".split())
        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))

        with ConsoleRecorder() as recorder:
            self.assertEqual(1, self.mgr_sync.run(options))

        self.assertEqual([
            "Channel 'sles11-sp3-vmware-pool-i586' is not available, skipping"
        ], recorder.stdout)

    def test_add_unavailable_child_channel(self):
        """Test adding an unavailable child channel

        Should refuse to perform the operation, print to stderr and exit with
        an error code"""

        options = get_options("add channel sle10-sdk-sp4-pool-x86_64".split())
        self.mgr_sync._fetch_remote_channels = MagicMock(
            return_value=parse_channels(
                read_data_from_fixture("list_channels.data"),
                self.mgr_sync.log))

        with ConsoleRecorder() as recorder:
            self.assertEqual(1, self.mgr_sync.run(options))

        self.assertEqual(
            ["Channel 'sle10-sdk-sp4-pool-x86_64' is not available, skipping"],
            recorder.stdout)

    def test_add_available_child_channel_with_unavailable_parent(self):
        """Test adding an available child channel which has an unavailable parent.

        Should refuse to perform the operation, print to stderr and exit with
        an error code.
        This should never occur.
        """

        channels = parse_channels(read_data_from_fixture("list_channels.data"),
                                  self.mgr_sync.log)
        parent = channels['rhel-i386-es-4']
        parent.status = Channel.Status.UNAVAILABLE
        child = 'res4-es-i386'

        options = get_options("add channel {0}".format(child).split())
        self.mgr_sync._fetch_remote_channels = MagicMock(return_value=channels)

        with ConsoleRecorder() as recorder:
            self.assertEqual(1, self.mgr_sync.run(options))
        expected_output = """Error, 'res4-es-i386' depends on channel 'rhel-i386-es-4' which is not available
'res4-es-i386' has not been added"""

        self.assertFalse(recorder.stdout)
        self.assertEqual(expected_output.split("\n"), recorder.stderr)

    def test_add_channels_interactive(self):
        options = get_options("add channel".split())
        available_channels = ['ch1', 'ch2']
        chosen_channel = available_channels[0]
        self.mgr_sync._list_channels = MagicMock(
            return_value=available_channels)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_channels.index(chosen_channel) + 1)
            with ConsoleRecorder() as recorder:
                self.mgr_sync.run(options)

            expected_output = [
                "Added '{0}' channel".format(chosen_channel),
                "Scheduling reposync for following channels:",
                "- {0}".format(chosen_channel)
            ]
            self.assertEqual(expected_output, recorder.stdout)

            self.mgr_sync._list_channels.assert_called_once_with(
                expand=False,
                filter=None,
                no_optionals=False,
                show_interactive_numbers=True,
                compact=False,
                only_installed=False)

            expected_xmlrpc_calls = [
                call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                            "addChannels",
                                            self.fake_auth_token,
                                            chosen_channel, ''),
                call._execute_xmlrpc_method(
                    self.mgr_sync.conn.channel.software, "syncRepo",
                    self.fake_auth_token, [chosen_channel])
            ]

            stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_add_channels_interactive_no_optional(self):
        options = get_options("add channel --no-optional".split())
        available_channels = ['ch1', 'ch2']
        chosen_channel = available_channels[0]
        self.mgr_sync._list_channels = MagicMock(
            return_value=available_channels)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_channels.index(chosen_channel) + 1)
            with ConsoleRecorder() as recorder:
                self.mgr_sync.run(options)

            expected_output = [
                "Added '{0}' channel".format(chosen_channel),
                "Scheduling reposync for following channels:",
                "- {0}".format(chosen_channel)
            ]
            self.assertEqual(expected_output, recorder.stdout)

            self.mgr_sync._list_channels.assert_called_once_with(
                expand=False,
                filter=None,
                no_optionals=True,
                show_interactive_numbers=True,
                compact=False,
                only_installed=False)

            expected_xmlrpc_calls = [
                call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                            "addChannels",
                                            self.fake_auth_token,
                                            chosen_channel, ''),
                call._execute_xmlrpc_method(
                    self.mgr_sync.conn.channel.software, "syncRepo",
                    self.fake_auth_token, [chosen_channel])
            ]

            stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_add_channels_interactive_no_sync(self):
        options = get_options("add channel --no-sync".split())
        available_channels = ['ch1', 'ch2']
        chosen_channel = available_channels[0]
        self.mgr_sync._list_channels = MagicMock(
            return_value=available_channels)
        stubbed_xmlrpm_call = MagicMock()
        stubbed_xmlrpm_call.side_effect = xmlrpc_sideeffect
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_channels.index(chosen_channel) + 1)
            with ConsoleRecorder() as recorder:
                self.mgr_sync.run(options)

            expected_output = ["Added '{0}' channel".format(chosen_channel)]
            self.assertEqual(expected_output, recorder.stdout)

            self.mgr_sync._list_channels.assert_called_once_with(
                expand=False,
                filter=None,
                no_optionals=False,
                show_interactive_numbers=True,
                compact=False,
                only_installed=False)

            expected_xmlrpc_calls = [
                call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                            "addChannels",
                                            self.fake_auth_token,
                                            chosen_channel, '')
            ]

            stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_sync_channels_interactive(self):
        options = get_options("sync channels ".split())
        available_channels = [
            'sles10-sp4-pool-x86_64', 'sle10-sdk-sp4-updates-x86_64'
        ]
        chosen_channel = available_channels[0]
        self.mgr_sync._list_channels = MagicMock(
            return_value=available_channels)
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_channels.index(chosen_channel) + 1)
            with ConsoleRecorder() as recorder:
                self.mgr_sync.run(options)

            expected_output = [
                "Scheduling reposync for following channels:",
                "- {0}".format(chosen_channel)
            ]
            self.assertEqual(expected_output, recorder.stdout)

            self.mgr_sync._list_channels.assert_called_once_with(
                expand=False,
                filter=None,
                no_optionals=False,
                show_interactive_numbers=True,
                compact=False,
                only_installed=True)

            expected_xmlrpc_calls = [
                call._execute_xmlrpc_method(
                    self.mgr_sync.conn.channel.software, "syncRepo",
                    self.fake_auth_token, [chosen_channel])
            ]

            stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)

    def test_sync_channels_interactive_with_children(self):
        options = get_options("sync channels --with-children".split())
        available_channels = [
            'sles10-sp4-pool-x86_64', 'sle10-sdk-sp4-updates-x86_64'
        ]
        chosen_channel = available_channels[0]
        self.mgr_sync._list_channels = MagicMock(
            return_value=available_channels)
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call

        with patch('spacewalk.susemanager.mgr_sync.mgr_sync.cli_ask') as mock:
            mock.return_value = str(
                available_channels.index(chosen_channel) + 1)
            with ConsoleRecorder() as recorder:
                self.mgr_sync.run(options)

            expected_output = [
                "Scheduling reposync for following channels:",
                "- sles10-sp4-pool-x86_64",
                "- sle10-sdk-sp4-updates-x86_64",
            ]
            self.assertEqual(expected_output, recorder.stdout)

            self.mgr_sync._list_channels.assert_called_once_with(
                expand=False,
                filter=None,
                no_optionals=False,
                show_interactive_numbers=True,
                compact=False,
                only_installed=True)

            expected_xmlrpc_calls = [
                call._execute_xmlrpc_method(
                    self.mgr_sync.conn.channel.software, "syncRepo",
                    self.fake_auth_token,
                    ["sles10-sp4-pool-x86_64", "sle10-sdk-sp4-updates-x86_64"])
            ]

            stubbed_xmlrpm_call.assert_has_calls(expected_xmlrpc_calls)
예제 #5
0
class RefreshOperationsTest(unittest.TestCase):
    def setUp(self):
        self.mgr_sync = MgrSync()
        self.mgr_sync.conn = MagicMock()
        self.fake_auth_token = "fake_token"
        self.mgr_sync.auth.token = MagicMock(return_value=self.fake_auth_token)
        self.mgr_sync.config.write = MagicMock()
        self.mgr_sync.conn.sync.master.hasMaster = MagicMock(
            return_value=False)

    def test_refresh_from_mirror(self):
        """ Test the refresh action """
        mirror_url = "http://smt.suse.de"
        options = get_options(
            "refresh --from-mirror {0}".format(mirror_url).split())
        stubbed_xmlrpm_call = MagicMock(return_value=True)
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        stubbed_reposync = MagicMock()
        self.mgr_sync._schedule_channel_reposync = stubbed_reposync
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Refreshing Channels                            [DONE]
Refreshing Channel families                    [DONE]
Refreshing SUSE products                       [DONE]
Refreshing SUSE Product channels               [DONE]
Refreshing Subscriptions                       [DONE]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannels",
                                        self.fake_auth_token, mirror_url),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannelFamilies",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProducts",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProductChannels",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeSubscriptions",
                                        self.fake_auth_token)
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_calls)
        self.assertFalse(stubbed_reposync.mock_calls)

    def test_refresh(self):
        """ Test the refresh action """

        options = get_options("refresh".split())
        stubbed_xmlrpm_call = MagicMock(return_value=True)
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        stubbed_reposync = MagicMock()
        self.mgr_sync._schedule_channel_reposync = stubbed_reposync
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Refreshing Channels                            [DONE]
Refreshing Channel families                    [DONE]
Refreshing SUSE products                       [DONE]
Refreshing SUSE Product channels               [DONE]
Refreshing Subscriptions                       [DONE]"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannels",
                                        self.fake_auth_token, ''),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannelFamilies",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProducts",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProductChannels",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeSubscriptions",
                                        self.fake_auth_token)
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_calls)
        self.assertFalse(stubbed_reposync.mock_calls)

    def test_refresh_enable_reposync(self):
        """ Test the refresh action """

        options = get_options("refresh --refresh-channels".split())
        stubbed_xmlrpm_call = MagicMock(return_value=read_data_from_fixture(
            'list_channels_simplified.data'))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        with ConsoleRecorder() as recorder:
            self.mgr_sync.run(options)

        expected_output = """Refreshing Channels                            [DONE]
Refreshing Channel families                    [DONE]
Refreshing SUSE products                       [DONE]
Refreshing SUSE Product channels               [DONE]
Refreshing Subscriptions                       [DONE]

Scheduling refresh of all the available channels
Scheduling reposync for following channels:
- sles10-sp4-pool-x86_64
- sle10-sdk-sp4-updates-x86_64"""

        self.assertEqual(expected_output.split("\n"), recorder.stdout)

        expected_calls = [
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannels",
                                        self.fake_auth_token, ''),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeChannelFamilies",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProducts",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeProductChannels",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "synchronizeSubscriptions",
                                        self.fake_auth_token),
            call._execute_xmlrpc_method(self.mgr_sync.conn.sync.content,
                                        "listChannels", self.fake_auth_token),
            call._execute_xmlrpc_method(
                self.mgr_sync.conn.channel.software, "syncRepo",
                self.fake_auth_token,
                ["sles10-sp4-pool-x86_64", "sle10-sdk-sp4-updates-x86_64"]),
        ]
        stubbed_xmlrpm_call.assert_has_calls(expected_calls)

    def test_refresh_never_ask_credentials_when_schedule_option_is_set(self):
        """ Refresh with the 'schedule' option should just schedule the
            operation. User credentials must not be asked.
        """

        options = get_options("refresh --schedule".split())
        mock_execute_xmlrpc = MagicMock()
        self.mgr_sync._execute_xmlrpc_method = mock_execute_xmlrpc
        mock_reposync = MagicMock()
        self.mgr_sync._schedule_channel_reposync = mock_reposync
        mock_schedule_taskomatic_refresh = MagicMock()
        self.mgr_sync._schedule_taskomatic_refresh = mock_schedule_taskomatic_refresh

        with ConsoleRecorder() as recorder:
            self.assertEqual(0, self.mgr_sync.run(options))

        self.assertEqual(['Refresh successfully scheduled'], recorder.stdout)

        self.assertTrue(mock_schedule_taskomatic_refresh.mock_calls)
        self.assertFalse(mock_execute_xmlrpc.mock_calls)
        self.assertFalse(mock_reposync.mock_calls)

    def test_refresh_should_not_trigger_reposync_when_there_is_an_error(self):
        """ The refresh action should not trigger a reposync when something
            went wrong during one of the refresh steps.
        """

        options = get_options("refresh --refresh-channels".split())
        stubbed_xmlrpm_call = MagicMock(side_effect=Exception("Boom baby!"))
        self.mgr_sync._execute_xmlrpc_method = stubbed_xmlrpm_call
        mock_reposync = MagicMock()
        self.mgr_sync._schedule_channel_reposync = mock_reposync

        with ConsoleRecorder() as recorder:
            self.assertEqual(1, self.mgr_sync.run(options))

        self.assertTrue(recorder.stderr)
        self.assertFalse(mock_reposync.mock_calls)