def build_widget(self, **kwargs):

        def remove_p(charm_class):
            n = self.pc.assignment_machine_count_for_charm(charm_class)
            return n > 0

        def not_conflicted_p(cc):
            state, _, _ = self.pc.get_charm_state(cc)
            return state != CharmState.CONFLICTED

        actions = [(remove_p, 'Remove', self.do_remove),
                   (not_conflicted_p, 'Add', self.do_add)]
        self.unrequired_undeployed_sl = ServicesList(self.pc,
                                                     actions, actions,
                                                     ignore_deployed=True,
                                                     title="Un-Deployed")
        self.deployed_sl = ServicesList(self.pc,
                                        actions, actions,
                                        deployed_only=True,
                                        show_placements=True,
                                        title="Deployed Services")

        self.assigned_sl = ServicesList(self.pc,
                                        actions, actions,
                                        assigned_only=True,
                                        show_placements=True,
                                        title="Services to be Deployed")

        self.buttons = []
        self.button_grid = GridFlow(self.buttons, 22, 1, 1, 'center')
        self.pile1 = Pile([self.button_grid, self.assigned_sl,
                           self.unrequired_undeployed_sl])
        self.pile2 = Pile([self.deployed_sl])
        return LineBox(Columns([self.pile1, self.pile2]),
                       title="Add Services")
예제 #2
0
    def build_widgets(self):
        self.deploy_view = DeployView(self.display_controller,
                                      self.placement_controller,
                                      self.placement_view)

        def not_conflicted_p(cc):
            state, _, _ = self.placement_controller.get_charm_state(cc)
            return state != CharmState.CONFLICTED

        actions = [(not_conflicted_p, "Choose Machine",
                    self.placement_view.do_show_machine_chooser)]
        subordinate_actions = [(not_conflicted_p, "Add",
                                self.do_place_subordinate)]
        self.required_services_list = ServicesList(self.placement_controller,
                                                   actions,
                                                   subordinate_actions,
                                                   ignore_assigned=True,
                                                   ignore_deployed=True,
                                                   show_type='required',
                                                   show_constraints=True,
                                                   title="Required Services")
        self.additional_services_list = ServicesList(self.placement_controller,
                                                     actions,
                                                     subordinate_actions,
                                                     show_type='non-required',
                                                     show_constraints=True,
                                                     title="Additional "
                                                     "Services")

        autoplace_func = self.placement_view.do_autoplace
        self.autoplace_button = AttrMap(
            Button("Auto-place Remaining Services", on_press=autoplace_func),
            'button_secondary', 'button_secondary focus')

        clear_all_func = self.placement_view.do_clear_all
        self.clear_all_button = AttrMap(
            Button("Clear all Placements", on_press=clear_all_func),
            'button_secondary', 'button_secondary focus')

        self.required_services_pile = Pile(
            [self.required_services_list,
             Divider()])
        self.additional_services_pile = Pile(
            [self.additional_services_list,
             Divider()])

        self.top_buttons = []
        self.top_button_grid = GridFlow(self.top_buttons, 36, 1, 0, 'center')

        pl = [
            Text(('subheading', "Services"), align='center'),
            Divider(), self.top_button_grid,
            Divider(), self.deploy_view,
            Divider(), self.required_services_pile,
            Divider(), self.additional_services_pile
        ]

        self.main_pile = Pile(pl)

        return self.main_pile
예제 #3
0
 def test_machine_checks_constraints(self, mock_servicewidgetclass):
     mock_machine = make_fake_machine('fm', {'cpu_count': 0,
                                             'storage': 0,
                                             'memory': 0})
     sl = ServicesList(self.pc, self.actions, self.sub_actions,
                       machine=mock_machine)
     self.assertEqual(len(sl.service_widgets), 0)
예제 #4
0
    def build_widgets(self):

        instructions = Text("Remove services from {}".format(
            self.machine.hostname))

        self.machine_widget = MachineWidget(self.machine,
                                            self.controller,
                                            show_hardware=True)

        def show_remove_p(cc):
            md = self.controller.get_assignments(cc)
            for atype, ms in md.items():
                hostnames = [m.hostname for m in ms]
                if self.machine.hostname in hostnames:
                    return True
            return False

        actions = [(show_remove_p, 'Remove', self.do_remove)]

        self.services_list = ServicesList(self.controller,
                                          actions,
                                          actions,
                                          machine=self.machine)

        close_button = AttrMap(Button('X', on_press=self.close_pressed),
                               'button_secondary', 'button_secondary focus')
        p = Pile([
            GridFlow([close_button], 5, 1, 0, 'right'), instructions,
            Divider(), self.machine_widget,
            Divider(), self.services_list
        ])

        return LineBox(p, title="Remove Services")
예제 #5
0
 def test_no_machine_no_constraints(self, mock_servicewidgetclass):
     with patch.object(self.pc, 'charm_classes') as mock_classesfunc:
         fc = MagicMock(name='fakeclass1')
         fc.required_num_units.return_value = 1
         fc.constraints = {'cpu_count': 1000}
         mock_classesfunc.return_value = [fc]
         sl = ServicesList(self.pc, self.actions, self.sub_actions)
         self.assertEqual(len(sl.service_widgets), 1)
예제 #6
0
 def test_do_not_show_assigned(self, mock_servicewidgetclass):
     mock_machine = make_fake_machine('fm', {'cpu_count': 0,
                                             'storage': 0,
                                             'memory': 0})
     self.pc.assign(mock_machine, CharmNovaCompute,
                    AssignmentType.LXC)
     sl = ServicesList(self.pc, self.actions, self.sub_actions,
                       machine=mock_machine)
     classes = [sw.charm_class for sw in sl.service_widgets]
     self.assertTrue(CharmNovaCompute not in classes)
예제 #7
0
 def test_widgets_config(self, mock_servicewidgetclass):
     for show_constraints in [False, True]:
         sl = ServicesList(self.pc, self.actions, self.sub_actions,
                           show_constraints=show_constraints)
         mock_servicewidgetclass.assert_any_call(
             CharmNovaCompute,
             self.pc,
             self.actions,
             show_constraints,
             show_placements=sl.show_placements)
         mock_servicewidgetclass.reset_mock()
예제 #8
0
    def test_show_type(self, mock_servicewidgetclass):
        """Test combinations of show_type values.

        This tests three values of show_type with three return values
        for is_required(): all required, no required, and 1/3
        required. It's all lumped in one test to consolidate setup.

        """
        mock_sw1 = MagicMock(name='sw1')
        mock_sw1.charm_class.charm_name = 'cc1'
        mock_sw2 = MagicMock(name='sw2')
        mock_sw2.charm_class.charm_name = 'cc2'
        mock_sw3 = MagicMock(name='sw3')
        mock_sw3.charm_class.charm_name = 'cc3'
        mock_servicewidgetclass.side_effect = [mock_sw1, mock_sw2, mock_sw3]

        with patch.object(self.pc, 'get_charm_state') as mock_get_state:
            with patch.object(self.pc, 'charm_classes') as mock_classesfunc:
                mock_classesfunc.return_value = [
                    MagicMock(name='fake-class-1', charm_name='cc1'),
                    MagicMock(name='fake-class-2', charm_name='cc2'),
                    MagicMock(name='fake-class-3', charm_name='cc3')
                ]

                # First, test when all charms are required
                mock_get_state.return_value = (CharmState.REQUIRED, [], [])

                # rsl shows required charms
                rsl = ServicesList(self.pc,
                                   self.actions,
                                   self.sub_actions,
                                   machine=None,
                                   show_type='required')
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show all 3
                self.assertEqual(len(rsl.service_widgets), 3)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                # usl shows ONLY un-required charms
                usl = ServicesList(self.pc,
                                   self.actions,
                                   self.sub_actions,
                                   machine=None,
                                   show_type='non-required')
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show 0
                self.assertEqual(len(usl.service_widgets), 0)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                # asl has default show_type='all', showing all charms
                asl = ServicesList(self.pc, self.actions, self.sub_actions)
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show all 3
                self.assertEqual(len(asl.service_widgets), 3)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                # next, test where no charms are required
                mock_get_state.return_value = (CharmState.OPTIONAL, [], [])
                rsl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show 0 charms
                self.assertEqual(len(rsl.service_widgets), 0)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                usl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show all 3
                self.assertEqual(len(usl.service_widgets), 3)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                asl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should still show all 3
                self.assertEqual(len(asl.service_widgets), 3)
                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]

                # next test two un-required and one required charm:
                mock_get_state.side_effect = [(CharmState.OPTIONAL, [], []),
                                              (CharmState.REQUIRED, [], []),
                                              (CharmState.OPTIONAL, [], [])]
                rsl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show 1:
                self.assertEqual(len(rsl.service_widgets), 1)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]
                mock_get_state.side_effect = [(CharmState.OPTIONAL, [], []),
                                              (CharmState.REQUIRED, [], []),
                                              (CharmState.OPTIONAL, [], [])]

                usl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should show two
                self.assertEqual(len(usl.service_widgets), 2)

                mock_get_state.reset_mock()
                mock_servicewidgetclass.reset_mock()
                mock_servicewidgetclass.side_effect = [
                    mock_sw1, mock_sw2, mock_sw3
                ]
                mock_get_state.side_effect = [(CharmState.OPTIONAL, [], []),
                                              (CharmState.REQUIRED, [], []),
                                              (CharmState.OPTIONAL, [], [])]

                asl.update()
                self.assertEqual(len(mock_get_state.mock_calls), 3)
                # should still show all three
                self.assertEqual(len(asl.service_widgets), 3)