def test_enumerate_boards(self): w, h = 10, 9 dead_boards = set([ (0, 0, 1), ]) dead_links = set([ (0, 0, 0, Links.north), (1, 2, 0, Links.north), ]) cf = _CandidateFilter(w, h, dead_boards, dead_links, 0, 0, False) # From 0, 0 we should not be able to reach anything else unless we have # wrap-around links assert cf._enumerate_boards(0, 0, 1, 1) == set([(0, 0, 0)]) assert cf._enumerate_boards(0, 0, 3, 4) == set([(0, 0, 0)]) assert cf._enumerate_boards(0, 0, w, h) == set([ # pragma: no branch (x, y, z) for x in range(w) for y in range(h) for z in range(3) if (x, y, z) not in dead_boards]) # From 1, 1 we should be able to reach everything despite being blocked # off one of the links from (1, 1, 0) assert cf._enumerate_boards(1, 2, 5, 4) == set([ # pragma: no branch (x, y, z) for x in range(1, 6) for y in range(2, 6) for z in range(3)])
def test_expected_boards(self, expected_boards): dead_boards = set([(0, 0, 2)]) dead_links = set() cf = _CandidateFilter(1, 1, dead_boards, dead_links, 0, None, False, expected_boards) assert cf(0, 0, 1, 1) == (expected_boards < 3)
def test_call_no_bottom_left_board(self, max_dead_boards): # Should never allow allocation when bottom-left board is dead dead_boards = set([(0, 0, 0)]) dead_links = set() cf = _CandidateFilter(1, 1, dead_boards, dead_links, max_dead_boards, None, False) assert cf(0, 0, 1, 1) is False
def test_not_a_torus(self): w, h = 10, 9 cf = _CandidateFilter(w, h, set(), set(), 0, 0, True) assert cf(0, 0, w - 1, h - 1) is False assert cf(0, 0, w - 1, h) is True assert cf(0, 0, w, h - 1) is True assert cf(0, 0, w, h) is True
def test_torus(self): # Should notice if a torus is allocated w, h = 10, 9 cf = _CandidateFilter(w, h, set(), set(), None, None, False) assert cf(0, 0, 1, 1) is True assert cf.torus is WrapAround.none assert cf(0, 0, w, 1) is True assert cf.torus is WrapAround.x assert cf(0, 0, 1, h) is True assert cf.torus is WrapAround.y assert cf(0, 0, w, h) is True assert cf.torus is WrapAround.both
def test_call_too_many_dead(self, w, h, max_dead_boards): w, h = 10, 9 dead_boards = set([ (0, 0, 1), ]) dead_links = set([ (0, 0, 0, Links.north), (1, 2, 0, Links.north), ]) cf = _CandidateFilter(w, h, dead_boards, dead_links, max_dead_boards, 0, False) assert cf(0, 0, w, h) is False
def test_call_success(self, have_dead_links, have_dead_boards): # If "None" is provided for maximum links/boards we should always # succeed w, h = 10, 9 dead_boards = set([0, 0, 1]) if have_dead_boards else set() dead_links = set([0, 0, 0, Links.north]) if have_dead_links else set() cf = _CandidateFilter(w, h, dead_boards, dead_links, None, None, False) assert cf(0, 0, 1, 1) is True assert cf.boards == set((0, 0, z) for z in range(3)) assert cf.periphery == set( # pragma: no branch (0, 0, z, link) for z in range(3) for link in Links if board_down_link(0, 0, z, link, w, h)[:2] != (0, 0)) assert cf.torus == WrapAround.none
def test_call_too_many_dead_links(self, require_torus, dead_on_torus): w, h = 10, 9 dead_boards = set() dead_links = set([ (0, 0, 0, Links.west) if dead_on_torus else (0, 0, 0, Links.north), ]) max_dead_links = 0 cf = _CandidateFilter(w, h, dead_boards, dead_links, 0, max_dead_links, require_torus) expected = not require_torus and dead_on_torus if require_torus: assert cf(0, 0, w, h) is expected else: assert cf(0, 0, 1, 1) is expected
def test_classify_links_wrap_around(self): w, h = 10, 10 cf = _CandidateFilter(w, h, set(), set(), 0, 0, False) assert cf._classify_links(set([(0, 0, 0), (0, 0, 1)]))[5] == \ WrapAround.none assert cf._classify_links(set([(0, 0, 0), (0, 0, 1), (0, h-1, 2)]))[5] == \ WrapAround.y assert cf._classify_links(set([(0, 0, 0), (0, 0, 1), (w-1, 0, 1)]))[5] == \ WrapAround.x assert cf._classify_links(set([(0, 0, 0), (0, 0, 1), (0, h-1, 2), (w-1, 0, 1)]))[5] == \ WrapAround.both
def test_classify_links(self): w, h = 10, 9 dead_boards = set([ (0, 0, 1), ]) dead_links = set([ (0, 0, 0, Links.north), (0, 0, 2, Links.south), (0, 0, 0, Links.north_east), (0, 0, 1, Links.south_west), (0, 0, 0, Links.east), (0, h-1, 2, Links.west), (0, 0, 2, Links.north_east), (1, 1, 0, Links.south_west), ]) cf = _CandidateFilter(w, h, dead_boards, dead_links, 0, 0, False) # For 1x1 we should have just peripheral links all of which are listed # even if they're dead. (alive, wrap, dead, dead_wrap, periphery, wrap_around_type) =\ cf._classify_links(set([(0, 0, 0)])) assert alive == set() assert wrap == set() assert dead == set() assert dead_wrap == set() assert periphery == set([(0, 0, 0, link) for link in Links]) assert wrap_around_type is WrapAround.none # For a connected block, links to internal dead boards should still be # regarded as peripheral. NB: The block of chips is not fully connected # but provides exhibits examples of all types of connectivity. # # (1, 1, 0) -> ___ # ___/ 0 \___ # (0, 0, 2) -> / 2 x___/ 2 \ <- (1, 0, 2) # \_x_/ X \___/ # (0, 0, 0) -> / 0 x___/ 0 \ <- (1, 0, 0) # \___x 2 \___/ # (0, h-1, 2) -> \___/ (alive, wrap, dead, dead_wrap, periphery, wrap_around_type) =\ cf._classify_links(set([(0, 0, 0), (0, 0, 2), (1, 1, 0), (1, 0, 2), (1, 0, 0), (0, h-1, 2)])) assert alive == set([ (1, 1, 0, Links.east), (1, 0, 2, Links.west), (1, 0, 2, Links.south), (1, 0, 0, Links.north), ]) assert wrap == set([ (1, 0, 0, Links.south_west), (0, h-1, 2, Links.north_east), ]) assert dead == set([ (0, 0, 0, Links.north), (0, 0, 2, Links.south), (0, 0, 2, Links.north_east), (1, 1, 0, Links.south_west), ]) assert dead_wrap == set([ (0, 0, 0, Links.east), (0, h-1, 2, Links.west), ]) assert periphery == set([ # Around the outside (0, 0, 0, Links.south), (0, 0, 0, Links.south_west), (0, 0, 0, Links.west), (0, 0, 2, Links.south_west), (0, 0, 2, Links.west), (0, 0, 2, Links.north), (1, 1, 0, Links.west), (1, 1, 0, Links.north), (1, 1, 0, Links.north_east), (1, 0, 2, Links.north), (1, 0, 2, Links.north_east), (1, 0, 2, Links.east), (1, 0, 0, Links.north_east), (1, 0, 0, Links.east), (1, 0, 0, Links.south), (0, h-1, 2, Links.east), (0, h-1, 2, Links.south), (0, h-1, 2, Links.south_west), # Around the inside (0, 0, 0, Links.north_east), (0, 0, 2, Links.east), (1, 1, 0, Links.south), (1, 0, 2, Links.south_west), (1, 0, 0, Links.west), (0, h-1, 2, Links.north), ]) assert wrap_around_type == WrapAround.y