Skip to content

Commit

Permalink
Update test patterns (#810)
Browse files Browse the repository at this point in the history
* fix stray Scaffold constructors

* delete N/A test files

* fix Scaffold constructors

* skip MissingActiveConfigErrors

* fix non zero offset topologies

* don't use non-included hdf5 default

* bump deps
  • Loading branch information
Helveg committed Mar 7, 2024
1 parent 83083a7 commit 35afc0c
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 337 deletions.
2 changes: 1 addition & 1 deletion bsb/config/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class Configuration:
@classmethod
def default(cls, **kwargs):
default_args = dict(
storage={"engine": "hdf5"},
storage={"engine": "fs"},
network={"x": 200, "y": 200, "z": 200},
partitions={},
cell_types={},
Expand Down
1 change: 0 additions & 1 deletion bsb/config/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ def _load_class(cfg_classname, module_path, interface=None, classmap=None):
class_ref = cfg_classname
class_name = cfg_classname.__name__
else:
print("classname?", cfg_classname, classmap)
class_ref = _load_object(cfg_classname, module_path)
class_name = class_ref.__name__

Expand Down
20 changes: 16 additions & 4 deletions bsb/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
from ._util import obj_str_insert
from .config._config import Configuration
from .connectivity import ConnectionStrategy
from .exceptions import InputError, NodeNotFoundError, RedoError
from .exceptions import (
InputError,
MissingActiveConfigError,
NodeNotFoundError,
RedoError,
)
from .placement import PlacementStrategy
from .profiling import meter
from .reporting import report, warn
Expand Down Expand Up @@ -159,7 +164,10 @@ def _bootstrap(self, config, storage, clear=False):
report(f"Pulling configuration from linked {linked}.", level=2)
config = linked
elif storage is not None:
config = storage.load_active_config()
try:
config = storage.load_active_config()
except MissingActiveConfigError:
config = Configuration.default()
else:
config = Configuration.default()
if not storage:
Expand Down Expand Up @@ -245,9 +253,13 @@ def resize(self, x=None, y=None, z=None):
if y is not None:
self.network.y = y
if z is not None:
z = self.network.z
self.network.z = z
self.topology.do_layout(
box_layout([0.0, 0.0, 0.0], [self.network.x, self.network.y, self.network.z])
box_layout(
self.network.origin,
np.array(self.network.origin)
+ [self.network.x, self.network.y, self.network.z],
)
)

@meter()
Expand Down
1 change: 1 addition & 0 deletions bsb/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
DataNotFoundError=_e(),
AttributeMissingError=_e(),
UnknownStorageEngineError=_e(),
MissingActiveConfigError=_e(),
),
DataNotProvidedError=_e(),
PluginError=_e("plugin"),
Expand Down
3 changes: 2 additions & 1 deletion bsb/storage/fs/file_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import typing
from uuid import uuid4

from ...exceptions import MissingActiveConfigError
from ..interfaces import FileStore as IFileStore


Expand Down Expand Up @@ -105,7 +106,7 @@ def load_active_config(self):

stored = self.find_meta("active_config", True)
if stored is None:
raise Exception("No active config")
raise MissingActiveConfigError("No active config")
else:
content, meta = stored.load()
tree = json.loads(content)
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ parallel = [
]
test = [
"bsb-arbor==0.0.0b1",
"bsb-hdf5==1.0.0b2",
"bsb-test==0.0.0b14",
"bsb-hdf5==1.0.0b3",
"bsb-test==0.0.0b15",
"coverage~=7.3",
]
docs = [
Expand Down
25 changes: 13 additions & 12 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1404,9 +1404,9 @@ class MainClass:
self.assertEqual(instance.b, copied.b)


class TestDictScripting(unittest.TestCase):
class TestDictScripting(RandomStorageFixture, unittest.TestCase, engine_name="fs"):
def test_add(self):
netw = Scaffold()
netw = Scaffold(storage=self.storage)
cfg = netw.configuration
ct = cfg.cell_types.add("test", spatial=dict(radius=2))
# Check that the dict operation completed succesfully
Expand All @@ -1428,7 +1428,7 @@ def test_ref(self):
self.assertIs(reg, part.region, "reference not resolved")

def test_clear(self):
netw = Scaffold()
netw = Scaffold(storage=self.storage)
netw.regions.add("ello", children=[])
netw.regions.add("ello2", children=[])
r3 = netw.regions.add("ello3", children=[])
Expand All @@ -1442,7 +1442,7 @@ def test_clear(self):
self.assertIs(r3, _attrs._get_root(r3), "chain not cleared")

def test_pop(self):
netw = Scaffold()
netw = Scaffold(storage=self.storage)
netw.regions.add("ello", children=[])
netw.regions.add("ello2", children=[])
r3 = netw.regions.add("ello3", children=[])
Expand All @@ -1457,7 +1457,7 @@ def test_pop(self):
self.assertIs(r3, _attrs._get_root(r3), "chain not cleared")

def test_popitem(self):
netw = Scaffold()
netw = Scaffold(storage=self.storage)
netw.regions.add("ello", children=[])
netw.regions.add("ello2", children=[])
r3 = netw.regions.add("ello3", children=[])
Expand All @@ -1472,15 +1472,15 @@ def test_popitem(self):
self.assertIs(r3, _attrs._get_root(r3), "chain not cleared")

def test_setdefault(self):
netw = Scaffold()
netw = Scaffold(storage=self.storage)
default = netw.regions.setdefault("ello", dict(children=[]))
self.assertEqual(RegionGroup, type(default), "expected group")
newer = netw.regions.setdefault("ello", dict(children=[]))
self.assertIs(default, newer, "default not respected")

def test_ior(self):
n1 = Scaffold()
n2 = Scaffold()
n1 = Scaffold(storage=self.random_storage())
n2 = Scaffold(storage=self.random_storage())
n1.regions.add("test", children=[])
n2.regions.add("test2", children=[])
n2.regions.add("test", children=[], type="stack")
Expand All @@ -1489,9 +1489,10 @@ def test_ior(self):
self.assertEqual("stack", n1.regions.test.type, "merge right failed")


class TestListScripting(unittest.TestCase):
class TestListScripting(RandomStorageFixture, unittest.TestCase, engine_name="fs"):
def setUp(self):
self.netw = Scaffold()
super().setUp()
self.netw = Scaffold(storage=self.storage)
self.list = self.netw.cell_types.add(
"test", spatial=dict(radius=2, morphologies=[])
).spatial.morphologies
Expand Down Expand Up @@ -1565,12 +1566,12 @@ def test_clear(self):
self.assertList(0)


class TestScripting(unittest.TestCase):
class TestScripting(RandomStorageFixture, unittest.TestCase, engine_name="fs"):
def test_booted_root(self):
cfg = Configuration.default()
self.assertIsNone(_attrs._booted_root(cfg), "shouldnt be booted yet")
self.assertIsNone(_attrs._booted_root(cfg.partitions), "shouldnt be booted yet")
Scaffold(cfg)
Scaffold(cfg, self.storage)
self.assertIsNotNone(_attrs._booted_root(cfg), "now it should be booted")


Expand Down
105 changes: 56 additions & 49 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,76 @@
import os
import unittest

from bsb_test import RandomStorageFixture
from bsb_test import NetworkFixture, RandomStorageFixture

from bsb import core
from bsb.config import Configuration
from bsb.core import Scaffold
from bsb.storage.interfaces import PlacementSet


class TestCore(unittest.TestCase):
class TestCore(
RandomStorageFixture, NetworkFixture, unittest.TestCase, engine_name="hdf5"
):
def setUp(self):
self.cfg = Configuration.default()
super().setUp()

def test_from_storage(self):
# Use the `from_storage` function to load a network.
netw = Scaffold()
netw.compile(clear=True)
core.from_storage(netw.storage.root)
"""Use the `from_storage` function to load a network."""
self.network.compile(clear=True)
core.from_storage(self.network.storage.root)

def test_missing_storage(self):
with self.assertRaises(FileNotFoundError):
core.from_storage("does_not_exist")

@classmethod
def tearDownClass(cls):
try:
os.unlink("does_not_exist2")
except Exception:
pass

def test_set_netw_root_nodes(self):
netw = Scaffold()
# anti-pattern, but testing it anyway, resetting the storage configuration leads
# to undefined behavior. (Only changing the properties of the storage object is
# supported).
netw.storage_cfg = {"root": netw.storage.root, "engine": "hdf5"}
netw.storage_cfg.root
"""
Test the anti-pattern of resetting the storage configuration for runtime errors.
"""
self.network.storage_cfg = {"root": self.network.storage.root, "engine": "hdf5"}

def test_set_netw_config(self):
netw = Scaffold()
netw.configuration = Configuration.default(regions=dict(x=dict(children=[])))
self.assertEqual(1, len(netw.regions), "setting cfg failed")
"""
Test resetting the configuration object
"""
self.network.configuration = Configuration.default(
regions=dict(x=dict(children=[]))
)
self.assertEqual(1, len(self.network.regions), "setting cfg failed")

def test_netw_props(self):
netw = Scaffold()
self.assertEqual(0, len(netw.morphologies.all()), "just checking morph prop")
"""
Test the storage engine property keys like `.morphologies` and `.files`
"""
self.assertEqual(
0, len(self.network.morphologies.all()), "just checking morph prop"
)

def test_resize(self):
cfg = Configuration.default()
cfg.partitions.add("layer", thickness=100)
cfg.regions.add("region", children=["layer"])
netw = Scaffold(cfg)
netw.resize(x=500, y=500, z=500)
self.assertEqual(500, netw.network.x, "resize didnt update network node")
self.assertEqual(500, netw.partitions.layer.data.width, "didnt resize layer")
self.network.partitions.add("layer", thickness=100)
self.network.regions.add("region", children=["layer"])
# fixme: https://github.com/dbbs-lab/bsb-core/issues/812
self.network.topology.children.append(self.network.regions.region)
self.network.resize(x=500, y=500, z=500)
self.assertEqual(500, self.network.network.x, "resize didnt update network node")
self.assertEqual(
500, self.network.partitions.layer.data.width, "didnt resize layer"
)

def test_get_placement_sets(self):
cfg = Configuration.default(
cell_types=dict(my_type=dict(spatial=dict(radius=2, density=1)))
)
netw = Scaffold(cfg)
pslist = netw.get_placement_sets()
"""
Test that placement sets for cell types are automatically initialized
"""
self.network.cell_types.add("my_type", spatial=dict(radius=2, density=1))
pslist = self.network.get_placement_sets()
self.assertIsInstance(pslist, list, "should get list of PS")
self.assertEqual(1, len(pslist), "should have one PS per cell type")
self.assertIsInstance(pslist[0], PlacementSet, "elements should be PS")

def test_diagrams(self):
netw = Scaffold()
netw.cell_types.add("cell1", {"spatial": {"radius": 1, "density": 1}})
netw.cell_types.add("cell2", {"spatial": {"radius": 1, "density": 1}})
netw.placement.add(
self.network.cell_types.add("cell1", {"spatial": {"radius": 1, "density": 1}})
self.network.cell_types.add("cell2", {"spatial": {"radius": 1, "density": 1}})
self.network.placement.add(
"p1",
{
"strategy": "bsb.placement.FixedPositions",
Expand All @@ -74,37 +79,39 @@ def test_diagrams(self):
"partitions": [],
},
)
netw.connectivity.add(
self.network.connectivity.add(
"a_to_b",
{
"strategy": "bsb.connectivity.AllToAll",
"presynaptic": {"cell_types": ["cell1"]},
"postsynaptic": {"cell_types": ["cell2"]},
},
)
cfg_diagram = netw.get_config_diagram()
cfg_diagram = self.network.get_config_diagram()
self.assertIn('digraph "network"', cfg_diagram)
self.assertIn('cell1[label="cell1"]', cfg_diagram)
self.assertIn('cell2[label="cell2"]', cfg_diagram)
self.assertIn('cell1 -> cell2[label="a_to_b"]', cfg_diagram)
netw.compile()
storage_diagram = netw.get_storage_diagram()
self.network.compile()
storage_diagram = self.network.get_storage_diagram()
self.assertIn('digraph "network"', storage_diagram)
self.assertIn('cell1[label="cell1 (3 cell1)"]', storage_diagram)
self.assertIn('cell2[label="cell2 (3 cell2)"]', storage_diagram)
self.assertIn('cell1 -> cell2[label="a_to_b (9)"]', storage_diagram)


class TestProfiling(RandomStorageFixture, unittest.TestCase, engine_name="hdf5"):
class TestProfiling(
RandomStorageFixture, NetworkFixture, unittest.TestCase, engine_name="hdf5"
):
def setUp(self):
self.cfg = Configuration.default()
super().setUp()
self.netw = Scaffold(Configuration.default(), storage=self.storage)

def test_profiling(self):
import bsb.profiling

bsb.options.profiling = True
self.netw.compile()
self.network.compile()

self.assertGreater(
len(bsb.profiling.get_active_session()._meters), 0, "missing meters"
Expand Down

0 comments on commit 35afc0c

Please sign in to comment.