Пример #1
0
 def test_draining_server_can_be_deleted_if_all_lbs_can_be_removed(self):
     """
     If draining server can be removed from all the load balancers, the
     server can be deleted.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0),
             set([server('abc', state=ServerState.ACTIVE,
                         metadata=dict([DRAINING_METADATA]),
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
             set([CLBNode(node_id='1', address='1.1.1.1',
                          description=copy_clb_desc(
                              self.clb_desc,
                              condition=CLBNodeCondition.DRAINING)),
                  RCv3Node(node_id='2', cloud_server_id='abc',
                           description=self.rcv3_desc)]),
             0),
         pbag([
             DeleteServer(server_id='abc'),
             RemoveNodesFromCLB(lb_id='1', node_ids=s('1')),
             BulkRemoveFromRCv3(lb_node_pairs=s(
                 (self.rcv3_desc.lb_id, 'abc')))
         ]))
Пример #2
0
 def test_clean_up_deleted_servers_with_lb_nodes(self):
     """
     If a server has been deleted, we want to remove any dangling LB nodes
     referencing the server.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0),
             set([server('abc', ServerState.DELETED,
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(CLBDescription(lb_id='5', port=80),
                                       CLBDescription(lb_id='5', port=8080),
                                       RCv3Description(lb_id='6')))]),
             set([CLBNode(address='1.1.1.1', node_id='3',
                          description=CLBDescription(lb_id='5',
                                                     port=80)),
                  CLBNode(address='1.1.1.1', node_id='5',
                          description=CLBDescription(lb_id='5',
                                                     port=8080)),
                  RCv3Node(node_id='123', cloud_server_id='abc',
                           description=RCv3Description(lb_id='6'))]),
             0),
         pbag([
             RemoveNodesFromCLB(lb_id='5', node_ids=s('3')),
             RemoveNodesFromCLB(lb_id='5', node_ids=s('5')),
             BulkRemoveFromRCv3(lb_node_pairs=s(('6', 'abc'))),
         ]))
Пример #3
0
    def test_plan(self):
        """An optimized plan is returned. Steps are limited."""
        desc = CLBDescription(lb_id='5', port=80)
        desired_lbs = s(desc)
        desired_group_state = DesiredGroupState(
            server_config={}, capacity=20, desired_lbs=desired_lbs)

        result = plan(
            desired_group_state,
            set([server('server1', state=ServerState.ACTIVE,
                        servicenet_address='1.1.1.1',
                        desired_lbs=desired_lbs),
                 server('server2', state=ServerState.ACTIVE,
                        servicenet_address='1.2.3.4',
                        desired_lbs=desired_lbs)]),
            set(),
            0,
            build_timeout=3600)

        self.assertEqual(
            result,
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1', desc), ('1.2.3.4', desc))
                )] + [CreateServer(server_config=pmap({}))] * 10))
Пример #4
0
 def test_delete_error_state_servers_with_lb_nodes(self):
     """
     If a server we created enters error state and it is attached to one
     or more load balancers, it will be removed from its load balancers
     as well as get deleted.  (Tests that error state servers are not
     excluded from converging load balancer state.)
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=1),
             set([server('abc', ServerState.ERROR,
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(CLBDescription(lb_id='5', port=80),
                                       CLBDescription(lb_id='5', port=8080),
                                       RCv3Description(lb_id='6')))]),
             set([CLBNode(address='1.1.1.1', node_id='3',
                          description=CLBDescription(lb_id='5',
                                                     port=80)),
                  CLBNode(address='1.1.1.1', node_id='5',
                          description=CLBDescription(lb_id='5',
                                                     port=8080)),
                  RCv3Node(node_id='123', cloud_server_id='abc',
                           description=RCv3Description(lb_id='6'))]),
             0),
         pbag([
             DeleteServer(server_id='abc'),
             RemoveNodesFromCLB(lb_id='5', node_ids=s('3')),
             RemoveNodesFromCLB(lb_id='5', node_ids=s('5')),
             BulkRemoveFromRCv3(lb_node_pairs=s(('6', 'abc'))),
             CreateServer(server_config=pmap()),
         ]))
Пример #5
0
    def test_same_clb_multiple_ports(self):
        """
        It's possible to have the same cloud load balancer using multiple ports
        on the host.

        (use case: running multiple single-threaded server processes on a
        machine)
        """
        desired = s(CLBDescription(lb_id='5', port=8080),
                    CLBDescription(lb_id='5', port=8081))
        current = []
        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=1),
                set([server('abc', ServerState.ACTIVE,
                            servicenet_address='1.1.1.1',
                            desired_lbs=desired)]),
                set(current),
                0),
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1',
                                       CLBDescription(lb_id='5', port=8080)))),
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1',
                                       CLBDescription(lb_id='5', port=8081))))
                ]))
Пример #6
0
 def test_converge_active_servers_ignores_servers_to_be_deleted(self):
     """
     Only servers in active that are not being deleted will have their
     load balancers converged.
     """
     desc = CLBDescription(lb_id='5', port=80)
     desired_lbs = s(desc)
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=1,
                               desired_lbs=desired_lbs),
             set([server('abc', ServerState.ACTIVE,
                         servicenet_address='1.1.1.1', created=0,
                         desired_lbs=desired_lbs),
                  server('bcd', ServerState.ACTIVE,
                         servicenet_address='2.2.2.2', created=1,
                         desired_lbs=desired_lbs)]),
             set(),
             0),
         pbag([
             DeleteServer(server_id='abc'),
             AddNodesToCLB(
                 lb_id='5',
                 address_configs=s(('2.2.2.2', desc)))
         ]))
Пример #7
0
 def test_active_server_is_drained_if_not_all_lbs_can_be_removed(self):
     """
     If an active server to be deleted cannot be removed from all the load
     balancers, it is set to draining state and all the nodes are set to
     draining condition.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0,
                               draining_timeout=10.0),
             set([server('abc', state=ServerState.ACTIVE,
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
             set([CLBNode(node_id='1', address='1.1.1.1',
                          description=self.clb_desc),
                  RCv3Node(node_id='2', cloud_server_id='abc',
                           description=self.rcv3_desc)]),
             0),
         pbag([
             ChangeCLBNode(lb_id='1', node_id='1', weight=1,
                           condition=CLBNodeCondition.DRAINING,
                           type=CLBNodeType.PRIMARY),
             SetMetadataItemOnServer(server_id='abc',
                                     key=DRAINING_METADATA[0],
                                     value=DRAINING_METADATA[1]),
             BulkRemoveFromRCv3(lb_node_pairs=s(
                 (self.rcv3_desc.lb_id, 'abc')))
         ]))
Пример #8
0
 def __init__(
     self,
     attrs: Optional[Iterable[Attr]] = None,
     props: Optional[Iterable[Prop]] = None,
 ):
     self.attrs = s() if attrs is None else PSet(attrs)
     self.props = s() if props is None else PSet(props)
Пример #9
0
 def test_filters_clb_types(self):
     """
     Only one CLB step is returned per CLB
     """
     steps = pbag([
         AddNodesToCLB(
             lb_id='5',
             address_configs=s(('1.1.1.1',
                                CLBDescription(lb_id='5', port=80)))),
         RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
         # Unoptimizable step
         CreateServer(server_config=pmap({})),
     ])
     # returned steps could be pbag of any of the 2 lists below depending
     # on how `one_clb_step` iterates over the steps. Since it is pbag the
     # order of elements is not guaranteed
     list1 = [
         AddNodesToCLB(
             lb_id='5',
             address_configs=s(
                 ('1.1.1.1', CLBDescription(lb_id='5', port=80)))),
         CreateServer(server_config=pmap({}))
     ]
     list2 = [
         RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
         CreateServer(server_config=pmap({}))
     ]
     self.assertEqual(
         matches(MatchesAny(Equals(pbag(list1)), Equals(pbag(list2)))),
         optimize_steps(steps)
     )
Пример #10
0
 def test_filters_clb_types(self):
     """
     Only one CLB step is returned per CLB
     """
     steps = pbag([
         AddNodesToCLB(lb_id='5',
                       address_configs=s(
                           ('1.1.1.1', CLBDescription(lb_id='5',
                                                      port=80)))),
         RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
         # Unoptimizable step
         CreateServer(server_config=pmap({})),
     ])
     # returned steps could be pbag of any of the 2 lists below depending
     # on how `one_clb_step` iterates over the steps. Since it is pbag the
     # order of elements is not guaranteed
     list1 = [
         AddNodesToCLB(lb_id='5',
                       address_configs=s(
                           ('1.1.1.1', CLBDescription(lb_id='5',
                                                      port=80)))),
         CreateServer(server_config=pmap({}))
     ]
     list2 = [
         RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
         CreateServer(server_config=pmap({}))
     ]
     self.assertEqual(
         matches(MatchesAny(Equals(pbag(list1)), Equals(pbag(list2)))),
         optimize_steps(steps))
Пример #11
0
    def test_optimize_clb_adds_maintain_unique_ports(self):
        """
        Multiple ports can be specified for the same address and LB ID when
        adding to a CLB.
        """
        steps = pbag([
            AddNodesToCLB(
                lb_id='5',
                address_configs=s(('1.1.1.1',
                                   CLBDescription(lb_id='5', port=80)))),
            AddNodesToCLB(
                lb_id='5',
                address_configs=s(('1.1.1.1',
                                   CLBDescription(lb_id='5', port=8080))))])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(
                        ('1.1.1.1',
                         CLBDescription(lb_id='5', port=80)),
                        ('1.1.1.1',
                         CLBDescription(lb_id='5', port=8080))))]))
Пример #12
0
 def __init__(self,
              contents=None,
              relationships=None,
              relationship_registry=None):
     self.contents = contents or s()
     self.relationships = relationships or s()
     self.relationship_registry = relationship_registry
Пример #13
0
    def test_optimize_clb_adds_maintain_unique_ports(self):
        """
        Multiple ports can be specified for the same address and LB ID when
        adding to a CLB.
        """
        steps = pbag([
            AddNodesToCLB(lb_id='5',
                          address_configs=s(
                              ('1.1.1.1', CLBDescription(lb_id='5',
                                                         port=80)))),
            AddNodesToCLB(lb_id='5',
                          address_configs=s(
                              ('1.1.1.1', CLBDescription(lb_id='5',
                                                         port=8080))))
        ])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(
                        ('1.1.1.1', CLBDescription(lb_id='5', port=80)),
                        ('1.1.1.1', CLBDescription(lb_id='5', port=8080))))
            ]))
Пример #14
0
    def test_add_to_lb(self):
        """
        If a desired LB config is not in the set of current configs,
        `converge_lb_state` returns the relevant adding-to-load-balancer
        steps (:class:`AddNodesToCLB` in the case of CLB,
        :class:`BulkAddToRCv3` in the case of RCv3).
        """
        clb_desc = CLBDescription(lb_id='5', port=80)
        rcv3_desc = RCv3Description(
            lb_id='c6fe49fa-114a-4ea4-9425-0af8b30ff1e7')

        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=1),
                set([server('abc', ServerState.ACTIVE,
                            servicenet_address='1.1.1.1',
                            desired_lbs=s(clb_desc, rcv3_desc))]),
                set(),
                0),
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1', clb_desc))),
                BulkAddToRCv3(
                    lb_node_pairs=s(
                        ('c6fe49fa-114a-4ea4-9425-0af8b30ff1e7', 'abc')))
            ]))
Пример #15
0
def test_evolver_simple_remove():
    x = s(1, 2, 3)
    e = x.evolver()
    e.remove(2)

    x2 = e.persistent()
    assert x2 == s(1, 3)
    assert x == s(1, 2, 3)
Пример #16
0
def test_evolver_simple_remove():
    x = s(1, 2, 3)
    e = x.evolver()
    e.remove(2)

    x2 = e.persistent()
    assert x2 == s(1, 3)
    assert x == s(1, 2, 3)
Пример #17
0
    def make_border(
        points: np.ndarray, edges: Complex
    ) -> Tuple[np.ndarray, Complex, Complex, PSet[Cycle], PSet[Cycle]]:
        def first_index(array: np.ndarray, value: np.ndarray) -> float:
            return next(i for i, _ in enumerate(array)
                        if np.linalg.norm(value - _) < EPSILON)

        first_index_points = partial(first_index, points)

        corners = v(v(-0.5, 0.5), v(-0.5, -0.5), v(0.5, -0.5), v(0.5, 0.5))

        ul, dl, dr, ur = pipe(corners, map(np.array), map(first_index_points))

        max_ind = len(points)

        cul = max_ind
        cdl = max_ind + 1
        cdr = max_ind + 2
        cur = max_ind + 3

        left_c = v(ul, cul, cdl, dl)
        right_c = v(dr, cdr, cur, ur)
        down_c = v(dl, cdl, cdr, dr)
        up_c = v(ur, cur, cul, ul)

        red_base_cs = s(left_c, right_c)
        blue_base_cs = s(up_c, down_c)

        def border_edges(pts: np.ndarray, es: Complex, coord: int,
                         side: float) -> Complex:
            return pset(edge for edge in es if all(
                np.linalg.norm(pts[vert][coord] - side) < EPSILON
                for vert in edge))

        border_edges_from_square_side = partial(border_edges, points, edges)

        left_faces = faces_from_edges(
            border_edges_from_square_side(0, -0.5)
            | outer_edges_from_cycle(left_c))
        right_faces = faces_from_edges(
            border_edges_from_square_side(0, 0.5)
            | outer_edges_from_cycle(right_c))
        down_faces = faces_from_edges(
            border_edges_from_square_side(1, -0.5)
            | outer_edges_from_cycle(down_c))
        up_faces = faces_from_edges(
            border_edges_from_square_side(1, 0.5)
            | outer_edges_from_cycle(up_c))

        red_base = closure(left_faces | right_faces)
        blue_base = closure(down_faces | up_faces)

        border_points = np.array(corners) * BORDER_SCALE
        aug_points = np.concatenate((points, border_points))

        return aug_points, blue_base, red_base, blue_base_cs, red_base_cs
Пример #18
0
def test_evolver_simple_add():
    x = s(1, 2, 3)
    e = x.evolver()
    assert not e.is_dirty()

    e.add(4)
    assert e.is_dirty()

    x2 = e.persistent()
    assert not e.is_dirty()
    assert x2 == s(1, 2, 3, 4)
    assert x == s(1, 2, 3)
Пример #19
0
def test_evolver_simple_add():
    x = s(1, 2, 3)
    e = x.evolver()
    assert not e.is_dirty()

    e.add(4)
    assert e.is_dirty()

    x2 = e.persistent()
    assert not e.is_dirty()
    assert x2 == s(1, 2, 3, 4)
    assert x == s(1, 2, 3)
Пример #20
0
    def test_all_clb_changes_together(self):
        """
        Given all possible combination of clb load balancer states and
        timeouts, ensure function produces the right set of step for all of
        them.
        """
        clb_descs = [CLBDescription(lb_id='1', port=80),
                     CLBDescription(lb_id='2', port=80),
                     CLBDescription(lb_id='3', port=80),
                     CLBDescription(lb_id='4', port=80),
                     CLBDescription(lb_id='5', port=80)]

        clb_nodes = [
            # enabled, should be drained
            CLBNode(node_id='1', address=self.address,
                    description=clb_descs[0]),
            # disabled, should be removed
            CLBNode(node_id='2', address=self.address,
                    description=copy_clb_desc(
                        clb_descs[1], condition=CLBNodeCondition.DISABLED)),
            # draining, still connections, should be ignored
            CLBNode(node_id='3', address='1.1.1.1',
                    description=copy_clb_desc(
                        clb_descs[2], condition=CLBNodeCondition.DRAINING),
                    connections=3, drained_at=5.0),
            # draining, no connections, should be removed
            CLBNode(node_id='4', address='1.1.1.1',
                    description=copy_clb_desc(
                        clb_descs[3], condition=CLBNodeCondition.DRAINING),
                    connections=0, drained_at=5.0),
            # draining, timeout exired, should be removed
            CLBNode(node_id='5', address='1.1.1.1',
                    description=copy_clb_desc(
                        clb_descs[4], condition=CLBNodeCondition.DRAINING),
                    connections=10, drained_at=0.0)]

        clb_steps = [
            ChangeCLBNode(lb_id='1', node_id='1', weight=1,
                          condition=CLBNodeCondition.DRAINING,
                          type=CLBNodeType.PRIMARY),
            RemoveNodesFromCLB(lb_id='2', node_ids=s('2')),
            RemoveNodesFromCLB(lb_id='4', node_ids=s('4')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('5')),
        ]

        self.assert_converge_clb_steps(
            clb_descs=clb_descs,
            clb_nodes=clb_nodes,
            clb_steps=clb_steps,
            draining_timeout=10.0,
            now=10)
Пример #21
0
def test_supports_set_comparisons():
    s1 = s(1, 2, 3)
    s3 = s(1, 2)
    s4 = s(1, 2, 3)

    assert s(1, 2, 3, 3, 5) == s(1, 2, 3, 5)
    assert s1 != s3

    assert s3 < s1
    assert s3 <= s1
    assert s3 <= s4

    assert s1 > s3
    assert s1 >= s3
    assert s4 >= s3
Пример #22
0
def test_supports_set_operations():
    s1 = pset([1, 2, 3])
    s2 = pset([3, 4, 5])

    assert s1 | s2 == s(1, 2, 3, 4, 5)
    assert s1.union(s2) == s1 | s2

    assert s1 & s2 == s(3)
    assert s1.intersection(s2) == s1 & s2

    assert s1 - s2 == s(1, 2)
    assert s1.difference(s2) == s1 - s2

    assert s1 ^ s2 == s(1, 2, 4, 5)
    assert s1.symmetric_difference(s2) == s1 ^ s2
Пример #23
0
def test_supports_set_operations():
    s1 = pset([1, 2, 3])
    s2 = pset([3, 4, 5])

    assert s1 | s2 == s(1, 2, 3, 4, 5)
    assert s1.union(s2) == s1 | s2

    assert s1 & s2 == s(3)
    assert s1.intersection(s2) == s1 & s2

    assert s1 - s2 == s(1, 2)
    assert s1.difference(s2) == s1 - s2

    assert s1 ^ s2 == s(1, 2, 4, 5)
    assert s1.symmetric_difference(s2) == s1 ^ s2
Пример #24
0
def test_supports_set_comparisons():
    s1 = s(1, 2, 3)
    s3 = s(1, 2)
    s4 = s(1, 2, 3)

    assert s(1, 2, 3, 3, 5) == s(1, 2, 3, 5)
    assert s1 != s3

    assert s3 < s1
    assert s3 <= s1
    assert s3 <= s4

    assert s1 > s3
    assert s1 >= s3
    assert s4 >= s3
Пример #25
0
 def setUp(self):
     self.tenant_id = 'tenant-id'
     self.group_id = 'group-id'
     self.state = GroupState(self.tenant_id, self.group_id, 'group-name',
                             {}, {}, None, {}, False,
                             ScalingGroupStatus.ACTIVE, desired=2)
     self.group = mock_group(self.state, self.tenant_id, self.group_id)
     self.lc = {'args': {'server': {'name': 'foo'}, 'loadBalancers': []}}
     self.desired_lbs = s(CLBDescription(lb_id='23', port=80))
     self.servers = (
         server('a', ServerState.ACTIVE, servicenet_address='10.0.0.1',
                desired_lbs=self.desired_lbs,
                links=freeze([{'href': 'link1', 'rel': 'self'}])),
         server('b', ServerState.ACTIVE, servicenet_address='10.0.0.2',
                desired_lbs=self.desired_lbs,
                links=freeze([{'href': 'link2', 'rel': 'self'}]))
     )
     self.state_active = {}
     self.cache = [thaw(self.servers[0].json), thaw(self.servers[1].json)]
     self.gsgi = GetScalingGroupInfo(tenant_id='tenant-id',
                                     group_id='group-id')
     self.manifest = {  # Many details elided!
         'state': self.state,
         'launchConfiguration': self.lc,
     }
     self.gsgi_result = (self.group, self.manifest)
     self.now = datetime(1970, 1, 1)
Пример #26
0
def hello():

    number_nodes = int(request.args.get('nodes', 6))

    identity = uuid.uuid1().hex
    point_map = graphs.generate_point_map(number_nodes)
    edges = graphs.no_interesctions(point_map)
    domain = s('red', 'green', 'blue', 'purple')
    nodes = [
        Node(id=ix, point=y, color=None, domain=domain)
        for ix, y in point_map.items()
    ]

    problem = Graph(edges=edges,
                    nodes=dict([(node.id, node) for node in nodes]))
    solver = BacktrackSolver()
    solution = solver.external_backtrack(problem)

    solutions[identity] = solution
    return render_template("hello.html.j2",
                           identity=identity,
                           runtime=solver.runtime,
                           backtrack_calls=solver.backtrack_calls,
                           constraint_tests=solver.constraint_tests,
                           failed_node_choice=solver.failed_node_choice)
Пример #27
0
class Piece(object):
    """
    A piece that moves to explicit static squares.
    """

    black_character = u" "
    white_character = u" "

    _capturable = attr.ib(default=s())
    _reachable = attr.ib(default=s())

    def capturable_from(self, square):
        return self._capturable

    def reachable_from(self, square):
        return self._reachable
Пример #28
0
 def composition(self, relation):
     new_relation = s()
     for i in self.relation:
         for j in relation:
             if i[1] == j[0]:
                 new_relation = new_relation.add((i[0], j[1]))
     return Relation(self.set, new_relation)
Пример #29
0
    def test_change_lb_node(self):
        """
        If a desired CLB mapping is in the set of current configs,
        but the configuration is wrong, `converge_lb_state` returns a
        :class:`ChangeCLBNode` object.  RCv3 nodes cannot be changed - they are
        either right or wrong.
        """
        clb_desc = CLBDescription(lb_id='5', port=80)
        rcv3_desc = RCv3Description(
            lb_id='c6fe49fa-114a-4ea4-9425-0af8b30ff1e7')

        current = [CLBNode(node_id='123', address='1.1.1.1',
                           description=copy_clb_desc(clb_desc, weight=5)),
                   RCv3Node(node_id='234', cloud_server_id='abc',
                            description=rcv3_desc)]
        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=1),
                set([server('abc', ServerState.ACTIVE,
                            servicenet_address='1.1.1.1',
                            desired_lbs=s(clb_desc, rcv3_desc))]),
                set(current),
                0),
            pbag([
                ChangeCLBNode(lb_id='5', node_id='123', weight=1,
                              condition=CLBNodeCondition.ENABLED,
                              type=CLBNodeType.PRIMARY)]))
Пример #30
0
 def _build(thing, on_route=pyrsistent.s()):
     if thing in on_route:
         raise ValueError("circular dependency detected", thing,
                          on_route)
     if thing in ret:
         return ret[thing]
     on_route = on_route.add(thing)
     plugin = collection[thing]
     func = plugin.original
     dependencies, possible_dependencies, regular = plugin.extra
     my_dependencies, my_possible_dependencies = {}, {}
     for other_thing in dependencies:
         my_dependencies[other_thing] = _build(other_thing, on_route)
     for other_thing in possible_dependencies:
         builder = functools.partial(_build, other_thing, on_route)
         my_possible_dependencies[other_thing] = builder
     if regular:
         args = {
             'build_' + key: value
             for key, value in my_possible_dependencies.items()
         }
         args.update(my_dependencies)
         ret[thing] = func(**args)
     else:
         ret[thing] = func(my_dependencies, my_possible_dependencies)
     return ret[thing]
Пример #31
0
    def test_draining_server_has_all_enabled_lb_set_to_draining(self):
        """
        If a draining server is associated with any load balancers, those
        load balancer nodes will be set to draining and the server is not
        deleted.  The metadata on the server is not re-set to draining.

        This can happen for instance if the server was supposed to be deleted
        in a previous convergence run, and the server metadata was set but
        the load balancers update failed.

        Or if the server is set to be manually deleted via the API.
        """
        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=0,
                                  draining_timeout=10.0),
                set([server('abc', state=ServerState.ACTIVE,
                            metadata=dict([DRAINING_METADATA]),
                            servicenet_address='1.1.1.1',
                            desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
                set([CLBNode(node_id='1', address='1.1.1.1',
                             description=self.clb_desc)]),
                1),
            pbag([
                ChangeCLBNode(lb_id='1', node_id='1', weight=1,
                              condition=CLBNodeCondition.DRAINING,
                              type=CLBNodeType.PRIMARY)
            ]))
Пример #32
0
    def test_active_server_is_drained_even_if_all_already_in_draining(self):
        """
        If an active server is attached to load balancers, and all those load
        balancer nodes are already in draining but it cannot be removed yet,
        the server is set to draining state even though no load balancer
        actions need to be performed.

        This can happen for instance if the server was supposed to be deleted
        in a previous convergence run, and the load balancers were set to
        draining but setting the server metadata failed.
        """
        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=0,
                                  draining_timeout=10.0),
                set([server('abc', state=ServerState.ACTIVE,
                            servicenet_address='1.1.1.1',
                            desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
                set([CLBNode(node_id='1', address='1.1.1.1',
                             description=copy_clb_desc(
                                 self.clb_desc,
                                 condition=CLBNodeCondition.DRAINING),
                             connections=1, drained_at=0.0)]),
                1),
            pbag([
                SetMetadataItemOnServer(server_id='abc',
                                        key=DRAINING_METADATA[0],
                                        value=DRAINING_METADATA[1]),
                self.clstep
            ]))
Пример #33
0
    def test_optimize_clb_removes(self):
        """
        Aggregation is done on a per-load-balancer basis when remove nodes from
        a CLB.
        """
        steps = pbag([
            RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('2')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('3')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('4'))])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                RemoveNodesFromCLB(lb_id='5', node_ids=s('1', '2', '3', '4'))
            ]))
Пример #34
0
 def test_multiple_lb_pending(self):
     """
     When a server needs to be added to multiple LBs, it's only counted
     once.
     """
     lb_nodes = [
         CLBNode(node_id='1',
                 description=CLBDescription(lb_id='foo', port=1),
                 address='1.1.1.1'),
         CLBNode(node_id='2',
                 description=CLBDescription(lb_id='foo', port=2),
                 address='1.1.1.1'),
         CLBNode(node_id='3',
                 description=CLBDescription(lb_id='bar', port=3),
                 address='1.1.1.1'),
         CLBNode(node_id='4',
                 description=CLBDescription(lb_id='bar', port=4),
                 address='1.1.1.1'),
     ]
     desired_lbs = s(CLBDescription(lb_id='foo', port=1),
                     CLBDescription(lb_id='foo', port=2),
                     CLBDescription(lb_id='bar', port=3),
                     CLBDescription(lb_id='bar', port=4))
     self.assertEqual(
         is_autoscale_active(
             server('id1', ServerState.ACTIVE, servicenet_address='1.1.1.1',
                    desired_lbs=desired_lbs),
             lb_nodes),
         True)
Пример #35
0
    def test_mixed_optimization(self):
        """
        Mixes of optimizable and unoptimizable steps still get optimized
        correctly.
        """
        steps = pbag([
            # CLB adds
            AddNodesToCLB(
                lb_id='5',
                address_configs=s(('1.1.1.1',
                                   CLBDescription(lb_id='5', port=80)))),
            AddNodesToCLB(
                lb_id='5',
                address_configs=s(('1.1.1.2',
                                   CLBDescription(lb_id='5', port=80)))),
            AddNodesToCLB(
                lb_id='6',
                address_configs=s(('1.1.1.1',
                                   CLBDescription(lb_id='6', port=80)))),
            AddNodesToCLB(
                lb_id='6',
                address_configs=s(('1.1.1.2',
                                   CLBDescription(lb_id='6', port=80)))),
            RemoveNodesFromCLB(lb_id='7', node_ids=s('1')),
            RemoveNodesFromCLB(lb_id='7', node_ids=s('2')),

            # Unoptimizable steps
            CreateServer(server_config=pmap({})),
        ])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                # Optimized CLB adds
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1',
                                       CLBDescription(lb_id='5', port=80)),
                                      ('1.1.1.2',
                                       CLBDescription(lb_id='5', port=80)))),
                AddNodesToCLB(
                    lb_id='6',
                    address_configs=s(('1.1.1.1',
                                       CLBDescription(lb_id='6', port=80)),
                                      ('1.1.1.2',
                                       CLBDescription(lb_id='6', port=80)))),
                RemoveNodesFromCLB(lb_id='7', node_ids=s('1', '2')),

                # Unoptimizable steps
                CreateServer(server_config=pmap({}))
            ]))
Пример #36
0
    def test_optimize_clb_removes(self):
        """
        Aggregation is done on a per-load-balancer basis when remove nodes from
        a CLB.
        """
        steps = pbag([
            RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('2')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('3')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('4'))
        ])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                RemoveNodesFromCLB(lb_id='5', node_ids=s('1', '2', '3', '4'))
            ]))
Пример #37
0
 def test_optimize_leaves_other_steps(self):
     """
     Unoptimizable steps pass the optimizer unchanged.
     """
     steps = pbag([
         AddNodesToCLB(lb_id='5',
                       address_configs=s(
                           ('1.1.1.1', CLBDescription(lb_id='5',
                                                      port=80)))),
         RemoveNodesFromCLB(lb_id='6', node_ids=s('1')),
         CreateServer(server_config=pmap({})),
         BulkRemoveFromRCv3(lb_node_pairs=pset([("lb-1", "node-a")])),
         BulkAddToRCv3(lb_node_pairs=pset([("lb-2", "node-b")]))
         # Note that the add & remove pair should not be the same;
         # the optimizer might reasonably optimize opposite
         # operations away in the future.
     ])
     self.assertEqual(optimize_steps(steps), steps)
Пример #38
0
    def test_mixed_optimization(self):
        """
        Mixes of optimizable and unoptimizable steps still get optimized
        correctly.
        """
        steps = pbag([
            # CLB adds
            AddNodesToCLB(lb_id='5',
                          address_configs=s(
                              ('1.1.1.1', CLBDescription(lb_id='5',
                                                         port=80)))),
            AddNodesToCLB(lb_id='5',
                          address_configs=s(
                              ('1.1.1.2', CLBDescription(lb_id='5',
                                                         port=80)))),
            AddNodesToCLB(lb_id='6',
                          address_configs=s(
                              ('1.1.1.1', CLBDescription(lb_id='6',
                                                         port=80)))),
            AddNodesToCLB(lb_id='6',
                          address_configs=s(
                              ('1.1.1.2', CLBDescription(lb_id='6',
                                                         port=80)))),
            RemoveNodesFromCLB(lb_id='7', node_ids=s('1')),
            RemoveNodesFromCLB(lb_id='7', node_ids=s('2')),

            # Unoptimizable steps
            CreateServer(server_config=pmap({})),
        ])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                # Optimized CLB adds
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(
                        ('1.1.1.1', CLBDescription(lb_id='5', port=80)),
                        ('1.1.1.2', CLBDescription(lb_id='5', port=80)))),
                AddNodesToCLB(
                    lb_id='6',
                    address_configs=s(
                        ('1.1.1.1', CLBDescription(lb_id='6', port=80)),
                        ('1.1.1.2', CLBDescription(lb_id='6', port=80)))),
                RemoveNodesFromCLB(lb_id='7', node_ids=s('1', '2')),

                # Unoptimizable steps
                CreateServer(server_config=pmap({}))
            ]))
Пример #39
0
def test_identify_with_non_alphanumeric_tag_status_uid():
    uid = 'UID %-'
    tag = 'a tag #0'
    status = 'a status #0'

    m0 = messages.BusMessage(tag=tag, status=status, payload=0, seeds=m())
    m1 = m0.identify(uid)

    seeds_c = freeze({tag: s(uid)})
    mc = messages.BusMessage(tag=tag, status=status, payload=0, seeds=seeds_c)
    assert (m1 == mc)
Пример #40
0
def add_edges(point_map):
    """Simple edge creation that adds edges only between a point and its nearest
    neighbor"""
    edges = []
    for anchor in point_map.keys():
        distances = [(search, distance(point_map[anchor], point_map[search]))
                     for search in set(point_map.keys()).difference({anchor})]

        min_distance = min(distances, key=lambda y: y[1])
        edges.append(s(anchor, min_distance[0]))
    return pset(edges)
Пример #41
0
def add_edges(point_map):
    """Simple edge creation that adds edges only between a point and its nearest
    neighbor"""
    edges = []
    for anchor in point_map.keys():
        distances = [(search, distance(point_map[anchor], point_map[search]))
                     for search in set(point_map.keys()).difference({anchor})]

        min_distance = min(distances, key=lambda y: y[1])
        edges.append(s(anchor, min_distance[0]))
    return pset(edges)
Пример #42
0
 def test_optimize_leaves_other_steps(self):
     """
     Unoptimizable steps pass the optimizer unchanged.
     """
     steps = pbag([
         AddNodesToCLB(
             lb_id='5',
             address_configs=s(('1.1.1.1',
                                CLBDescription(lb_id='5', port=80)))),
         RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
         CreateServer(server_config=pmap({})),
         BulkRemoveFromRCv3(lb_node_pairs=pset([("lb-1", "node-a")])),
         BulkAddToRCv3(lb_node_pairs=pset([("lb-2", "node-b")]))
         # Note that the add & remove pair should not be the same;
         # the optimizer might reasonably optimize opposite
         # operations away in the future.
     ])
     self.assertEqual(
         optimize_steps(steps),
         steps)
Пример #43
0
    def test_all_changes(self):
        """
        Remove, change, and add a node to a load balancer all together
        """
        descs = [CLBDescription(lb_id='5', port=80),
                 CLBDescription(lb_id='6', port=80, weight=2),
                 RCv3Description(lb_id='c6fe49fa-114a-4ea4-9425-0af8b30ff1e7')]

        current = [
            CLBNode(node_id='123', address='1.1.1.1',
                    description=CLBDescription(lb_id='5', port=8080)),
            CLBNode(node_id='234', address='1.1.1.1',
                    description=copy_clb_desc(descs[1], weight=1)),
            RCv3Node(node_id='345', cloud_server_id='abc',
                     description=RCv3Description(
                         lb_id='e762e42a-8a4e-4ffb-be17-f9dc672729b2'))
        ]

        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=1),
                set([server('abc', ServerState.ACTIVE,
                            servicenet_address='1.1.1.1',
                            desired_lbs=pset(descs))]),
                set(current),
                0),
            pbag([
                AddNodesToCLB(
                    lb_id='5',
                    address_configs=s(('1.1.1.1',
                                       CLBDescription(lb_id='5', port=80)))),
                ChangeCLBNode(lb_id='6', node_id='234', weight=2,
                              condition=CLBNodeCondition.ENABLED,
                              type=CLBNodeType.PRIMARY),
                RemoveNodesFromCLB(lb_id='5', node_ids=s('123')),
                BulkAddToRCv3(lb_node_pairs=s(
                    ('c6fe49fa-114a-4ea4-9425-0af8b30ff1e7', 'abc'))),
                BulkRemoveFromRCv3(lb_node_pairs=s(
                    ('e762e42a-8a4e-4ffb-be17-f9dc672729b2', 'abc')))
            ]))
Пример #44
0
    def test_draining_server_waiting_for_timeout_some_lbs_removed(self):
        """
        Load balancers that can be removed are removed, even if the server is
        already in draining state is waiting for the draining timeout on some
        load balancers.
        """
        other_clb_desc = CLBDescription(lb_id='9', port=80)

        self.assertEqual(
            converge(
                DesiredGroupState(server_config={}, capacity=0,
                                  draining_timeout=2.0),
                set([server('abc', state=ServerState.ACTIVE,
                            metadata=dict([DRAINING_METADATA]),
                            servicenet_address='1.1.1.1',
                            desired_lbs=s(self.clb_desc, self.rcv3_desc,
                                          other_clb_desc))]),
                set([
                    # This node is in draining - nothing will be done to it
                    CLBNode(node_id='1', address='1.1.1.1',
                            description=copy_clb_desc(
                                self.clb_desc,
                                condition=CLBNodeCondition.DRAINING),
                            drained_at=1.0, connections=1),
                    # This node is done draining, it can be removed
                    CLBNode(node_id='2', address='1.1.1.1',
                            description=copy_clb_desc(
                                other_clb_desc,
                                condition=CLBNodeCondition.DRAINING),
                            drained_at=0.0),
                    # This node is not drainable, it can be removed
                    RCv3Node(node_id='3', cloud_server_id='abc',
                             description=self.rcv3_desc)]),
                2),
            pbag([
                RemoveNodesFromCLB(lb_id='9', node_ids=s('2')),
                BulkRemoveFromRCv3(lb_node_pairs=s(
                    (self.rcv3_desc.lb_id, 'abc'))),
                self.clstep
            ]))
Пример #45
0
    def perimeter_positions(self, game: Game):
        all_positions_set = pset(
            game.black_positions.union(game.white_positions))
        all_positions = plist(all_positions_set)

        horizon = s()
        while len(all_positions) > 0:
            head = all_positions.first
            all_positions = all_positions.rest
            neighbors = self.get_neighbors(head)
            horizon = horizon.union(neighbors)

        return horizon.difference(all_positions_set)
Пример #46
0
    def initial_game(self) -> Game:
        lower = int(self.board_size / 2) - 1
        upper = int(self.board_size / 2)

        black_positions = s(
            Position(x_position=lower,
                     y_position=lower,
                     board_size=self.board_size),
            Position(x_position=upper,
                     y_position=upper,
                     board_size=self.board_size))

        white_positions = s(
            Position(x_position=lower,
                     y_position=upper,
                     board_size=self.board_size),
            Position(x_position=upper,
                     y_position=lower,
                     board_size=self.board_size))

        return Game(black_positions=black_positions,
                    white_positions=white_positions)
Пример #47
0
 def test_active_server_can_be_deleted_if_all_lbs_can_be_removed(self):
     """
     If an active server to be scaled down can be removed from all the load
     balancers, the server can be deleted.  It is not first put into
     draining state.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0),
             set([server('abc', state=ServerState.ACTIVE,
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
             set([CLBNode(node_id='1', address='1.1.1.1',
                          description=self.clb_desc),
                  RCv3Node(node_id='2', cloud_server_id='abc',
                           description=self.rcv3_desc)]),
             0),
         pbag([
             DeleteServer(server_id='abc'),
             RemoveNodesFromCLB(lb_id='1', node_ids=s('1')),
             BulkRemoveFromRCv3(lb_node_pairs=s(
                 (self.rcv3_desc.lb_id, 'abc')))
         ]))
Пример #48
0
 def test_optimize_clb_adds(self):
     """
     Multiple :class:`AddNodesToCLB` steps for the same LB
     are merged into one.
     """
     steps = pbag([
         AddNodesToCLB(
             lb_id='5',
             address_configs=s(('1.1.1.1',
                                CLBDescription(lb_id='5', port=80)))),
         AddNodesToCLB(
             lb_id='5',
             address_configs=s(('1.2.3.4',
                                CLBDescription(lb_id='5', port=80))))])
     self.assertEqual(
         optimize_steps(steps),
         pbag([
             AddNodesToCLB(
                 lb_id='5',
                 address_configs=s(
                     ('1.1.1.1', CLBDescription(lb_id='5', port=80)),
                     ('1.2.3.4', CLBDescription(lb_id='5', port=80)))
             )]))
Пример #49
0
 def test_optimize_clb_adds(self):
     """
     Multiple :class:`AddNodesToCLB` steps for the same LB
     are merged into one.
     """
     steps = pbag([
         AddNodesToCLB(lb_id='5',
                       address_configs=s(
                           ('1.1.1.1', CLBDescription(lb_id='5',
                                                      port=80)))),
         AddNodesToCLB(lb_id='5',
                       address_configs=s(
                           ('1.2.3.4', CLBDescription(lb_id='5', port=80))))
     ])
     self.assertEqual(
         optimize_steps(steps),
         pbag([
             AddNodesToCLB(
                 lb_id='5',
                 address_configs=s(
                     ('1.1.1.1', CLBDescription(lb_id='5', port=80)),
                     ('1.2.3.4', CLBDescription(lb_id='5', port=80))))
         ]))
Пример #50
0
 def test_building_servers_are_deleted(self):
     """
     A building server to be scaled down is just deleted and removed from
     any load balancers.  It is not put into a draining state, nor are the
     load balancers nodes drained, even if the timeout is greater than zero.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0,
                               draining_timeout=10.0),
             set([server('abc', state=ServerState.BUILD,
                         servicenet_address='1.1.1.1',
                         desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
             set([CLBNode(node_id='1', address='1.1.1.1',
                          description=self.clb_desc),
                  RCv3Node(node_id='2', cloud_server_id='abc',
                           description=self.rcv3_desc)]),
             0),
         pbag([
             DeleteServer(server_id='abc'),
             RemoveNodesFromCLB(lb_id='1', node_ids=s('1')),
             BulkRemoveFromRCv3(lb_node_pairs=s(
                 (self.rcv3_desc.lb_id, 'abc')))
         ]))
Пример #51
0
 def test_active_server_without_load_balancers_can_be_deleted(self):
     """
     If an active server to be scaled down is not attached to any load
     balancers, even if it should be, it can be deleted.
     It is not first put into draining state.
     """
     self.assertEqual(
         converge(
             DesiredGroupState(server_config={}, capacity=0,
                               draining_timeout=10.0),
             set([server('abc', state=ServerState.ACTIVE,
                         desired_lbs=s(self.clb_desc, self.rcv3_desc))]),
             set(),
             0),
         pbag([DeleteServer(server_id='abc')]))
Пример #52
0
    def test_children(self):
        fs = self.FS()
        tempdir = fs.temporary_directory()
        self.addCleanup(fs.remove, tempdir)

        a = tempdir.descendant("a")
        b = tempdir.descendant("b")
        c = tempdir.descendant("b", "c")
        d = tempdir.descendant("d")

        fs.touch(path=a)
        fs.create_directory(path=b)
        fs.touch(path=c)
        fs.link(source=c, to=d)

        self.assertEqual(fs.children(path=tempdir), s(a, b, d))
Пример #53
0
    def test_remove_does_not_follow_directory_links(self):
        fs = self.FS()
        tempdir = fs.temporary_directory()
        self.addCleanup(fs.remove, tempdir)

        directory = tempdir.descendant("directory")
        fs.create_directory(path=directory)
        fs.touch(directory.descendant("a"))

        link = tempdir.descendant("link")
        fs.link(source=directory, to=link)
        self.assertTrue(fs.is_link(path=link))

        fs.remove(path=link)

        self.assertEqual(
            fs.children(path=directory), s(directory.descendant("a")),
        )
Пример #54
0
    def reflexiveTransitiveClosure(self):
        closure = self.relation
        for i in self.set:
            closure = closure.add((i, i))

        while True:
            new_relation = s()
            for i in closure:
                for j in closure:
                    if i[1] == j[0]:
                        new_relation = new_relation.add((i[0], j[1]))

            current_closure = closure | new_relation
            if closure == current_closure:
                break
            closure = current_closure

        return Relation(self.set, closure)
Пример #55
0
        def reflexive_transitive(self):
            """reflexive-transitive closure"""
            relation = self.relation
            temp = s()
            for x in self.members:
                if (x, x) not in self.relation:
                    temp = temp.add((x, x))
            while True:
                for x, y in relation:
                    for w, v in relation:
                        if w == y:
                            temp = temp.add((x, v))
                current = relation.union(temp)
                if current == relation:
                    break
                relation = current

            return get_relation_class(self.members, relation)
Пример #56
0
def no_interesctions(point_map):
    """Finds all of the graph edges such that all nodes are connected and no
    edges 'intersect' on the 2d plane"""
    all_edges = pset([
        s(anchor, search) for anchor in point_map.keys()
        for search in point_map.keys() if anchor != search
    ])
    edges_by_distance = sorted(plist(all_edges),
                               key=lambda y: edge_distance(y, point_map))

    edges = []
    for edge in edges_by_distance:
        pair_a = edge_to_pair(edge, point_map)
        if not any([
                find_affine_intersection(pair_a, edge_to_pair(y, point_map))
                for y in edges
        ]):
            edges.append(edge)

    return edges
Пример #57
0
    def test_remove(self):
        fs = self.FS()
        tempdir = fs.temporary_directory()
        self.addCleanup(fs.remove, tempdir)

        directory = tempdir.descendant("directory")
        fs.create_directory(directory)

        a = directory.descendant("a")
        b = directory.descendant("b")
        c = directory.descendant("b", "c")
        d = directory.descendant("d")

        fs.touch(path=a)
        fs.create_directory(path=b)
        fs.touch(path=c)
        fs.touch(path=d)

        fs.remove(directory)

        self.assertEqual(fs.children(path=tempdir), s())
Пример #58
0
    def test_glob_children(self):
        fs = self.FS()
        tempdir = fs.temporary_directory()
        self.addCleanup(fs.remove, tempdir)

        a = tempdir.descendant("a")
        b = tempdir.descendant("b")
        c = tempdir.descendant("b", "c")
        abc = tempdir.descendant("abc")
        fedcba = tempdir.descendant("fedcba")

        fs.touch(path=a)
        fs.create_directory(path=b)
        fs.touch(path=c)
        fs.touch(path=abc)
        fs.touch(path=fedcba)

        self.assertEqual(
            fs.glob_children(path=tempdir, glob="*b*"),
            s(b, abc, fedcba),
        )
Пример #59
0
    def test_clb_remove_multiple_load_balancers(self):
        """
        Multiple :class:`RemoveNodesFromCLB` steps for the same LB
        are merged into one.
        """
        steps = pbag([
            RemoveNodesFromCLB(lb_id='5', node_ids=s('1')),
            RemoveNodesFromCLB(lb_id='5', node_ids=s('2')),
            RemoveNodesFromCLB(lb_id='6', node_ids=s('3')),
            RemoveNodesFromCLB(lb_id='6', node_ids=s('4'))
        ])

        self.assertEqual(
            optimize_steps(steps),
            pbag([
                RemoveNodesFromCLB(lb_id='5', node_ids=s('1', '2')),
                RemoveNodesFromCLB(lb_id='6', node_ids=s('3', '4'))
            ]))
Пример #60
0
    def __init__(self, game: Game) -> None:
        root = tk.Tk()
        root.resizable(False, False)
        root.title(TITLE)

        self.canvas = tk.Canvas(
            root,
            height=SCREEN_SIZE,
            width=SCREEN_SIZE,
            bg=COLOR_BG,
            highlightthickness=0,
        )
        self.game = game
        self.text = Text(root, game)

        for player in s(Player.BLUE, Player.RED):
            self.generate_base_polygons(game.board, player)

        for c in game.board.cycles:
            CyclePolygon(self, game, c)

        self.canvas.pack(side="left", fill="both")

        root.mainloop()