Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type unit tests #590

Merged
merged 15 commits into from
Mar 3, 2025
3 changes: 1 addition & 2 deletions .github/workflows/python_actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,5 @@ jobs:
coverage-package: pacman
flake8-packages: pacman unittests pacman_test_objects
pylint-packages: pacman pacman_test_objects
mypy-full-packages: pacman pacman_test_objects
mypy-packages: unittests
mypy-full-packages: pacman pacman_test_objects unittests
secrets: inherit
2 changes: 1 addition & 1 deletion mypyd.bash
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ utils="../SpiNNUtils/spinn_utilities"
machine="../SpiNNMachine/spinn_machine"
man="../SpiNNMan/spinnman"

mypy --python-version 3.8 --disallow-untyped-defs $utils $machine $man pacman pacman_test_objects
mypy --python-version 3.8 --disallow-untyped-defs $utils $machine $man pacman pacman_test_objects unittests
9 changes: 4 additions & 5 deletions pacman/model/graphs/application/application_vertex.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
Collection, Generic, Optional, Tuple, TypeVar, Union, cast, TYPE_CHECKING)

import numpy
from typing_extensions import Self

from spinn_utilities.abstract_base import AbstractBase, abstractmethod
from spinn_utilities.ordered_set import OrderedSet
Expand Down Expand Up @@ -62,7 +61,7 @@ class ApplicationVertex(AbstractVertex, Generic[MV], metaclass=AbstractBase):
def __init__(
self, label: Optional[str] = None,
max_atoms_per_core: Optional[Union[int, Tuple[int, ...]]] = None,
splitter: Optional[AbstractSplitterCommon[Self]] = None):
splitter: Optional[AbstractSplitterCommon] = None):
"""
:param str label: The optional name of the vertex.
:param max_atoms_per_core: The max number of atoms that can be
Expand All @@ -77,7 +76,7 @@ def __init__(
~pacman.model.partitioner_splitters.AbstractSplitterCommon
"""
# Need to set to None temporarily as add_constraint checks splitter
self._splitter: Optional[AbstractSplitterCommon[Self]] = None
self._splitter: Optional[AbstractSplitterCommon] = None
super().__init__(label)
self._machine_vertices: OrderedSet[MV] = OrderedSet()
if splitter:
Expand Down Expand Up @@ -105,7 +104,7 @@ def has_splitter(self) -> bool:
return self._splitter is not None

@property
def splitter(self) -> AbstractSplitterCommon[Self]:
def splitter(self) -> AbstractSplitterCommon:
"""
:rtype: ~pacman.model.partitioner_splitters.AbstractSplitterCommon
"""
Expand All @@ -117,7 +116,7 @@ def splitter(self) -> AbstractSplitterCommon[Self]:
return s

@splitter.setter
def splitter(self, new_value: AbstractSplitterCommon[Self]) -> None:
def splitter(self, new_value: AbstractSplitterCommon) -> None:
"""
Sets the splitter object. Does not allow repeated settings.

Expand Down
2 changes: 1 addition & 1 deletion pacman/model/tags/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def get_ip_tags_for_vertex(self, vertex: MachineVertex) -> Optional[
return self._ip_tags_by_vertex.get(vertex)

def get_reverse_ip_tags_for_vertex(
self, vertex: MachineVertex) -> Optional[Iterable[ReverseIPTag]]:
self, vertex: MachineVertex) -> Optional[List[ReverseIPTag]]:
"""
Get the Reverse IP Tags assigned to a given machine vertex.

Expand Down
4 changes: 1 addition & 3 deletions pacman_test_objects/simple_test_vertex.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
"""
from typing import Optional

from typing_extensions import Self

from spinn_utilities.overrides import overrides

from pacman.model.partitioner_interfaces.legacy_partitioner_api import (
Expand All @@ -38,7 +36,7 @@ class SimpleTestVertex(ApplicationVertex, LegacyPartitionerAPI):
def __init__(self, n_atoms: int, label: str = "testVertex",
max_atoms_per_core: int = 256,
fixed_sdram_value: Optional[int] = None,
splitter: Optional[AbstractSplitterCommon[Self]] = None):
splitter: Optional[AbstractSplitterCommon] = None):
super().__init__(
label=label, max_atoms_per_core=max_atoms_per_core,
splitter=splitter)
Expand Down
112 changes: 62 additions & 50 deletions unittests/data/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,38 @@ class SimpleTestVertex2(SimpleTestVertex):

class TestSimulatorData(unittest.TestCase):

def setUp(self):
def setUp(self) -> None:
unittest_setup()

def test_setup(self):
def test_setup(self) -> None:
# What happens before setup depends on the previous test
# Use manual_check to verify this without dependency
PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_n_placements()

def test_mock(self):
def test_mock(self) -> None:
PacmanDataWriter.mock()
# check there is a value not what it is
PacmanDataView.get_run_dir_path()

def test_graph_functions(self):
def test_graph_functions(self) -> None:
writer = PacmanDataWriter.setup()
sdram = ConstantSDRAM(123)
app1 = SimpleTestVertex(12, "app1")
m11 = app1.create_machine_vertex(Slice(0, 6), None)
m11 = app1.create_machine_vertex(Slice(0, 6), sdram)
app1.remember_machine_vertex(m11)
m12 = app1.create_machine_vertex(Slice(7, 12), None)
m12 = app1.create_machine_vertex(Slice(7, 12), sdram)
app1.remember_machine_vertex(m12)
app2 = SimpleTestVertex2(23, "app21")
m21 = app2.create_machine_vertex(Slice(0, 23), None)
m21 = app2.create_machine_vertex(Slice(0, 23), sdram)
app2.remember_machine_vertex(m21)
app3 = SimpleTestVertex2(33, "app3")
m31 = app3.create_machine_vertex(Slice(0, 11), None)
m31 = app3.create_machine_vertex(Slice(0, 11), sdram)
app3.remember_machine_vertex(m31)
m32 = app3.create_machine_vertex(Slice(11, 22), None)
m32 = app3.create_machine_vertex(Slice(11, 22), sdram)
app3.remember_machine_vertex(m32)
m33 = app3.create_machine_vertex(Slice(22, 33), None)
m33 = app3.create_machine_vertex(Slice(22, 33), sdram)
app3.remember_machine_vertex(m33)
edge12 = ApplicationEdge(app1, app2)
edge32 = ApplicationEdge(app3, app2)
Expand Down Expand Up @@ -98,7 +99,7 @@ def test_graph_functions(self):
self.assertEqual(2, PacmanDataView.get_n_partitions())
ps = PacmanDataView.get_outgoing_edge_partitions_starting_at_vertex(
app1)
self.assertEqual(1, len(ps))
self.assertEqual(1, len(list(ps)))
self.assertEqual([edge12, edge13, edge11, edge32],
PacmanDataView.get_edges())
self.assertEqual(6, PacmanDataView.get_n_machine_vertices())
Expand All @@ -123,74 +124,84 @@ def test_graph_functions(self):
with self.assertRaises(SimulatorShutdownException):
PacmanDataView.add_edge(ApplicationEdge(app1, app2), "new")

def test_graph_safety_code(self):
def test_graph_safety_code(self) -> None:
writer = PacmanDataWriter.setup()
# there is always a graph so to hit safety code you need a hack
writer._PacmanDataWriter__pacman_data._graph = None
(writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data)._graph = None
with self.assertRaises(DataNotYetAvialable):
writer.add_vertex(None)
writer.add_vertex(SimpleTestVertex(1))
with self.assertRaises(DataNotYetAvialable):
writer.add_edge(None, None)
writer.add_edge(ApplicationEdge(
SimpleTestVertex(1), SimpleTestVertex2(1)), "test")
with self.assertRaises(DataNotYetAvialable):
writer.iterate_vertices()
with self.assertRaises(DataNotYetAvialable):
list(writer.get_vertices_by_type(None))
list(writer.get_vertices_by_type(SimpleTestVertex))
with self.assertRaises(DataNotYetAvialable):
writer.get_n_vertices()
with self.assertRaises(DataNotYetAvialable):
writer.iterate_partitions()
with self.assertRaises(DataNotYetAvialable):
writer.get_n_partitions()
with self.assertRaises(DataNotYetAvialable):
writer.get_outgoing_edge_partitions_starting_at_vertex(None)
writer.get_outgoing_edge_partitions_starting_at_vertex(
SimpleTestVertex(1))
with self.assertRaises(DataNotYetAvialable):
writer.get_edges()
with self.assertRaises(DataNotYetAvialable):
writer.get_n_machine_vertices()
with self.assertRaises(DataNotYetAvialable):
list(writer.iterate_machine_vertices())

def test_graph_never_changes(self):
def test_graph_never_changes(self) -> None:
writer = PacmanDataWriter.setup()
# graph is hidden so need a hack to get it.
graph1 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
writer.start_run()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph2 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))
writer.finish_run()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))
writer.soft_reset()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))
writer.hard_reset()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))
writer.start_run()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))
writer.finish_run()
graph2 = writer._PacmanDataWriter__pacman_data._graph
graph1 = (writer. # type: ignore[attr-defined]
_PacmanDataWriter__pacman_data._graph)
self.assertEqual(id(graph1), id(graph2))

def test_placements_safety_code(self):
def test_placements_safety_code(self) -> None:
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
writer.iterate_placemements()
with self.assertRaises(DataNotYetAvialable):
writer.iterate_placements_by_vertex_type(None)
writer.iterate_placements_by_vertex_type(SimpleTestVertex)
with self.assertRaises(DataNotYetAvialable):
writer.iterate_placements_on_core((None, None))
writer.iterate_placements_on_core((1, 2))
with self.assertRaises(DataNotYetAvialable):
writer.iterate_placements_by_xy_and_type((None, None), None)
writer.iterate_placements_by_xy_and_type((1, 1), SimpleTestVertex)
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_n_placements()
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_placement_of_vertex(None)
PacmanDataView.get_placement_of_vertex(SimpleMachineVertex(None))
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_placement_on_processor(None, None, None)
PacmanDataView.get_placement_on_processor(1, 2, 3)

def test_placements(self):
def test_placements(self) -> None:
writer = PacmanDataWriter.setup()
info = Placements([])
p1 = Placement(SimpleMachineVertex(None), 1, 2, 3)
Expand All @@ -209,29 +220,29 @@ def test_placements(self):
PacmanDataView.get_placement_of_vertex(SimpleMachineVertex(None))

with self.assertRaises(TypeError):
writer.set_placements("Bacon")
writer.set_placements("Bacon") # type: ignore[arg-type]

def test_routing_infos(self):
def test_routing_infos(self) -> None:
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_routing_infos()
info = RoutingInfo()
writer.set_routing_infos(info)
self.assertEqual(info, PacmanDataView.get_routing_infos())
with self.assertRaises(TypeError):
writer.set_routing_infos("Bacon")
writer.set_routing_infos("Bacon") # type: ignore[arg-type]

def test_tags(self):
def test_tags(self) -> None:
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_tags()
tags = Tags()
writer.set_tags(tags)
self.assertEqual(tags, PacmanDataView.get_tags())
with self.assertRaises(TypeError):
writer.set_tags("Bacon")
writer.set_tags("Bacon") # type: ignore[arg-type]

def test_router_tables(self):
def test_router_tables(self) -> None:
table = MulticastRoutingTables()
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
Expand All @@ -241,9 +252,9 @@ def test_router_tables(self):
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_precompressed()
with self.assertRaises(TypeError):
writer.set_uncompressed("Bacon")
writer.set_uncompressed("Bacon") # type: ignore[arg-type]

def test_precompressed_router_tables(self):
def test_precompressed_router_tables(self) -> None:
table = MulticastRoutingTables()
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
Expand All @@ -254,18 +265,18 @@ def test_precompressed_router_tables(self):
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_uncompressed()
with self.assertRaises(TypeError):
writer.set_precompressed(None)
writer.set_precompressed(None) # type: ignore[arg-type]

def test_plan_n_timesteps(self):
def test_plan_n_timesteps(self) -> None:
writer = PacmanDataWriter.setup()
writer.set_plan_n_timesteps(1234)
self.assertEqual(1234, PacmanDataView.get_plan_n_timestep())
with self.assertRaises(TypeError):
writer.set_plan_n_timesteps("Bacon")
writer.set_plan_n_timesteps("Bacon") # type: ignore[arg-type]
with self.assertRaises(PacmanConfigurationException):
writer.set_plan_n_timesteps(-1)

def test_routing_table_by_partition(self):
def test_routing_table_by_partition(self) -> None:
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
PacmanDataView.get_routing_table_by_partition()
Expand All @@ -274,9 +285,10 @@ def test_routing_table_by_partition(self):
self.assertEqual(
table, PacmanDataView.get_routing_table_by_partition())
with self.assertRaises(TypeError):
writer.set_routing_table_by_partition("Bacon")
writer.set_routing_table_by_partition(
"Bacon") # type: ignore[arg-type]

def test_add_requires_mapping(self):
def test_add_requires_mapping(self) -> None:
writer = PacmanDataWriter.setup()
# before first run
self.assertTrue(PacmanDataView.get_requires_mapping())
Expand Down Expand Up @@ -346,7 +358,7 @@ def test_add_requires_mapping(self):
writer.hard_reset()
self.assertTrue(PacmanDataView.get_requires_mapping())

def test_get_monitors(self):
def test_get_monitors(self) -> None:
writer = PacmanDataWriter.setup()
self.assertEqual(0, PacmanDataView.get_all_monitor_cores())
self.assertEqual(ConstantSDRAM(0),
Expand Down Expand Up @@ -374,7 +386,7 @@ def test_get_monitors(self):
self.assertEqual(VariableSDRAM(200 + 100 + 55, 10 + 15),
PacmanDataView.get_ethernet_monitor_sdram())

def test_required(self):
def test_required(self) -> None:
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
self.assertIsNone(PacmanDataView.get_n_boards_required())
Expand Down Expand Up @@ -449,6 +461,6 @@ def test_required(self):
with self.assertRaises(ValueError):
writer.set_n_required(0, None)
with self.assertRaises(TypeError):
writer.set_n_required(None, "five")
writer.set_n_required(None, "five") # type: ignore[arg-type]
with self.assertRaises(TypeError):
writer.set_n_required("2.3", None)
writer.set_n_required("2.3", None) # type: ignore[arg-type]
Loading
Loading