From dd5968cc8c0321807a75a2311d0fdb26653bc06a Mon Sep 17 00:00:00 2001 From: Andrey Golovanov Date: Sat, 31 Oct 2026 00:33:11 +0000 Subject: [PATCH] Rename NetGraph-Sim to NetLab-Sim Rename the distribution, package and CLI together. Preserve PRNG sequences and historical provenance, and bound pytest for benchmark fixture compatibility. --- .superset/workspace.sh | 2 +- Makefile | 6 +- README.md | 64 ++++----- benchmarks/batch.py | 8 +- benchmarks/batch_snapshots.py | 6 +- benchmarks/pmap_scale.py | 6 +- benchmarks/s0_prng.py | 12 +- benchmarks/s0_prng_determinism.json | 2 +- benchmarks/s0_w1_scale.py | 12 +- benchmarks/s0_w2_scale.py | 14 +- benchmarks/study_metrics.py | 10 +- benchmarks/study_overhead.py | 6 +- benchmarks/t3_rib_index.py | 10 +- benchmarks/t3b_rib_updates.py | 10 +- benchmarks/verify_converge.py | 12 +- benchmarks/verify_pending.py | 14 +- docs/history/README.md | 13 +- docs/history/rename-project-identity.md | 25 ++++ docs/reference.md | 6 +- {ngraph_sim => netlab_sim}/__init__.py | 10 +- netlab_sim/__main__.py | 3 + .../adapters/__init__.py | 0 {ngraph_sim => netlab_sim}/adapters/core.py | 8 +- {ngraph_sim => netlab_sim}/adapters/ngraph.py | 80 +++++------ {ngraph_sim => netlab_sim}/adapters/sonic.py | 22 ++-- {ngraph_sim => netlab_sim}/agents/__init__.py | 2 +- .../agents/reference.py | 8 +- {ngraph_sim => netlab_sim}/cli.py | 6 +- {ngraph_sim => netlab_sim}/core.py | 2 +- {ngraph_sim => netlab_sim}/exceptions.py | 2 +- {ngraph_sim => netlab_sim}/model/__init__.py | 0 .../model/addressing.py | 0 {ngraph_sim => netlab_sim}/model/contracts.py | 6 +- {ngraph_sim => netlab_sim}/model/derive.py | 26 ++-- {ngraph_sim => netlab_sim}/model/entities.py | 20 +-- {ngraph_sim => netlab_sim}/model/flows.py | 24 ++-- .../model/forwarding.py | 30 ++--- {ngraph_sim => netlab_sim}/model/hashing.py | 4 +- {ngraph_sim => netlab_sim}/model/igp.py | 12 +- .../model/interfaces.py | 6 +- {ngraph_sim => netlab_sim}/model/links.py | 2 +- {ngraph_sim => netlab_sim}/model/lpm.py | 0 {ngraph_sim => netlab_sim}/model/network.py | 36 ++--- {ngraph_sim => netlab_sim}/model/nht.py | 14 +- {ngraph_sim => netlab_sim}/model/packets.py | 6 +- {ngraph_sim => netlab_sim}/model/prng.py | 2 +- {ngraph_sim => netlab_sim}/model/routing.py | 14 +- {ngraph_sim => netlab_sim}/model/srv6.py | 48 +++---- .../model/srv6_compress.py | 6 +- {ngraph_sim => netlab_sim}/model/state.py | 10 +- {ngraph_sim => netlab_sim}/py.typed | 0 {ngraph_sim => netlab_sim}/resources.py | 2 +- .../runtime/__init__.py | 6 +- {ngraph_sim => netlab_sim}/runtime/agents.py | 20 +-- .../runtime/channels.py | 12 +- {ngraph_sim => netlab_sim}/runtime/events.py | 4 +- .../runtime/failures.py | 8 +- .../runtime/pipeline.py | 10 +- .../runtime/simulation.py | 30 ++--- .../runtime/subscriptions.py | 4 +- .../runtime/timeline.py | 12 +- .../runtime/transport.py | 24 ++-- {ngraph_sim => netlab_sim}/study.py | 28 ++-- ngraph_sim/__main__.py | 3 - pyproject.toml | 22 ++-- tests/adapters/test_ngraph.py | 52 ++++---- tests/adapters/test_ngraph_srv6.py | 10 +- tests/adapters/test_sonic.py | 10 +- tests/adapters/test_study_ngraph.py | 28 ++-- tests/agents/fixtures.py | 16 +-- tests/agents/test_locality.py | 24 ++-- tests/agents/test_reference.py | 44 +++---- tests/model/clos.py | 4 +- tests/model/test_addressing.py | 2 +- tests/model/test_agent_contract.py | 16 +-- tests/model/test_batch.py | 78 +++++------ tests/model/test_flows.py | 18 +-- tests/model/test_flows_srv6.py | 14 +- tests/model/test_forwarding_srv6.py | 30 ++--- tests/model/test_igp.py | 16 +-- tests/model/test_interfaces.py | 8 +- tests/model/test_l3_scoped.py | 22 ++-- tests/model/test_lpm.py | 8 +- tests/model/test_lpm_scale.py | 2 +- tests/model/test_network.py | 20 +-- tests/model/test_nht.py | 26 ++-- tests/model/test_nht_agent.py | 12 +- tests/model/test_nht_context.py | 22 ++-- tests/model/test_packets_hashing.py | 8 +- tests/model/test_packets_srv6.py | 8 +- tests/model/test_policies.py | 38 +++--- tests/model/test_routing.py | 36 ++--- tests/model/test_routing_srv6.py | 12 +- tests/model/test_s0_locator_consumer.py | 8 +- tests/model/test_scale_fingerprints.py | 4 +- tests/model/test_sharded_maps.py | 14 +- tests/model/test_srdb_source.py | 16 +-- tests/model/test_srv6_compress.py | 6 +- tests/model/test_srv6_contract.py | 6 +- tests/model/test_srv6_db.py | 24 ++-- tests/model/test_srv6_invalidation.py | 10 +- tests/model/test_state.py | 12 +- tests/model/test_trace.py | 10 +- tests/model/test_usid.py | 20 +-- tests/runtime/test_agent_fresh_runtime.py | 14 +- tests/runtime/test_agent_integration.py | 20 +-- tests/runtime/test_agent_prng.py | 12 +- tests/runtime/test_agent_prng_retention.py | 2 +- tests/runtime/test_agent_retry.py | 12 +- tests/runtime/test_agent_review.py | 60 ++++----- tests/runtime/test_agent_scale.py | 10 +- tests/runtime/test_agents.py | 56 ++++---- tests/runtime/test_equivalence.py | 12 +- tests/runtime/test_failures.py | 14 +- tests/runtime/test_invariants_runtime.py | 14 +- tests/runtime/test_packet_loss.py | 16 +-- tests/runtime/test_pipeline.py | 10 +- tests/runtime/test_prng.py | 6 +- tests/runtime/test_sessions.py | 8 +- tests/runtime/test_simulation.py | 32 ++--- tests/runtime/test_srv6_diamond.py | 28 ++-- tests/runtime/test_srv6_events.py | 28 ++-- tests/runtime/test_study.py | 30 ++--- tests/runtime/test_study_srv6.py | 8 +- tests/runtime/test_study_windows.py | 24 ++-- tests/runtime/test_timeline.py | 44 +++---- tests/runtime/test_timeline_retention.py | 12 +- tests/runtime/test_transport.py | 14 +- tests/runtime/test_transport_integration.py | 16 +-- tests/runtime/test_transport_review.py | 8 +- tests/runtime/test_usid_diamond.py | 14 +- tests/test_advanced_scenarios.py | 54 ++++---- tests/test_benchmarks.py | 32 ++--- tests/test_condition.py | 52 ++++---- tests/test_container.py | 58 ++++---- tests/test_environment.py | 68 +++++----- tests/test_event.py | 56 ++++---- tests/test_filter_store.py | 14 +- tests/test_fingerprints.py | 4 +- tests/test_integration.py | 28 ++-- tests/test_interrupt.py | 26 ++-- tests/test_invariants.py | 66 +++++----- tests/test_priority_band.py | 14 +- tests/test_priority_resource.py | 40 +++--- tests/test_priority_store.py | 26 ++-- tests/test_process.py | 44 +++---- tests/test_resource.py | 32 ++--- tests/test_scenarios.py | 124 +++++++++--------- tests/test_sorted_queue.py | 2 +- tests/test_store.py | 38 +++--- tests/test_threading.py | 10 +- tests/test_timeout.py | 22 ++-- 152 files changed, 1456 insertions(+), 1424 deletions(-) create mode 100644 docs/history/rename-project-identity.md rename {ngraph_sim => netlab_sim}/__init__.py (74%) create mode 100644 netlab_sim/__main__.py rename {ngraph_sim => netlab_sim}/adapters/__init__.py (100%) rename {ngraph_sim => netlab_sim}/adapters/core.py (93%) rename {ngraph_sim => netlab_sim}/adapters/ngraph.py (93%) rename {ngraph_sim => netlab_sim}/adapters/sonic.py (98%) rename {ngraph_sim => netlab_sim}/agents/__init__.py (65%) rename {ngraph_sim => netlab_sim}/agents/reference.py (99%) rename {ngraph_sim => netlab_sim}/cli.py (87%) rename {ngraph_sim => netlab_sim}/core.py (99%) rename {ngraph_sim => netlab_sim}/exceptions.py (93%) rename {ngraph_sim => netlab_sim}/model/__init__.py (100%) rename {ngraph_sim => netlab_sim}/model/addressing.py (100%) rename {ngraph_sim => netlab_sim}/model/contracts.py (99%) rename {ngraph_sim => netlab_sim}/model/derive.py (98%) rename {ngraph_sim => netlab_sim}/model/entities.py (98%) rename {ngraph_sim => netlab_sim}/model/flows.py (99%) rename {ngraph_sim => netlab_sim}/model/forwarding.py (96%) rename {ngraph_sim => netlab_sim}/model/hashing.py (97%) rename {ngraph_sim => netlab_sim}/model/igp.py (96%) rename {ngraph_sim => netlab_sim}/model/interfaces.py (98%) rename {ngraph_sim => netlab_sim}/model/links.py (98%) rename {ngraph_sim => netlab_sim}/model/lpm.py (100%) rename {ngraph_sim => netlab_sim}/model/network.py (97%) rename {ngraph_sim => netlab_sim}/model/nht.py (97%) rename {ngraph_sim => netlab_sim}/model/packets.py (98%) rename {ngraph_sim => netlab_sim}/model/prng.py (99%) rename {ngraph_sim => netlab_sim}/model/routing.py (99%) rename {ngraph_sim => netlab_sim}/model/srv6.py (98%) rename {ngraph_sim => netlab_sim}/model/srv6_compress.py (97%) rename {ngraph_sim => netlab_sim}/model/state.py (99%) rename {ngraph_sim => netlab_sim}/py.typed (100%) rename {ngraph_sim => netlab_sim}/resources.py (99%) rename {ngraph_sim => netlab_sim}/runtime/__init__.py (70%) rename {ngraph_sim => netlab_sim}/runtime/agents.py (98%) rename {ngraph_sim => netlab_sim}/runtime/channels.py (94%) rename {ngraph_sim => netlab_sim}/runtime/events.py (98%) rename {ngraph_sim => netlab_sim}/runtime/failures.py (98%) rename {ngraph_sim => netlab_sim}/runtime/pipeline.py (99%) rename {ngraph_sim => netlab_sim}/runtime/simulation.py (93%) rename {ngraph_sim => netlab_sim}/runtime/subscriptions.py (97%) rename {ngraph_sim => netlab_sim}/runtime/timeline.py (99%) rename {ngraph_sim => netlab_sim}/runtime/transport.py (99%) rename {ngraph_sim => netlab_sim}/study.py (98%) delete mode 100644 ngraph_sim/__main__.py diff --git a/.superset/workspace.sh b/.superset/workspace.sh index 75a75c0..8deb7ac 100644 --- a/.superset/workspace.sh +++ b/.superset/workspace.sh @@ -16,7 +16,7 @@ unset PYTHONPATH PYTHONHOME if [[ "$mode" == setup ]]; then python -m pip install -e '.[dev]' python -m pip check - python -c 'import ngraph_sim; print("Workspace environment ready")' + python -c 'import netlab_sim; print("Workspace environment ready")' else make check-ci fi diff --git a/Makefile b/Makefile index 4532d03..c70c455 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# NetGraph-Sim Development Makefile +# NetLab-Sim Development Makefile .PHONY: help venv clean-venv dev install check check-ci lint format test qt venv-ft check-ft build clean check-dist publish-test publish info hooks check-python @@ -24,7 +24,7 @@ PRECOMMIT := $(PYTHON) -m pre_commit # Help # -------------------------------------------------------------------------- help: - @echo "NetGraph-Sim Development Commands" + @echo "NetLab-Sim Development Commands" @echo "" @echo "Setup:" @echo " make venv - Create virtual environment (./venv)" @@ -147,7 +147,7 @@ build: @$(PYTHON) -m build clean: - @rm -rf build/ dist/ *.egg-info/ ngraph_sim.egg-info/ + @rm -rf build/ dist/ *.egg-info/ netlab_sim.egg-info/ check-dist: @$(PYTHON) -m twine check dist/* diff --git a/README.md b/README.md index 211102c..0916af1 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# NetGraph-Sim +# NetLab-Sim -[![CI](https://github.com/networmix/NetGraph-Sim/actions/workflows/python-test.yml/badge.svg?branch=main)](https://github.com/networmix/NetGraph-Sim/actions/workflows/python-test.yml) +[![CI](https://github.com/networmix/NetLab-Sim/actions/workflows/python-test.yml/badge.svg?branch=main)](https://github.com/networmix/NetLab-Sim/actions/workflows/python-test.yml) Discrete-event simulation for IP networks. Zero dependencies. Python 3.11+, including free-threaded builds. Two layers: -- `ngraph_sim` is a small SimPy-style engine: an environment, events, +- `netlab_sim` is a small SimPy-style engine: an environment, events, processes and resources. -- `ngraph_sim.model`, `ngraph_sim.runtime`, `ngraph_sim.agents` and - `ngraph_sim.study` model routers with a RIB and a FIB, interfaces and links +- `netlab_sim.model`, `netlab_sim.runtime`, `netlab_sim.agents` and + `netlab_sim.study` model routers with a RIB and a FIB, interfaces and links that fail and recover, static and shortest-path routing with ECMP, SRv6 policies, flow placement with per-link utilization, protocol agents that learn routes by exchanging messages, and failure studies that measure what @@ -19,18 +19,18 @@ Two layers: ## Install ```bash -pip install git+https://github.com/networmix/NetGraph-Sim +pip install git+https://github.com/networmix/NetLab-Sim ``` -The distribution is `ngraph-sim`, part of the NetGraph family (`ngraph`), and -the package imports as `ngraph_sim`. It does not depend on NetGraph. +NetLab-Sim is distributed as `netlab-sim` and imports as `netlab_sim`. +It does not depend on NetGraph. ## Engine ```python -import ngraph_sim +import netlab_sim -env = ngraph_sim.Environment() +env = netlab_sim.Environment() def producer(env, store): for i in range(5): @@ -42,7 +42,7 @@ def consumer(env, store): item = yield store.get() print(f't={env.now}: got {item}') -store = ngraph_sim.Store(env) +store = netlab_sim.Store(env) env.process(producer(env, store)) env.process(consumer(env, store)) env.run() @@ -59,7 +59,7 @@ env.run() | `Container` | Bulk quantities | A process interrupts another with `proc.interrupt(cause)`; the target sees -`ngraph_sim.Interrupt`. Resources are used with +`netlab_sim.Interrupt`. Resources are used with `with resource.request() as req: yield req`. An `Environment` is single-threaded and shares nothing with other environments, so independent simulations run in parallel threads on a free-threaded build. @@ -67,9 +67,9 @@ simulations run in parallel threads on a free-threaded build. ## Network layer ```python -import ngraph_sim -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation net = Network() r1, r2 = net.add_device('R1'), net.add_device('R2') @@ -79,7 +79,7 @@ net.add_p2p(r1, 'eth1', r2, 'eth1', ipv4=('10.1.12.0/31', '10.1.12.1/31'), speed r1.add_route('10.0.0.2/32', [('eth1', '10.1.12.1')]) net.add_demand('d1', 'R1', '10.0.0.2', rate=4e9) -sim = Simulation(ngraph_sim.Environment(), net) # converges at t=0 +sim = Simulation(netlab_sim.Environment(), net) # converges at t=0 sim.at(10, net.links['R1:eth1--R2:eth1'].fail) sim.run_until(20) print(sim.timeline.snapshot_at(10).placement.dropped_by_reason) # PMap({'NO_ROUTE': 4000000000.0}) @@ -97,7 +97,7 @@ traffic is still sent to a dead leg and dropped. `select(kind=EventClass, device=...)`, `interface_series(device, interface)`, `utilization_series(edge)`, `rows()`, `to_csv(path)`. By default it keeps the latest 10,000 records and 100,000 events. -- `net.add_source(oracle_igp)`, from `ngraph_sim.model.igp`, installs +- `net.add_source(oracle_igp)`, from `netlab_sim.model.igp`, installs shortest-path ECMP routes without a protocol. ## Segment routing @@ -109,9 +109,9 @@ H.Encaps.Red at the headend. Placement follows the encapsulated packet hop by hop, so wire load includes the outer headers. ```python -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.igp import oracle_igp +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.igp import oracle_igp net = Network() with net.batch(): @@ -134,7 +134,7 @@ print(r1.node.srv6_policies.states[policy.key].status) # UP Policy state reports validity, the selected path and programming status; `srv6.policy_status(state)` adds the delivery observed in placement. See -`ngraph_sim/model/srv6.py` for the records and `docs/reference.md` for the +`netlab_sim/model/srv6.py` for the records and `docs/reference.md` for the SONiC CONFIG_DB interchange format. ## Protocol agents @@ -147,14 +147,14 @@ round and isolates a rejected output from its peers. Datagrams travel over link channels that honour physical failure; sessions are ordered reliable streams with timeouts. -`ngraph_sim.agents.reference` is a small link-state protocol built on that +`netlab_sim.agents.reference` is a small link-state protocol built on that contract: hello discovery, flooding, SPF, learned SRv6 SIDs. It converges to the same routes as the oracle without reading remote state. ```python -from ngraph_sim.agents.reference import ReferenceAgent, ReferenceConfig -from ngraph_sim.model.addressing import to_network -from ngraph_sim.model.contracts import ClientId +from netlab_sim.agents.reference import ReferenceAgent, ReferenceConfig +from netlab_sim.model.addressing import to_network +from netlab_sim.model.contracts import ClientId net = Network() r1, r2 = net.add_device('R1'), net.add_device('R2') @@ -163,7 +163,7 @@ r2.add_loopback('lo0', ipv4=['10.0.0.2/32']) net.add_p2p(r1, 'eth1', r2, 'eth1', unnumbered=True) for name in ('R1', 'R2'): net.add_agent(name, ReferenceAgent(ReferenceConfig(hello_interval=0.5, hold_time=1.5))) -sim = Simulation(ngraph_sim.Environment(), net) +sim = Simulation(netlab_sim.Environment(), net) sim.run_until(5) print([str(to_network(*row.prefix, 4)) for row in r1.rib(4).rows_of(ClientId('ref'))]) # ['10.0.0.2/32'] ``` @@ -171,8 +171,8 @@ print([str(to_network(*row.prefix, 4)) for row in r1.rib(4).rows_of(ClientId('re ## Failure studies ```python -from ngraph_sim.runtime import Draws, Process -from ngraph_sim.study import Study +from netlab_sim.runtime import Draws, Process +from netlab_sim.study import Study net = Network() r1, r2, r3 = (net.add_device(f'R{i}') for i in (1, 2, 3)) @@ -202,16 +202,16 @@ and the `SimStudy` workflow step reuse NetGraph scenarios, failure policies, seeds and the `results.json` format: ```sh -ngraph-sim run scenario.yaml --results results.json +netlab-sim run scenario.yaml --results results.json ``` ## Adapters -- `ngraph_sim.adapters.ngraph`: NetGraph scenarios and networks in, per-link +- `netlab_sim.adapters.ngraph`: NetGraph scenarios and networks in, per-link utilization and NetGraph-shaped results out. -- `ngraph_sim.adapters.core`: links as NetGraph-Core graph arrays +- `netlab_sim.adapters.core`: links as NetGraph-Core graph arrays (`edge_arrays`, `build_graph`), used to cross-check plain-IP placement. -- `ngraph_sim.adapters.sonic`: SONiC CONFIG_DB load and dump for a bounded +- `netlab_sim.adapters.sonic`: SONiC CONFIG_DB load and dump for a bounded schema. Details of these formats and the study options are in diff --git a/benchmarks/batch.py b/benchmarks/batch.py index 29d0e31..a0d3ffe 100644 --- a/benchmarks/batch.py +++ b/benchmarks/batch.py @@ -24,9 +24,9 @@ from time import perf_counter from typing import Any -from ngraph_sim.model.lpm import FrozenPrefixTable -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import FloatArray, PMap, _is_ignored_field +from netlab_sim.model.lpm import FrozenPrefixTable +from netlab_sim.model.network import Network +from netlab_sim.model.state import FloatArray, PMap, _is_ignored_field def normalized(value: Any) -> Any: @@ -73,7 +73,7 @@ def main() -> None: scenario = None adapter = None if args.workload == 'scenario': - adapter = importlib.import_module('ngraph_sim.adapters.ngraph') + adapter = importlib.import_module('netlab_sim.adapters.ngraph') Scenario = importlib.import_module('ngraph.scenario').Scenario scenario = Scenario.from_yaml(Path(args.scenario).read_text()) timings = [] diff --git a/benchmarks/batch_snapshots.py b/benchmarks/batch_snapshots.py index 01e1370..f4ea323 100644 --- a/benchmarks/batch_snapshots.py +++ b/benchmarks/batch_snapshots.py @@ -16,9 +16,9 @@ from dataclasses import replace from time import perf_counter -from ngraph_sim.model import routing -from ngraph_sim.model.addressing import IPV4 -from ngraph_sim.model.network import Network +from netlab_sim.model import routing +from netlab_sim.model.addressing import IPV4 +from netlab_sim.model.network import Network def main() -> None: diff --git a/benchmarks/pmap_scale.py b/benchmarks/pmap_scale.py index d53b62a..c979ca7 100644 --- a/benchmarks/pmap_scale.py +++ b/benchmarks/pmap_scale.py @@ -43,9 +43,9 @@ def main(): args = parser.parse_args() sys.path.insert(0, os.path.abspath(args.repo)) - from ngraph_sim.model import derive - from ngraph_sim.model.network import Network - from ngraph_sim.model.state import DeviceState, NetworkState, PMap, StateDelta + from netlab_sim.model import derive + from netlab_sim.model.network import Network + from netlab_sim.model.state import DeviceState, NetworkState, PMap, StateDelta if args.shards: PMap._SHARD_COUNT = args.shards diff --git a/benchmarks/s0_prng.py b/benchmarks/s0_prng.py index 6841377..84e663d 100644 --- a/benchmarks/s0_prng.py +++ b/benchmarks/s0_prng.py @@ -21,10 +21,10 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1])) -from ngraph_sim import Environment # noqa: E402 -from ngraph_sim.model import contracts as c # noqa: E402 -from ngraph_sim.model.network import Network # noqa: E402 -from ngraph_sim.runtime import simulation # noqa: E402 +from netlab_sim import Environment # noqa: E402 +from netlab_sim.model import contracts as c # noqa: E402 +from netlab_sim.model.network import Network # noqa: E402 +from netlab_sim.runtime import simulation # noqa: E402 class Ticker: @@ -66,10 +66,10 @@ def main(): args = parser.parse_args() if args.runtime_ref: source = subprocess.check_output( - ['git', 'show', f'{args.runtime_ref}:ngraph_sim/runtime/agents.py'], + ['git', 'show', f'{args.runtime_ref}:netlab_sim/runtime/agents.py'], text=True, ) - module = types.ModuleType('ngraph_sim.runtime._s0_benchmark_agents') + module = types.ModuleType('netlab_sim.runtime._s0_benchmark_agents') sys.modules[module.__name__] = module exec(compile(source, f'{args.runtime_ref}:agents.py', 'exec'), module.__dict__) simulation.AgentRuntime = module.AgentRuntime diff --git a/benchmarks/s0_prng_determinism.json b/benchmarks/s0_prng_determinism.json index 11a9c9a..3389e05 100644 --- a/benchmarks/s0_prng_determinism.json +++ b/benchmarks/s0_prng_determinism.json @@ -1,5 +1,5 @@ { - "script": "\nimport json\nfrom ngraph_sim.model.prng import Prng\nstate = None\noutput = []\nfor run in range(100):\n r = Prng.for_agent(17, -9, 'module:β', 2) if state is None else Prng.restore(state)\n items = list(range(8))\n r.stream('shuffle').shuffle(items)\n output.append([r.random(), r.randrange(-10, 12, 3), r.choice('abc'),\n r.sample(range(30), 4), r.getrandbits(101),\n r.stream('jitter').uniform(1, 5), r.randint(-4, 8), items])\n state = r.getstate()\nprint(json.dumps([output, state], sort_keys=True))\n", + "script": "\nimport json\nfrom netlab_sim.model.prng import Prng\nstate = None\noutput = []\nfor run in range(100):\n r = Prng.for_agent(17, -9, 'module:β', 2) if state is None else Prng.restore(state)\n items = list(range(8))\n r.stream('shuffle').shuffle(items)\n output.append([r.random(), r.randrange(-10, 12, 3), r.choice('abc'),\n r.sample(range(30), 4), r.getrandbits(101),\n r.stream('jitter').uniform(1, 5), r.randint(-4, 8), items])\n state = r.getstate()\nprint(json.dumps([output, state], sort_keys=True))\n", "results": [ { "python": "venv/bin/python", diff --git a/benchmarks/s0_w1_scale.py b/benchmarks/s0_w1_scale.py index ffc3fd3..f49b53e 100644 --- a/benchmarks/s0_w1_scale.py +++ b/benchmarks/s0_w1_scale.py @@ -28,18 +28,18 @@ import tracemalloc from dataclasses import replace -from ngraph_sim.model import network as nw -from ngraph_sim.model import srv6 +from netlab_sim.model import network as nw +from netlab_sim.model import srv6 def load_baseline(revision: str) -> str: commit = subprocess.check_output(['git', 'rev-parse', revision], text=True).strip() source = subprocess.check_output( - ['git', 'show', f'{commit}:ngraph_sim/model/network.py'], text=True + ['git', 'show', f'{commit}:netlab_sim/model/network.py'], text=True ) - exec(compile(source, f'{commit}:ngraph_sim/model/network.py', 'exec'), nw.__dict__) + exec(compile(source, f'{commit}:netlab_sim/model/network.py', 'exec'), nw.__dict__) source = subprocess.check_output( - ['git', 'show', f'{commit}:ngraph_sim/model/srv6.py'], text=True + ['git', 'show', f'{commit}:netlab_sim/model/srv6.py'], text=True ) function = next( node @@ -47,7 +47,7 @@ def load_baseline(revision: str) -> str: if isinstance(node, ast.FunctionDef) and node.name == 'consumer_index' ) module = ast.Module(body=[function], type_ignores=[]) - exec(compile(module, f'{commit}:ngraph_sim/model/srv6.py', 'exec'), srv6.__dict__) + exec(compile(module, f'{commit}:netlab_sim/model/srv6.py', 'exec'), srv6.__dict__) return commit diff --git a/benchmarks/s0_w2_scale.py b/benchmarks/s0_w2_scale.py index ef218ba..d70ad3f 100644 --- a/benchmarks/s0_w2_scale.py +++ b/benchmarks/s0_w2_scale.py @@ -24,7 +24,7 @@ def lookup(): - from ngraph_sim.model.lpm import PrefixTable + from netlab_sim.model.lpm import PrefixTable results = {} for bits in (32, 128): @@ -91,7 +91,7 @@ def batch(call=call, addresses=addresses, method=method): def converge(): import tracemalloc - from ngraph_sim.model.network import Network + from netlab_sim.model.network import Network count = 2000 net = Network(seed=1) @@ -145,11 +145,11 @@ def main(): if args.case: assert args.source is not None sys.path.insert(0, str(args.source)) - # No NetGraph-Sim import is allowed before selecting the source snapshot. + # No NetLab-Sim import is allowed before selecting the source snapshot. data = lookup() if args.case == 'lookup' else converge() - import ngraph_sim + import netlab_sim - print(json.dumps({'source': ngraph_sim.__file__, 'data': data})) + print(json.dumps({'source': netlab_sim.__file__, 'data': data})) return assert args.output is not None, '--output is required for the comparison' repo = Path(__file__).resolve().parents[1] @@ -157,12 +157,12 @@ def main(): ['git', 'rev-parse', args.baseline], cwd=repo, text=True ).strip() archive = subprocess.check_output( - ['git', 'archive', '--format=tar', baseline, 'ngraph_sim'], cwd=repo + ['git', 'archive', '--format=tar', baseline, 'netlab_sim'], cwd=repo ) result: dict[str, object] = {'baseline': baseline, 'python': sys.version} runs = [] result['runs'] = runs - with tempfile.TemporaryDirectory(prefix='ngraph-sim-s0-w2-') as temporary: + with tempfile.TemporaryDirectory(prefix='netlab-sim-s0-w2-') as temporary: old = Path(temporary) with tarfile.open(fileobj=io.BytesIO(archive)) as source: source.extractall(old, filter='data') diff --git a/benchmarks/study_metrics.py b/benchmarks/study_metrics.py index a9c60da..83ff803 100644 --- a/benchmarks/study_metrics.py +++ b/benchmarks/study_metrics.py @@ -19,9 +19,9 @@ import types from dataclasses import replace -from ngraph_sim import Environment -from ngraph_sim.runtime import Schedule, Simulation -from ngraph_sim.study import Study +from netlab_sim import Environment +from netlab_sim.runtime import Schedule, Simulation +from netlab_sim.study import Study from tests.runtime.test_study import two_rate_network @@ -42,11 +42,11 @@ def main() -> None: parser.add_argument('--repeats', type=int, default=20) args = parser.parse_args() source = subprocess.check_output( - ['git', 'show', f'{args.old}:ngraph_sim/study.py'], text=True + ['git', 'show', f'{args.old}:netlab_sim/study.py'], text=True ) old = types.ModuleType('_t6b_old_study') sys.modules[old.__name__] = old - exec(compile(source, f'{args.old}:ngraph_sim/study.py', 'exec'), old.__dict__) + exec(compile(source, f'{args.old}:netlab_sim/study.py', 'exec'), old.__dict__) print( json.dumps( { diff --git a/benchmarks/study_overhead.py b/benchmarks/study_overhead.py index da27bfb..6e5701a 100644 --- a/benchmarks/study_overhead.py +++ b/benchmarks/study_overhead.py @@ -19,9 +19,9 @@ import sys import time -from ngraph_sim import Environment -from ngraph_sim.runtime import Draws, FailureSet, Simulation -from ngraph_sim.study import Study +from netlab_sim import Environment +from netlab_sim.runtime import Draws, FailureSet, Simulation +from netlab_sim.study import Study from tests.model.clos import build_clos diff --git a/benchmarks/t3_rib_index.py b/benchmarks/t3_rib_index.py index be7a1fb..bfd09d5 100644 --- a/benchmarks/t3_rib_index.py +++ b/benchmarks/t3_rib_index.py @@ -24,10 +24,10 @@ def main(): project = Path(__file__).resolve().parents[1] sys.path[:0] = [str(args.source.resolve()), str(project)] - import ngraph_sim - from ngraph_sim.model.addressing import IPV4 - from ngraph_sim.model.contracts import STATIC - from ngraph_sim.model.routing import Nexthop, RibState, Route, rib_apply + import netlab_sim + from netlab_sim.model.addressing import IPV4 + from netlab_sim.model.contracts import STATIC + from netlab_sim.model.routing import Nexthop, RibState, Route, rib_apply from tests.model.test_routing import routing_fingerprints nh = (Nexthop.blackhole(),) @@ -47,7 +47,7 @@ def sync(): 'label': args.label, 'python': platform.python_version(), 'gil': getattr(sys, '_is_gil_enabled', lambda: True)(), - 'source': ngraph_sim.__file__, + 'source': netlab_sim.__file__, } for name, fn in (('lookup_200_ms', lookups), ('sync_10k_ms', sync)): fn() # warm up; all route creation is outside the timed region diff --git a/benchmarks/t3b_rib_updates.py b/benchmarks/t3b_rib_updates.py index 868d198..e0b16b9 100644 --- a/benchmarks/t3b_rib_updates.py +++ b/benchmarks/t3b_rib_updates.py @@ -41,10 +41,10 @@ def main(): args = parser.parse_args() sys.path[:0] = [str(args.source.resolve()), str(project)] - import ngraph_sim - from ngraph_sim.model.addressing import IPV4 - from ngraph_sim.model.contracts import STATIC - from ngraph_sim.model.routing import Nexthop, RibState, Route, rib_apply + import netlab_sim + from netlab_sim.model.addressing import IPV4 + from netlab_sim.model.contracts import STATIC + from netlab_sim.model.routing import Nexthop, RibState, Route, rib_apply from tests.model.test_routing import routing_fingerprints nh = (Nexthop.blackhole(),) @@ -65,7 +65,7 @@ def main(): 'label': args.label, 'python': platform.python_version(), 'gil': getattr(sys, '_is_gil_enabled', lambda: True)(), - 'source': ngraph_sim.__file__, + 'source': netlab_sim.__file__, 'measurements': { name: measure(fn, 1 if name.startswith('sync') else 100) for name, fn in operations.items() diff --git a/benchmarks/verify_converge.py b/benchmarks/verify_converge.py index 43540b0..a7b61e8 100644 --- a/benchmarks/verify_converge.py +++ b/benchmarks/verify_converge.py @@ -2,11 +2,11 @@ import time -import ngraph_sim -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.lpm import PrefixTable -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.lpm import PrefixTable +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation def timed(fn): @@ -50,7 +50,7 @@ def ring(n): t_build, net = timed(lambda n=n: ring(n)) t_init, _ = timed(net.converge) t_noop, _ = timed(net.converge) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() t_sim, sim = timed(lambda env=env, net=net: Simulation(env, net)) lid = sorted(net.links)[3] sim.at(1, net.links[lid].fail) diff --git a/benchmarks/verify_pending.py b/benchmarks/verify_pending.py index 01b2496..b83855f 100644 --- a/benchmarks/verify_pending.py +++ b/benchmarks/verify_pending.py @@ -1,6 +1,6 @@ """Manual deadline benchmark; run old/new/old with the same Python executable. -Save the baseline with ``git show :ngraph_sim/runtime/pipeline.py > /tmp/old.py``. +Save the baseline with ``git show :netlab_sim/runtime/pipeline.py > /tmp/old.py``. Run ``python benchmarks/verify_pending.py --pipeline-source /tmp/old.py``, then without that option, then with it again. Add ``--carrier --repeats 1`` to run the carrier-debounce workload (which also measures derivations, @@ -19,12 +19,12 @@ import sys import time -from ngraph_sim import Environment -from ngraph_sim.model import derive -from ngraph_sim.model.lpm import FrozenPrefixTable -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import FloatArray, PMap -from ngraph_sim.runtime import pipeline, simulation +from netlab_sim import Environment +from netlab_sim.model import derive +from netlab_sim.model.lpm import FrozenPrefixTable +from netlab_sim.model.network import Network +from netlab_sim.model.state import FloatArray, PMap +from netlab_sim.runtime import pipeline, simulation def freeze(value): diff --git a/docs/history/README.md b/docs/history/README.md index de75b94..100eac5 100644 --- a/docs/history/README.md +++ b/docs/history/README.md @@ -8,15 +8,22 @@ disagrees with them, the report is out of date. The project was called NetSim, with the package `netsim`, until 2026-10-02, when it became NetGraph-Sim (`ngraph-sim`, imported as `ngraph_sim`). The -reports keep the old names. Benchmark scripts now import `ngraph_sim`, so a -comparison against a revision from before the rename needs the script from -that revision. +reports keep the old names. On 2026-10-31 the project became NetLab-Sim +(`netlab-sim`, imported as `netlab_sim`). Benchmark scripts now import +`netlab_sim`, so a comparison against a revision from before the rename +needs the script from that revision. Gate A is the plain-IP simulator, Gate B adds SRv6 and Gate C adds protocol agents. The T slices are scale fixes made after Gate A. S0 is scale hygiene before the Open/R and BGP work. Benchmark scripts and raw results are in [`benchmarks/`](../../benchmarks). +## Project identity, 2026-10-31 + +| Report | Topic | +| --- | --- | +| [Rename](rename-project-identity.md) | NetLab-Sim package, distribution and command names | + ## Scale fixes after Gate A, 2026-09-20 | Report | Topic | Note | diff --git a/docs/history/rename-project-identity.md b/docs/history/rename-project-identity.md new file mode 100644 index 0000000..c51c40f --- /dev/null +++ b/docs/history/rename-project-identity.md @@ -0,0 +1,25 @@ +# NetLab-Sim project identity + +NetGraph-Sim becomes NetLab-Sim. The distribution and command change from +`ngraph-sim` to `netlab-sim`; Python imports change from `ngraph_sim` to +`netlab_sim`. The debug variable is `NETLAB_SIM_DEBUG`, and opaque immutable +plugin types declare `__netlab_sim_immutable__`. There are no compatibility +aliases; callers must use the new names. +Pickles referring to `ngraph_sim` cannot load under the new package because +old module aliases are absent. + +Simulation algorithms, result schemas, package version and PRNG sequences +are unchanged. PRNG version-one hash personalizations retain their exact +bytes. Dated reports and raw benchmark provenance retain their historical +names. For comparisons with older revisions, use that revision's scripts. + +Development installs require `pytest>=8,<9.2` for compatibility with +pytest-benchmark 5.3. + +Lint, type checks and tests passed on GIL and free-threaded Python. +Wheel and sdist identities, installed CLI/API entry points, PRNG known +answers and deterministic simulation outputs were verified. No performance +claim is made. + +NetGraph releases without `Scenario.run()` are incompatible with the +optional scenario adapter. diff --git a/docs/reference.md b/docs/reference.md index 6d52360..af87c18 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -87,7 +87,7 @@ It maps nodes to devices with loopbacks, links to Ethernets (parallel links tagged `lag` to a PortChannel), costs to metrics and the demand set to demands. `pairwise` demands split the volume over the pairs; `combine` demands become one anycast prefix. NetGraph priorities (lower first) map to -NetGraph-Sim priorities (higher first). The failure policy becomes a +NetLab-Sim priorities (higher first). The failure policy becomes a `FailureSchedule` only when `iterations > 0`; for studies, use `Draws.from_policy`. With `srv6=True` every device gets an F3216 locator, uN and uDT46, every L3 link end a uA, and a pairwise demand with one explicit @@ -111,7 +111,7 @@ Per-entity settings are read only from the `attrs.sim` mapping: Entities that set both `mtbf` and `mttr` form `Study.failure_parameters`, the renewal process of the `SimStudy` process mode. -Importing `ngraph_sim.adapters.ngraph` registers the `SimStudy` workflow step: +Importing `netlab_sim.adapters.ngraph` registers the `SimStudy` workflow step: ```yaml workflow: @@ -127,7 +127,7 @@ workflow: keep: {roots: 0, deltas: 0, arrays: false, timeline: false} ``` -`ngraph-sim run scenario.yaml --results results.json` runs the scenario with +`netlab-sim run scenario.yaml --results results.json` runs the scenario with NetGraph and writes the complete results. ## SONiC adapter diff --git a/ngraph_sim/__init__.py b/netlab_sim/__init__.py similarity index 74% rename from ngraph_sim/__init__.py rename to netlab_sim/__init__.py index 0659d21..602f55a 100644 --- a/ngraph_sim/__init__.py +++ b/netlab_sim/__init__.py @@ -1,10 +1,10 @@ -"""NetGraph-Sim: a discrete-event simulation engine with a network layer. +"""NetLab-Sim: a discrete-event simulation engine with a network layer. The engine (``Environment``, ``Event``, ``Process``, resources) lives here; -the network model is ``ngraph_sim.model`` and its clock binding ``ngraph_sim.runtime``. +the network model is ``netlab_sim.model`` and its clock binding ``netlab_sim.runtime``. """ -from ngraph_sim.core import ( +from netlab_sim.core import ( DEFERRED, NORMAL, URGENT, @@ -18,8 +18,8 @@ Process, Timeout, ) -from ngraph_sim.exceptions import EmptySchedule, Interrupt -from ngraph_sim.resources import ( +from netlab_sim.exceptions import EmptySchedule, Interrupt +from netlab_sim.resources import ( BaseResource, Container, FilterStore, diff --git a/netlab_sim/__main__.py b/netlab_sim/__main__.py new file mode 100644 index 0000000..69f7ef1 --- /dev/null +++ b/netlab_sim/__main__.py @@ -0,0 +1,3 @@ +from netlab_sim.cli import main + +raise SystemExit(main()) diff --git a/ngraph_sim/adapters/__init__.py b/netlab_sim/adapters/__init__.py similarity index 100% rename from ngraph_sim/adapters/__init__.py rename to netlab_sim/adapters/__init__.py diff --git a/ngraph_sim/adapters/core.py b/netlab_sim/adapters/core.py similarity index 93% rename from ngraph_sim/adapters/core.py rename to netlab_sim/adapters/core.py index fe89aaf..c113a6a 100644 --- a/ngraph_sim/adapters/core.py +++ b/netlab_sim/adapters/core.py @@ -6,10 +6,10 @@ from typing import Any -from ngraph_sim.model import derive -from ngraph_sim.model.interfaces import OperState, l3_usable -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import NetworkState +from netlab_sim.model import derive +from netlab_sim.model.interfaces import OperState, l3_usable +from netlab_sim.model.network import Network +from netlab_sim.model.state import NetworkState def edge_arrays( diff --git a/ngraph_sim/adapters/ngraph.py b/netlab_sim/adapters/ngraph.py similarity index 93% rename from ngraph_sim/adapters/ngraph.py rename to netlab_sim/adapters/ngraph.py index b460f58..ae2d9f7 100644 --- a/ngraph_sim/adapters/ngraph.py +++ b/netlab_sim/adapters/ngraph.py @@ -18,13 +18,13 @@ from dataclasses import dataclass from typing import Any, Callable, Iterable -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.flows import PlacementReport -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import check_name -from ngraph_sim.runtime.failures import Draws, FaultEvent, Schedule, resolve_groups +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.flows import PlacementReport +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.model.state import check_name +from netlab_sim.runtime.failures import Draws, FaultEvent, Schedule, resolve_groups DEFAULT_LOOPBACK_POOL = '10.255.0.0/16' DEFAULT_LINK_POOL = '10.0.0.0/8' @@ -82,7 +82,7 @@ def _device_name(node_name: str) -> str: def _link_ids(net: Network) -> dict[str, str]: - """NetGraph link id → NetGraph-Sim link id (recorded at import).""" + """NetGraph link id → NetLab-Sim link id (recorded at import).""" return getattr(net, 'ngraph_link_ids', {}) @@ -97,7 +97,7 @@ def __init__( class _MetadataGuard: - """Restore the adapter's ``ngraph_sim_*`` attributes if an import aborts, so + """Restore the adapter's ``netlab_sim_*`` attributes if an import aborts, so exported labels never disagree with the committed tree.""" def __init__(self, net: Network) -> None: @@ -106,7 +106,7 @@ def __init__(self, net: Network) -> None: self.saved = { k: copy.deepcopy(v) for k, v in vars(net).items() - if k.startswith('ngraph_sim_') + if k.startswith('netlab_sim_') } def __enter__(self) -> _MetadataGuard: @@ -117,7 +117,7 @@ def __exit__(self, exc_type: Any, exc: Any, tb: Any) -> None: # tree in place; the metadata must then describe that tree, so only # a failure before publication (root unchanged) rolls it back. if exc_type is not None and self.net.state is self.root: - for k in [k for k in vars(self.net) if k.startswith('ngraph_sim_')]: + for k in [k for k in vars(self.net) if k.startswith('netlab_sim_')]: delattr(self.net, k) for k, v in self.saved.items(): setattr(self.net, k, v) @@ -133,7 +133,7 @@ def from_network( pools: dict[str, str] | None = None, seed: int = 0, ) -> Network: - """Build a NetGraph-Sim ``Network`` from a NetGraph ``Network``.""" + """Build a NetLab-Sim ``Network`` from a NetGraph ``Network``.""" net = Network(seed=seed) with _MetadataGuard(net), net.batch(): _populate_network( @@ -171,10 +171,10 @@ def _populate_network( failure_parameters: dict[tuple[str, str], dict[str, Any]] = {} # Adapter metadata is outside the immutable forwarding tree. Study copies # it before forking, so no model-layer dependency on this adapter is needed. - net.ngraph_sim_capacity_unit = capacity_unit # type: ignore[attr-defined] - net.ngraph_sim_demand_destinations = {} # type: ignore[attr-defined] - net.ngraph_sim_demand_priorities = {} # type: ignore[attr-defined] - net.ngraph_sim_failure_parameters = failure_parameters # type: ignore[attr-defined] + net.netlab_sim_capacity_unit = capacity_unit # type: ignore[attr-defined] + net.netlab_sim_demand_destinations = {} # type: ignore[attr-defined] + net.netlab_sim_demand_priorities = {} # type: ignore[attr-defined] + net.netlab_sim_failure_parameters = failure_parameters # type: ignore[attr-defined] for name in sorted(network.nodes): node = network.nodes[name] check_name(name, allow_slash=True) @@ -222,7 +222,7 @@ def _populate_network( ) for i, link in enumerate(links): nid = f'{src}:{members_a[i]}--{dst}:{members_b[i]}' - from ngraph_sim.model.links import link_id + from netlab_sim.model.links import link_id net.ngraph_link_ids[link.id] = link_id( (src, members_a[i]), (dst, members_b[i]) @@ -268,13 +268,13 @@ def group_members(group: Any, visiting: set[str]) -> None: for _, group in sorted(getattr(network, 'risk_groups', {}).items()): group_members(group, set()) - net.ngraph_sim_risk_groups = resolve_groups(groups) # type: ignore[attr-defined] + net.netlab_sim_risk_groups = resolve_groups(groups) # type: ignore[attr-defined] if igp: net.add_source(oracle_igp) def _settings(entity: Any) -> dict[str, Any]: - """The NetGraph-Sim settings of a NetGraph entity: its ``attrs.sim`` mapping.""" + """The NetLab-Sim settings of a NetGraph entity: its ``attrs.sim`` mapping.""" return dict((getattr(entity, 'attrs', None) or {}).get('sim') or {}) @@ -354,7 +354,7 @@ def demands_from( *, capacity_unit: float = 1e9, ) -> list[str]: - """Expand NetGraph ``TrafficDemand`` entries into NetGraph-Sim demands. + """Expand NetGraph ``TrafficDemand`` entries into NetLab-Sim demands. Destinations are loopback addresses. """ @@ -365,7 +365,7 @@ def demands_from( SUPPORTED_FLOW_POLICIES = frozenset( {'SHORTEST_PATHS_ECMP', 'SHORTEST_PATHS_ECMP_LOSSY', 1, 6} ) -"""NetGraph presets whose forwarding NetGraph-Sim reproduces (hop-by-hop ECMP over +"""NetGraph presets whose forwarding NetLab-Sim reproduces (hop-by-hop ECMP over the oracle IGP; the lossy variant maps to the LOSSY capacity model).""" @@ -407,7 +407,7 @@ def _populate_demands( to one anycast prefix announced by all targets (the nearest target wins, as with NetGraph's pseudo sink), targets that are also sources are excluded. Known approximation: NetGraph re-splits a combined volume over - the sources that can reach a target in each iteration, NetGraph-Sim keeps each + the sources that can reach a target in each iteration, NetLab-Sim keeps each source's share fixed (a cut-off source drops its share). Unsupported options raise. With srv6=True, one explicit pairwise path becomes a DROP-fallback SR policy. TE admission semantics, group modes @@ -420,12 +420,12 @@ def _populate_demands( _check_supported( td, f'{set_name}[{i}]', - srv6=bool(getattr(net, 'ngraph_sim_srv6', False)), + srv6=bool(getattr(net, 'netlab_sim_srv6', False)), ) sources = _match(network, td.source) targets = _match(network, td.target) if getattr(td, 'static_paths', ()) and getattr( - net, 'ngraph_sim_srv6', False + net, 'netlab_sim_srv6', False ): ids.append( _pinned_demand( @@ -433,13 +433,13 @@ def _populate_demands( ) ) continue - # NetGraph: lower priority numbers are served first; NetGraph-Sim + # NetGraph: lower priority numbers are served first; NetLab-Sim # serves higher numbers first, so the sign flips here and the # original value is kept for exported results. ng_priority = int(getattr(td, 'priority', 0)) mode = str(getattr(td, 'mode', 'combine')).lower() - destinations = getattr(net, 'ngraph_sim_demand_destinations', None) - priorities = getattr(net, 'ngraph_sim_demand_priorities', None) + destinations = getattr(net, 'netlab_sim_demand_destinations', None) + priorities = getattr(net, 'netlab_sim_demand_priorities', None) if mode == 'pairwise': # ``pairwise``: the volume is split evenly over the pairs. pairs = [(s, t) for s in sources for t in targets if s != t] @@ -505,7 +505,7 @@ def _allocate_srv6(net: Network, seed: int) -> None: dev.add_local_sid( sr.END_X, structure=sr.F3216_LIB, flavors=sr.NEXT_CSID, interface=iface ) - net.ngraph_sim_srv6 = True # type: ignore[attr-defined] + net.netlab_sim_srv6 = True # type: ignore[attr-defined] def _path_interfaces( @@ -658,8 +658,8 @@ def _pinned_demand( tag=set_name, steer=sr.PolicyRef(color, endpoint), ) - net.ngraph_sim_demand_destinations[did] = target # type: ignore[attr-defined] - net.ngraph_sim_demand_priorities[did] = priority # type: ignore[attr-defined] + net.netlab_sim_demand_destinations[did] = target # type: ignore[attr-defined] + net.netlab_sim_demand_priorities[did] = priority # type: ignore[attr-defined] return did @@ -670,7 +670,7 @@ def _used_ipv4(net: Network) -> set[int]: for node in dev.interfaces.values(): for host, _plen in getattr(node.config, 'ipv4', ()) or (): out.add(host) - for address, _targets in (getattr(net, 'ngraph_sim_anycast', None) or {}).values(): + for address, _targets in (getattr(net, 'netlab_sim_anycast', None) or {}).values(): out.add(int(ipaddress.IPv4Address(address))) return out @@ -680,13 +680,13 @@ def _anycast(net: Network, key: str, targets: list[str], used: set[int]) -> str: address the tree already uses, and announce it on each target's ``lo0``. The allocation cursor lives in the adapter metadata (copied by ``Network.fork``), so a fork never re-issues an address of its base.""" - table = getattr(net, 'ngraph_sim_anycast', None) + table = getattr(net, 'netlab_sim_anycast', None) if table is None: - table = net.ngraph_sim_anycast = {} # type: ignore[attr-defined] + table = net.netlab_sim_anycast = {} # type: ignore[attr-defined] pool = ipaddress.ip_network( - getattr(net, 'ngraph_sim_anycast_pool', DEFAULT_ANYCAST_POOL) + getattr(net, 'netlab_sim_anycast_pool', DEFAULT_ANYCAST_POOL) ) - cursor = int(getattr(net, 'ngraph_sim_anycast_cursor', 0)) + cursor = int(getattr(net, 'netlab_sim_anycast_cursor', 0)) hosts = pool.num_addresses - 2 address = None while cursor < hosts: @@ -695,7 +695,7 @@ def _anycast(net: Network, key: str, targets: list[str], used: set[int]) -> str: if candidate not in used: address = candidate break - net.ngraph_sim_anycast_cursor = cursor # type: ignore[attr-defined] + net.netlab_sim_anycast_cursor = cursor # type: ignore[attr-defined] if address is None: raise ValueError(f'anycast pool {pool} exhausted while importing {key}') used.add(address) @@ -811,7 +811,7 @@ def to_network( attrs={'sim': {'loopback_ipv4': _loopback_v4(net, name)}}, ) ) - from ngraph_sim.model import derive + from netlab_sim.model import derive for lid, link in sorted(state.links.items(), key=lambda kv: kv[1].index): a, b = link.a, link.b @@ -903,7 +903,7 @@ def results_json( @dataclass class SimStudy(_workflow.WorkflowStep): - """NetGraph workflow entry point for serial NetGraph-Sim studies.""" + """NetGraph workflow entry point for serial NetLab-Sim studies.""" demand_set: str | None = None failure_policy: str | None = None @@ -932,8 +932,8 @@ class SimStudy(_workflow.WorkflowStep): seed: int | None = None def run(self, scenario: Any) -> None: - from ngraph_sim.runtime.failures import Process - from ngraph_sim.study import Study + from netlab_sim.runtime.failures import Process + from netlab_sim.study import Study study = Study.from_scenario( scenario, diff --git a/ngraph_sim/adapters/sonic.py b/netlab_sim/adapters/sonic.py similarity index 98% rename from ngraph_sim/adapters/sonic.py rename to netlab_sim/adapters/sonic.py index f62b27f..2b6a270 100644 --- a/ngraph_sim/adapters/sonic.py +++ b/netlab_sim/adapters/sonic.py @@ -2,7 +2,7 @@ Envelope: {"version": 1, "devices": {hostname: {table: {key: fields}}}}. The static locator/My-SID vocabulary follows SONiC's srv6_static_config_hld; -SRV6_POLICY candidate_paths and explicit per-SID lengths are NetGraph-Sim extensions. +SRV6_POLICY candidate_paths and explicit per-SID lengths are NetLab-Sim extensions. Only the default table and pipe decapsulation are modeled. See ``docs/reference.md`` for the complete subset. Unknown fields are errors, never silently discarded. """ @@ -17,13 +17,13 @@ from pathlib import Path from typing import Any, Iterator -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.addressing import AddressFamily, to_address -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.interfaces import AdminState, EthernetNode, LoopbackNode -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import BLACKHOLE -from ngraph_sim.model.srv6_compress import compress +from netlab_sim.model import srv6 as sr +from netlab_sim.model.addressing import AddressFamily, to_address +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.interfaces import AdminState, EthernetNode, LoopbackNode +from netlab_sim.model.network import Network +from netlab_sim.model.routing import BLACKHOLE +from netlab_sim.model.srv6_compress import compress class SchemaError(ValueError): @@ -189,7 +189,7 @@ def load(source: Mapping[str, Any] | str | Path) -> Network: devices = _object(root['devices'], '$.devices') net = Network() meta: dict[str, Any] = {'source': document, 'sid_keys': {}, 'lists': {}} - net.ngraph_sim_sonic = meta # type: ignore[attr-defined] + net.netlab_sim_sonic = meta # type: ignore[attr-defined] with net.batch(): for name, tables in sorted(devices.items()): where = f'$.devices.{name}' @@ -542,7 +542,7 @@ def dump(net: Network, destination: str | Path | None = None) -> dict[str, Any]: configuration raises instead of producing a misleading partial export. """ current = _encode(net) - meta = getattr(net, 'ngraph_sim_sonic', {}) + meta = getattr(net, 'netlab_sim_sonic', {}) if 'canonical' in meta: current = _restore(current, meta['canonical'], meta['source']) if destination is not None: @@ -552,7 +552,7 @@ def dump(net: Network, destination: str | Path | None = None) -> dict[str, Any]: def _encode(net: Network) -> dict[str, Any]: devices: dict[str, Any] = {} - meta = getattr(net, 'ngraph_sim_sonic', {}) + meta = getattr(net, 'netlab_sim_sonic', {}) for name, dev in net.state.devices.sorted_items(): # Version 1 has no table for these forwarding-relevant device settings. # Check the live tree before restoring source spelling or writing a file. diff --git a/ngraph_sim/agents/__init__.py b/netlab_sim/agents/__init__.py similarity index 65% rename from ngraph_sim/agents/__init__.py rename to netlab_sim/agents/__init__.py index 5859595..64fa46d 100644 --- a/ngraph_sim/agents/__init__.py +++ b/netlab_sim/agents/__init__.py @@ -1,5 +1,5 @@ """Local protocol plugins; no oracle or model-root access.""" -from ngraph_sim.agents.reference import ReferenceAgent, ReferenceConfig +from netlab_sim.agents.reference import ReferenceAgent, ReferenceConfig __all__ = ['ReferenceAgent', 'ReferenceConfig'] diff --git a/ngraph_sim/agents/reference.py b/netlab_sim/agents/reference.py similarity index 99% rename from ngraph_sim/agents/reference.py rename to netlab_sim/agents/reference.py index 1935fef..f6dd9fb 100644 --- a/ngraph_sim/agents/reference.py +++ b/netlab_sim/agents/reference.py @@ -42,10 +42,10 @@ from dataclasses import dataclass, field, replace from typing import Any -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import is_link_local_v6, mask_for -from ngraph_sim.model.routing import Nexthop, Route -from ngraph_sim.model.state import PMap, empty_pmap +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import is_link_local_v6, mask_for +from netlab_sim.model.routing import Nexthop, Route +from netlab_sim.model.state import PMap, empty_pmap @dataclass(frozen=True, slots=True) diff --git a/ngraph_sim/cli.py b/netlab_sim/cli.py similarity index 87% rename from ngraph_sim/cli.py rename to netlab_sim/cli.py index 2dc5d85..63807f4 100644 --- a/ngraph_sim/cli.py +++ b/netlab_sim/cli.py @@ -10,7 +10,7 @@ def main(argv: Sequence[str] | None = None) -> int: - parser = argparse.ArgumentParser(prog='ngraph-sim') + parser = argparse.ArgumentParser(prog='netlab-sim') commands = parser.add_subparsers(dest='command', required=True) run = commands.add_parser('run', help='run a NetGraph scenario with SimStudy steps') run.add_argument('scenario', type=Path) @@ -21,9 +21,9 @@ def main(argv: Sequence[str] | None = None) -> int: except ModuleNotFoundError as exc: if exc.name != 'ngraph': raise - parser.error('ngraph-sim run requires the optional ngraph package') + parser.error('netlab-sim run requires the optional ngraph package') importlib.import_module( - 'ngraph_sim.adapters.ngraph' + 'netlab_sim.adapters.ngraph' ) # Register before YAML parsing. scenario = scenario_module.Scenario.from_yaml(args.scenario.read_text()) scenario.run() diff --git a/ngraph_sim/core.py b/netlab_sim/core.py similarity index 99% rename from ngraph_sim/core.py rename to netlab_sim/core.py index 8050ba5..0d3ba0c 100644 --- a/ngraph_sim/core.py +++ b/netlab_sim/core.py @@ -9,7 +9,7 @@ from itertools import count from typing import Any, Callable, Generator, Iterable, Iterator -from ngraph_sim.exceptions import EmptySchedule, Interrupt +from netlab_sim.exceptions import EmptySchedule, Interrupt # --------------------------------------------------------------------------- # Constants diff --git a/ngraph_sim/exceptions.py b/netlab_sim/exceptions.py similarity index 93% rename from ngraph_sim/exceptions.py rename to netlab_sim/exceptions.py index 8dc7afa..bd25c6a 100644 --- a/ngraph_sim/exceptions.py +++ b/netlab_sim/exceptions.py @@ -1,4 +1,4 @@ -"""Exceptions raised by ``ngraph_sim``.""" +"""Exceptions raised by ``netlab_sim``.""" from __future__ import annotations diff --git a/ngraph_sim/model/__init__.py b/netlab_sim/model/__init__.py similarity index 100% rename from ngraph_sim/model/__init__.py rename to netlab_sim/model/__init__.py diff --git a/ngraph_sim/model/addressing.py b/netlab_sim/model/addressing.py similarity index 100% rename from ngraph_sim/model/addressing.py rename to netlab_sim/model/addressing.py diff --git a/ngraph_sim/model/contracts.py b/netlab_sim/model/contracts.py similarity index 99% rename from ngraph_sim/model/contracts.py rename to netlab_sim/model/contracts.py index 5e48228..d21515b 100644 --- a/ngraph_sim/model/contracts.py +++ b/netlab_sim/model/contracts.py @@ -10,7 +10,7 @@ records it returns (``AgentOutput`` and its operation records) and the records the tree keeps about it (``AgentNode``, ``RunReceipt``, NHT and transport state). Everything here is clock-free and immutable; the runtime -(``ngraph_sim.runtime.agents``, ``ngraph_sim.runtime.transport``) owns inboxes, +(``netlab_sim.runtime.agents``, ``netlab_sim.runtime.transport``) owns inboxes, timers, queues and publication. Contract rules (tested in ``tests/model/test_agent_contract.py``): @@ -33,7 +33,7 @@ from dataclasses import field from typing import Any, Protocol, runtime_checkable -from ngraph_sim.model.state import PMap, empty_pmap, record, validate_immutable +from netlab_sim.model.state import PMap, empty_pmap, record, validate_immutable @record @@ -945,7 +945,7 @@ def causes(self) -> tuple[Cause, ...]: ... @property def rng(self) -> Any: - """The agent's ``ngraph_sim.model.prng.Prng`` for this invocation. + """The agent's ``netlab_sim.model.prng.Prng`` for this invocation. The family key comes from (network seed, device seed, agent name, generation) at the generation's first publication. Seed edits after diff --git a/ngraph_sim/model/derive.py b/netlab_sim/model/derive.py similarity index 98% rename from ngraph_sim/model/derive.py rename to netlab_sim/model/derive.py index 8a6e567..ce866bb 100644 --- a/ngraph_sim/model/derive.py +++ b/netlab_sim/model/derive.py @@ -11,17 +11,17 @@ import dataclasses from typing import Callable, Iterable -from ngraph_sim.model import srv6 -from ngraph_sim.model.addressing import IPV4, IPV6, MacAddress -from ngraph_sim.model.contracts import ( +from netlab_sim.model import srv6 +from netlab_sim.model.addressing import IPV4, IPV6, MacAddress +from netlab_sim.model.contracts import ( CONNECTED, CONNECTED_PROFILE, LOCAL, LOCAL_PROFILE, SRV6_LOCAL, ) -from ngraph_sim.model.forwarding import Fib, NeighborTable -from ngraph_sim.model.interfaces import ( +from netlab_sim.model.forwarding import Fib, NeighborTable +from netlab_sim.model.interfaces import ( AdminState, BundleInput, EthernetNode, @@ -36,8 +36,8 @@ has_global_address, l3_usable, ) -from ngraph_sim.model.links import LinkNode -from ngraph_sim.model.routing import ( +from netlab_sim.model.links import LinkNode +from netlab_sim.model.routing import ( SRV6_LOCAL_NH, UNREACHABLE, Nexthop, @@ -47,7 +47,7 @@ resolve_fib, rib_apply, ) -from ngraph_sim.model.state import ( +from netlab_sim.model.state import ( DeviceOper, DeviceState, NetworkState, @@ -236,7 +236,7 @@ def derive_carrier( def _raw(link, peer_cfg, peer_enabled): - from ngraph_sim.model.interfaces import raw_carrier + from netlab_sim.model.interfaces import raw_carrier return raw_carrier(link.oper if link else None, peer_cfg, peer_enabled) @@ -344,7 +344,7 @@ def _bits(af: int) -> int: def _connected_rows( dev: DeviceState, af: int, names: Iterable[str] ) -> tuple[Route, ...]: - from ngraph_sim.model.addressing import mask_for + from netlab_sim.model.addressing import mask_for rows: list[Route] = [] bits = _bits(af) @@ -402,7 +402,7 @@ class L3Interface: def _interface_neighbors( state: NetworkState, device: str, name: str ) -> tuple[tuple[tuple[int, int], ...], int | None]: - from ngraph_sim.model.addressing import mask_for + from netlab_sim.model.addressing import mask_for dev = state.devices[device] node = dev.interfaces[name] @@ -732,7 +732,7 @@ def rib(self, af: int) -> RibState: def derive_fib( state: NetworkState, targets: Iterable[tuple[str, int]] | None = None ) -> NetworkState: - from ngraph_sim.model import nht + from netlab_sim.model import nht if targets is None: targets = [(d, af) for d, _ in state.devices.sorted_items() for af in AFS] @@ -904,7 +904,7 @@ def bump_epochs(old: NetworkState, new: NetworkState) -> NetworkState: # NHT observes RIB inputs immediately even when FIB programming is delayed. # A change confined to nht never enters all_changed/any_rib_changed above. if refresh_nht: - from ngraph_sim.model import nht + from netlab_sim.model import nht for name in refresh_nht: result = nht.refresh(result, name) diff --git a/ngraph_sim/model/entities.py b/netlab_sim/model/entities.py similarity index 98% rename from ngraph_sim/model/entities.py rename to netlab_sim/model/entities.py index d0b160e..838b750 100644 --- a/ngraph_sim/model/entities.py +++ b/netlab_sim/model/entities.py @@ -7,8 +7,8 @@ import dataclasses from typing import TYPE_CHECKING, Any, Iterable -from ngraph_sim.model import nht, srv6 -from ngraph_sim.model.addressing import ( +from netlab_sim.model import nht, srv6 +from netlab_sim.model.addressing import ( IPV4, IPV6, AddressFamily, @@ -16,7 +16,7 @@ prefix_to_int, to_int, ) -from ngraph_sim.model.contracts import ( +from netlab_sim.model.contracts import ( STATIC, STATIC_PROFILE, ClientId, @@ -24,8 +24,8 @@ NhtKey, NhtResult, ) -from ngraph_sim.model.forwarding import Fib -from ngraph_sim.model.interfaces import ( +from netlab_sim.model.forwarding import Fib +from netlab_sim.model.interfaces import ( AdminState, EthernetConfig, EthernetNode, @@ -35,8 +35,8 @@ PortChannelNode, l3_usable, ) -from ngraph_sim.model.links import LINK_FAILED, LINK_UP, LinkNode, LinkOper -from ngraph_sim.model.routing import ( +from netlab_sim.model.links import LINK_FAILED, LINK_UP, LinkNode, LinkOper +from netlab_sim.model.routing import ( BLACKHOLE, PROHIBIT, RECEIVE_NH, @@ -48,10 +48,10 @@ rib_apply, row_status, ) -from ngraph_sim.model.state import DeviceState, NetworkState +from netlab_sim.model.state import DeviceState, NetworkState if TYPE_CHECKING: - from ngraph_sim.model.network import Network, _Edits + from netlab_sim.model.network import Network, _Edits class StaleHandleError(LookupError): @@ -631,7 +631,7 @@ def resolve( ctx: nht.LocalContext | None = None, ) -> NhtResult: """Query a detached snapshot, or capture the device's current local inputs.""" - from ngraph_sim.model.routing import ResolutionPolicy + from netlab_sim.model.routing import ResolutionPolicy self._check(key) ctx = ctx if ctx is not None else nht.local_context(self.device.node) diff --git a/ngraph_sim/model/flows.py b/netlab_sim/model/flows.py similarity index 99% rename from ngraph_sim/model/flows.py rename to netlab_sim/model/flows.py index 776669e..e8923d9 100644 --- a/ngraph_sim/model/flows.py +++ b/netlab_sim/model/flows.py @@ -20,18 +20,18 @@ from fractions import Fraction from typing import Any, Iterator, NamedTuple, Protocol -from ngraph_sim.model import derive -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import IPV4, IPV6, to_int -from ngraph_sim.model.hashing import BalancerKind -from ngraph_sim.model.interfaces import ( +from netlab_sim.model import derive +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import IPV4, IPV6, to_int +from netlab_sim.model.hashing import BalancerKind +from netlab_sim.model.interfaces import ( AdminState, OperState, PortChannelNode, l3_usable, ) -from ngraph_sim.model.links import transfer_blocked -from ngraph_sim.model.packets import ( +from netlab_sim.model.links import transfer_blocked +from netlab_sim.model.packets import ( AFTER_DECAP, AFTER_ENCAP, ETHERNET_HEADER, @@ -52,8 +52,8 @@ frame_bytes, ip_bytes, ) -from ngraph_sim.model.srv6 import NESTED_ENCAP_UNSUPPORTED, PolicyRef -from ngraph_sim.model.state import ( +from netlab_sim.model.srv6 import NESTED_ENCAP_UNSUPPORTED, PolicyRef +from netlab_sim.model.state import ( FloatArray, NetworkState, PMap, @@ -525,7 +525,7 @@ def _forward_edges( Selection is pure: each branch replays a finite prefix of choices. TTL is intentionally absent from FLUID identity; the walk cuts cycles by SCC. """ - from ngraph_sim.model.network import _View + from netlab_sim.model.network import _View if packet_state.wire: af, dst = packet_state.wire[0], packet_state.wire[2] @@ -1115,7 +1115,7 @@ def walk_hash( def _source_address(state: NetworkState, device: str, af: int) -> int: - from ngraph_sim.model.interfaces import LoopbackNode + from netlab_sim.model.interfaces import LoopbackNode dev = state.devices[device] for node in dev.interfaces.values(): @@ -1187,7 +1187,7 @@ def derive_placement( delivered_total = 0.0 demands = sorted(state.demands.values(), key=lambda d: (-d.priority, d.id)) if views is None: - from ngraph_sim.model.network import _View + from netlab_sim.model.network import _View def _default_views(d: str) -> Any: return _View(state, d) diff --git a/ngraph_sim/model/forwarding.py b/netlab_sim/model/forwarding.py similarity index 96% rename from ngraph_sim/model/forwarding.py rename to netlab_sim/model/forwarding.py index 8f7db78..e78f343 100644 --- a/ngraph_sim/model/forwarding.py +++ b/netlab_sim/model/forwarding.py @@ -5,12 +5,12 @@ from dataclasses import field from typing import Any, Callable -from ngraph_sim.model.links import ( # noqa: F401 (re-exported drop reasons) +from netlab_sim.model.links import ( # noqa: F401 (re-exported drop reasons) LINK_DOWN, RX_DOWN, ) -from ngraph_sim.model.lpm import FrozenPrefixTable -from ngraph_sim.model.state import PMap, empty_pmap, record +from netlab_sim.model.lpm import FrozenPrefixTable +from netlab_sim.model.state import PMap, empty_pmap, record # FIB actions FORWARD = 1 @@ -139,12 +139,12 @@ def peer_mac(self, interface: str) -> int | None: from typing import Protocol # noqa: E402 -from ngraph_sim.model.hashing import ( # noqa: E402 +from netlab_sim.model.hashing import ( # noqa: E402 BalancerKind, LoadBalancer, flow_label_for, ) -from ngraph_sim.model.packets import ( # noqa: E402 +from netlab_sim.model.packets import ( # noqa: E402 AFTER_DECAP, AFTER_ENCAP, ETHERTYPE_IPV4, @@ -167,7 +167,7 @@ def peer_mac(self, interface: str) -> int | None: DROP = 'DROP' SRV6_UNSUPPORTED = 'SRV6_UNSUPPORTED' -from ngraph_sim.model.srv6 import ( # noqa: E402 +from netlab_sim.model.srv6 import ( # noqa: E402 END, END_DT46, END_X, @@ -183,7 +183,7 @@ def peer_mac(self, interface: str) -> int | None: PolicyRef, Srv6Encap, ) -from ngraph_sim.model.srv6_compress import csid_arg, shift_csid # noqa: E402 +from netlab_sim.model.srv6_compress import csid_arg, shift_csid # noqa: E402 RELOOKUP = 'RELOOKUP' CROSS_CONNECT = 'CROSS_CONNECT' @@ -317,7 +317,7 @@ def steering_policy(view: DeviceView, packet: IPPacket) -> PolicyRef | None: packet.payload, (IPv4Packet, IPv6Packet) ): return None - from ngraph_sim.model.addressing import mask_for + from netlab_sim.model.addressing import mask_for fib = view.fib(6) af = 4 if isinstance(packet, IPv4Packet) else 6 @@ -387,7 +387,7 @@ def srv6_settings(view: DeviceView, encap: Srv6Encap) -> tuple[int | None, int, G1's _View owns ``dev`` and ``state``. Keeping this adapter here avoids editing network.py while the other slice extends its view API. """ - from ngraph_sim.model.interfaces import LoopbackNode + from netlab_sim.model.interfaces import LoopbackNode dev = getattr(view, 'dev', None) config = getattr(dev, 'config', None) @@ -422,7 +422,7 @@ def _bind_adjacency(view: DeviceView, adj: Adjacency) -> Adjacency: def _l3_usable(node: Any, af: int) -> bool: - from ngraph_sim.model.interfaces import l3_usable + from netlab_sim.model.interfaces import l3_usable return l3_usable(node, af) @@ -431,7 +431,7 @@ def leg_live(node: Any, af: int) -> bool: """What a data plane with fast failover sees for a next-hop group leg: the egress is usable for *af* and, for an Ethernet port, its raw carrier (link state as the hardware sees it, before any debounce) is up.""" - from ngraph_sim.model.interfaces import EthernetNode, l3_usable + from netlab_sim.model.interfaces import EthernetNode, l3_usable if node is None or not l3_usable(node, af): return False @@ -617,7 +617,7 @@ def _transmit( select: Selection | None = None, ) -> StepResult: """Shared egress checks; a CROSS_CONNECT enters here without a DA lookup.""" - from ngraph_sim.model.interfaces import OperState, PortChannelNode + from netlab_sim.model.interfaces import OperState, PortChannelNode af = 4 if isinstance(packet, IPv4Packet) else 6 egress = view.interface(adj.interface) @@ -642,8 +642,8 @@ def _transmit( link, peer = tx member_node = view.interface(member) rx_admin, rx_enabled = view.endpoint_usable(peer) - from ngraph_sim.model.interfaces import AdminState - from ngraph_sim.model.links import transfer_blocked + from netlab_sim.model.interfaces import AdminState + from netlab_sim.model.links import transfer_blocked blocked = transfer_blocked( link.oper.state, @@ -686,7 +686,7 @@ def receive_frame( policies: list[tuple[int, int]] | None = None, ) -> StepResult: """L2 checks, then the IP step as a transit packet.""" - from ngraph_sim.model.interfaces import EthernetNode, OperState + from netlab_sim.model.interfaces import EthernetNode, OperState node = view.interface(ingress) if node is None or node.oper.oper != OperState.UP: diff --git a/ngraph_sim/model/hashing.py b/netlab_sim/model/hashing.py similarity index 97% rename from ngraph_sim/model/hashing.py rename to netlab_sim/model/hashing.py index 5e2c45a..3cc9484 100644 --- a/ngraph_sim/model/hashing.py +++ b/netlab_sim/model/hashing.py @@ -17,8 +17,8 @@ import struct from enum import IntEnum -from ngraph_sim.model.packets import FlowKey -from ngraph_sim.model.state import record +from netlab_sim.model.packets import FlowKey +from netlab_sim.model.state import record FIELD_SRC = 1 FIELD_DST = 2 diff --git a/ngraph_sim/model/igp.py b/netlab_sim/model/igp.py similarity index 96% rename from ngraph_sim/model/igp.py rename to netlab_sim/model/igp.py index 9e5fb2c..dc0f801 100644 --- a/ngraph_sim/model/igp.py +++ b/netlab_sim/model/igp.py @@ -13,17 +13,17 @@ import dataclasses import heapq -from ngraph_sim.model import derive -from ngraph_sim.model.addressing import IPV4, IPV6, mask_for -from ngraph_sim.model.contracts import IGP, IGP_PROFILE -from ngraph_sim.model.interfaces import ( +from netlab_sim.model import derive +from netlab_sim.model.addressing import IPV4, IPV6, mask_for +from netlab_sim.model.contracts import IGP, IGP_PROFILE +from netlab_sim.model.interfaces import ( EthernetNode, LoopbackNode, PortChannelNode, l3_usable, ) -from ngraph_sim.model.routing import Nexthop, RibState, Route, rib_apply -from ngraph_sim.model.state import NetworkState, PMap +from netlab_sim.model.routing import Nexthop, RibState, Route, rib_apply +from netlab_sim.model.state import NetworkState, PMap def _egresses( diff --git a/ngraph_sim/model/interfaces.py b/netlab_sim/model/interfaces.py similarity index 98% rename from ngraph_sim/model/interfaces.py rename to netlab_sim/model/interfaces.py index bb6ea49..59b95eb 100644 --- a/ngraph_sim/model/interfaces.py +++ b/netlab_sim/model/interfaces.py @@ -11,9 +11,9 @@ from enum import IntEnum from typing import Callable -from ngraph_sim.model.addressing import IPV4 -from ngraph_sim.model.links import LINK_UP, LinkOper -from ngraph_sim.model.state import PMap, empty_pmap, record +from netlab_sim.model.addressing import IPV4 +from netlab_sim.model.links import LINK_UP, LinkOper +from netlab_sim.model.state import PMap, empty_pmap, record class IfKind(IntEnum): diff --git a/ngraph_sim/model/links.py b/netlab_sim/model/links.py similarity index 98% rename from ngraph_sim/model/links.py rename to netlab_sim/model/links.py index 59b7f34..15ec47b 100644 --- a/ngraph_sim/model/links.py +++ b/netlab_sim/model/links.py @@ -2,7 +2,7 @@ from __future__ import annotations -from ngraph_sim.model.state import record +from netlab_sim.model.state import record LINK_UP = 1 LINK_FAILED = 0 diff --git a/ngraph_sim/model/lpm.py b/netlab_sim/model/lpm.py similarity index 100% rename from ngraph_sim/model/lpm.py rename to netlab_sim/model/lpm.py diff --git a/ngraph_sim/model/network.py b/netlab_sim/model/network.py similarity index 97% rename from ngraph_sim/model/network.py rename to netlab_sim/model/network.py index 94da51c..a1b91ca 100644 --- a/ngraph_sim/model/network.py +++ b/netlab_sim/model/network.py @@ -16,9 +16,9 @@ from contextlib import contextmanager from typing import Any, Callable, Iterable, Iterator -from ngraph_sim.model import derive, routing, srv6 -from ngraph_sim.model.addressing import IPV4, IPV6, LOCAL_ADMIN_BASE, mac_from_index -from ngraph_sim.model.contracts import ( +from netlab_sim.model import derive, routing, srv6 +from netlab_sim.model.addressing import IPV4, IPV6, LOCAL_ADMIN_BASE, mac_from_index +from netlab_sim.model.contracts import ( CONNECTED_PROFILE, IGP_PROFILE, LOCAL_PROFILE, @@ -30,7 +30,7 @@ DeviceAgent, check_agent, ) -from ngraph_sim.model.entities import ( +from netlab_sim.model.entities import ( Device, Interface, Link, @@ -38,7 +38,7 @@ _Handle, _remove_interfaces, ) -from ngraph_sim.model.interfaces import ( +from netlab_sim.model.interfaces import ( EthernetConfig, EthernetNode, EthernetOper, @@ -48,8 +48,8 @@ PortChannelNode, PortChannelOper, ) -from ngraph_sim.model.links import LinkConfig, LinkNode, LinkOper, link_id -from ngraph_sim.model.state import ( +from netlab_sim.model.links import LinkConfig, LinkNode, LinkOper, link_id +from netlab_sim.model.state import ( DEBUG_VALIDATE, DeviceConfig, DeviceState, @@ -286,14 +286,14 @@ def mark_published(error: BaseException) -> None: """Mark *error* as raised by an observer after the commit was published: the new root stands and the work that produced it is consumed.""" try: - error.ngraph_sim_published = True # type: ignore[attr-defined] + error.netlab_sim_published = True # type: ignore[attr-defined] except Exception: # pragma: no cover - exotic exception types pass def published_failure(error: BaseException) -> bool: """Whether *error* came from an observer after a successful publication.""" - return bool(getattr(error, 'ngraph_sim_published', False)) + return bool(getattr(error, 'netlab_sim_published', False)) class Network: @@ -324,7 +324,7 @@ def __init__(self, *, seed: int = 0) -> None: self._batch_handles: list[_Handle] = [] self._handles: dict[tuple, _Handle] = {} self.ngraph_link_ids: dict[str, str] = {} - """NetGraph link id → NetGraph-Sim link id, filled by the NetGraph adapter.""" + """NetGraph link id → NetLab-Sim link id, filled by the NetGraph adapter.""" self._mac_base = LOCAL_ADMIN_BASE | ((seed & 0xFF) << 32) # -- state and update ----------------------------------------------------- @@ -445,7 +445,7 @@ def fork(self) -> Network: # tree; a fork keeps its own copy so imports into the fork stay # consistent with what the shared root already contains. for name, value in vars(self).items(): - if name.startswith('ngraph_sim_'): + if name.startswith('netlab_sim_'): setattr(net, name, copy.deepcopy(value)) return net @@ -526,7 +526,7 @@ def add_source(self, source: RouteSource) -> None: def add_agent( self, device: Device | str, agent: DeviceAgent, name: str | None = None ) -> AgentNode: - """Register a protocol agent on a device (``ngraph_sim.model.contracts``). + """Register a protocol agent on a device (``netlab_sim.model.contracts``). Validates the plugin, registers its client profile (or checks it against an existing registration of the same client), and commits an @@ -892,7 +892,7 @@ def fn(state: _Edits) -> None: nodes[(dev_name, if_name)] = node allocators, gen = state.allocators.take_generation() allocators, index = allocators.take_link_index() - from ngraph_sim.model.links import canonical_endpoints + from netlab_sim.model.links import canonical_endpoints ca, cb = canonical_endpoints(ea, eb) link = LinkNode( @@ -1037,7 +1037,7 @@ def fn(state: NetworkState) -> NetworkState: # -- demands and placement ------------------------------------------------------ def add_demand(self, id: str, source: str, dst: str, rate: float, **kw: Any) -> Any: - from ngraph_sim.model.flows import make_demand + from netlab_sim.model.flows import make_demand demand = make_demand(id, source, dst, rate, **kw) @@ -1061,7 +1061,7 @@ def set_capacity_model(self, model: int) -> None: self.capacity_model = model def _placement(self, state: NetworkState) -> NetworkState: - from ngraph_sim.model.flows import derive_placement + from netlab_sim.model.flows import derive_placement return derive_placement(state, self.capacity_model) @@ -1082,7 +1082,7 @@ def view(self, device: str) -> _View: return _View(self.state, device) def trace(self, device: Device | str, packet: Any, max_hops: int = 64): - from ngraph_sim.model.forwarding import trace as _trace + from netlab_sim.model.forwarding import trace as _trace name = device.name if isinstance(device, Device) else device state = self.state @@ -1141,7 +1141,7 @@ def neighbor_mac(self, interface: str, address: int) -> int | None: return None if nt is None else nt.mac(interface, address) def load_balancer(self, kind: int) -> Any: - from ngraph_sim.model.hashing import LoadBalancer + from netlab_sim.model.hashing import LoadBalancer lbs = self.dev.load_balancers if lbs is not None and kind in lbs: @@ -1165,7 +1165,7 @@ def endpoint_usable(self, endpoint: tuple[str, str]) -> tuple[bool, bool]: node = dev.interfaces.get(endpoint[1]) if dev is not None else None if dev is None or node is None: return False, False - from ngraph_sim.model.interfaces import AdminState + from netlab_sim.model.interfaces import AdminState return node.config.admin == AdminState.UP, dev.config.enabled diff --git a/ngraph_sim/model/nht.py b/netlab_sim/model/nht.py similarity index 97% rename from ngraph_sim/model/nht.py rename to netlab_sim/model/nht.py index 3b96287..efc89d1 100644 --- a/ngraph_sim/model/nht.py +++ b/netlab_sim/model/nht.py @@ -14,8 +14,8 @@ from dataclasses import replace from typing import overload -from ngraph_sim.model.addressing import IPV4, IPV6, mask_for -from ngraph_sim.model.contracts import ( +from netlab_sim.model.addressing import IPV4, IPV6, mask_for +from netlab_sim.model.contracts import ( IGP, ClientId, LookupView, @@ -23,9 +23,9 @@ NhtResult, NhtTable, ) -from ngraph_sim.model.forwarding import Fib, NeighborTable -from ngraph_sim.model.interfaces import l3_usable -from ngraph_sim.model.routing import ( +from netlab_sim.model.forwarding import Fib, NeighborTable +from netlab_sim.model.interfaces import l3_usable +from netlab_sim.model.routing import ( ResolutionContext, ResolutionPolicy, ResolverOutcome, @@ -33,8 +33,8 @@ RowKey, resolve_candidate, ) -from ngraph_sim.model.srv6 import Srv6Policies -from ngraph_sim.model.state import ( +from netlab_sim.model.srv6 import Srv6Policies +from netlab_sim.model.state import ( DeviceConfig, DeviceState, NetworkState, diff --git a/ngraph_sim/model/packets.py b/netlab_sim/model/packets.py similarity index 98% rename from ngraph_sim/model/packets.py rename to netlab_sim/model/packets.py index d6bed84..836e027 100644 --- a/ngraph_sim/model/packets.py +++ b/netlab_sim/model/packets.py @@ -12,9 +12,9 @@ from dataclasses import replace from typing import Any, NamedTuple -from ngraph_sim.model.addressing import IPV4, IPV6, AddressFamily -from ngraph_sim.model.srv6 import H_ENCAPS, H_ENCAPS_RED -from ngraph_sim.model.state import record +from netlab_sim.model.addressing import IPV4, IPV6, AddressFamily +from netlab_sim.model.srv6 import H_ENCAPS, H_ENCAPS_RED +from netlab_sim.model.state import record ETHERTYPE_IPV4 = 0x0800 ETHERTYPE_IPV6 = 0x86DD diff --git a/ngraph_sim/model/prng.py b/netlab_sim/model/prng.py similarity index 99% rename from ngraph_sim/model/prng.py rename to netlab_sim/model/prng.py index 2071f0b..f558176 100644 --- a/ngraph_sim/model/prng.py +++ b/netlab_sim/model/prng.py @@ -13,7 +13,7 @@ Version 1 fixes the hash encoding, the constants and every distribution below. It does not reproduce ``random.Random`` sequences, and generation uses no stdlib random code, ``hash()`` or mutable globals. Code that persists state -outside NetGraph-Sim must record ``Prng.VERSION`` with it and pass it back on restore. +outside NetLab-Sim must record ``Prng.VERSION`` with it and pass it back on restore. """ from __future__ import annotations diff --git a/ngraph_sim/model/routing.py b/netlab_sim/model/routing.py similarity index 99% rename from ngraph_sim/model/routing.py rename to netlab_sim/model/routing.py index 8337bed..6b27358 100644 --- a/ngraph_sim/model/routing.py +++ b/netlab_sim/model/routing.py @@ -16,15 +16,15 @@ from math import lcm from typing import Any, Iterator, Protocol -from ngraph_sim.model.addressing import ( +from netlab_sim.model.addressing import ( IPV4, IPV6, MacAddress, is_link_local_v6, mask_for, ) -from ngraph_sim.model.contracts import CONNECTED, LOCAL, ClientId, ClientProfile -from ngraph_sim.model.forwarding import ( +from netlab_sim.model.contracts import CONNECTED, LOCAL, ClientId, ClientProfile +from netlab_sim.model.forwarding import ( CROSS_CONNECT, DECAP_LOOKUP, DROP_ACTIONS, @@ -43,16 +43,16 @@ Prefix, local_sid, ) -from ngraph_sim.model.lpm import FrozenPrefixTable, PrefixTable -from ngraph_sim.model.packets import IPv4Packet, IPv6Packet, encapsulate -from ngraph_sim.model.srv6 import ( +from netlab_sim.model.lpm import FrozenPrefixTable, PrefixTable +from netlab_sim.model.packets import IPv4Packet, IPv6Packet, encapsulate +from netlab_sim.model.srv6 import ( FALLBACK_DROP, LocalSid, PolicyRef, Srv6Encap, policy_programs, ) -from ngraph_sim.model.state import PMap, PMapBuilder, empty_pmap, record +from netlab_sim.model.state import PMap, PMapBuilder, empty_pmap, record # Special next-hops (RFC 8349 special-next-hop plus SRv6 local behaviours). BLACKHOLE = 1 diff --git a/ngraph_sim/model/srv6.py b/netlab_sim/model/srv6.py similarity index 98% rename from ngraph_sim/model/srv6.py rename to netlab_sim/model/srv6.py index 1d65a42..8439df5 100644 --- a/ngraph_sim/model/srv6.py +++ b/netlab_sim/model/srv6.py @@ -16,11 +16,11 @@ from ipaddress import IPv6Address, IPv6Network, summarize_address_range from typing import TYPE_CHECKING, Any, Iterable -from ngraph_sim.model.contracts import STATIC, ClientId, RemoteSid, SrDbView -from ngraph_sim.model.state import PMap, canon, empty_pmap, record +from netlab_sim.model.contracts import STATIC, ClientId, RemoteSid, SrDbView +from netlab_sim.model.state import PMap, canon, empty_pmap, record if TYPE_CHECKING: - from ngraph_sim.model.state import DeviceState, NetworkState + from netlab_sim.model.state import DeviceState, NetworkState # --------------------------------------------------------------------------- # Behaviours, flavors, headend behaviours (small ints on the hot path) @@ -172,7 +172,7 @@ class LocalSid: class SidRanges: """Inclusive 16-bit GIB, LIB and WLIB ranges for one locator block. - WLIB selects the high 16 bits of a 32-bit function (NetGraph-Sim F3216 convention). + WLIB selects the high 16 bits of a 32-bit function (NetLab-Sim F3216 convention). GIB/LIB scope and disjointness follow RFC 9800 §§5.1-5.2. Allocation divides each function pool into four disjoint purpose ranges. """ @@ -546,7 +546,7 @@ def add_locator( node_id: int | None, ranges: SidRanges, ) -> tuple[NetworkState, Locator]: - from ngraph_sim.model.state import check_name + from netlab_sim.model.state import check_name check_name(name) dev = state.devices[device] @@ -711,7 +711,7 @@ def add_local_sid( if behavior == END_X: if interface is None or interface not in dev.interfaces: raise ValueError('End.X requires a bound interface') - from ngraph_sim.model.interfaces import LoopbackNode + from netlab_sim.model.interfaces import LoopbackNode if isinstance(dev.interfaces[interface], LoopbackNode): raise ValueError('End.X requires an adjacency interface') @@ -811,7 +811,7 @@ def request_sid( behavior: int, args: dict[str, Any], ) -> tuple[NetworkState, LocalSid]: - from ngraph_sim.model.state import validate_immutable + from netlab_sim.model.state import validate_immutable if not request_id: raise ValueError('request id must be nonempty') @@ -1003,7 +1003,7 @@ def set_steering( if rule.af not in (None, 4, 6) or (rule.dst is not None and rule.af is None): raise ValueError('steering destination needs an address family') if rule.dst is not None: - from ngraph_sim.model.addressing import mask_for + from netlab_sim.model.addressing import mask_for net, length = rule.dst bits = 32 if rule.af == 4 else 128 @@ -1251,8 +1251,8 @@ def consumers_affected(old: NetworkState, new: NetworkState) -> set[str]: validation records also take the fallback. Derived policy/FIB outputs do not feed back into validation. """ - from ngraph_sim.model.interfaces import LoopbackNode - from ngraph_sim.model.state import diff_pmap + from netlab_sim.model.interfaces import LoopbackNode + from netlab_sim.model.state import diff_pmap delta = diff_pmap(old.devices, new.devices, by_identity=True) global_change = bool(delta.added or delta.removed or old.links != new.links) @@ -1320,7 +1320,7 @@ def _uses_devices(dev: DeviceState, changed: set[str]) -> bool: def consumer_index(old: NetworkState, new: NetworkState) -> frozenset[str]: """Update the root index by changed shards; plain-IP edits never scan the tree.""" - from ngraph_sim.model.state import diff_pmap + from netlab_sim.model.state import diff_pmap delta = diff_pmap(old.devices, new.devices, by_identity=True) previous = old.srv6_consumers @@ -1434,12 +1434,12 @@ def literal(self, address: int, current: str) -> tuple[str, LocalSid] | None: return result def peer(self, device: str, interface: str) -> str | None: - from ngraph_sim.model.derive import ( + from netlab_sim.model.derive import ( bundle_members, peer_bundle_key, peer_endpoint, ) - from ngraph_sim.model.interfaces import PortChannelNode + from netlab_sim.model.interfaces import PortChannelNode dev = self.state.devices[device] node = dev.interfaces.get(interface) @@ -1457,8 +1457,8 @@ def peer(self, device: str, interface: str) -> str | None: return result def forwarding(self, device: str, address: int): - from ngraph_sim.model.derive import DeviceContext - from ngraph_sim.model.routing import ResolutionPolicy, resolve_underlay_query + from netlab_sim.model.derive import DeviceContext + from netlab_sim.model.routing import ResolutionPolicy, resolve_underlay_query key = device, address if key not in self.queries: @@ -1479,7 +1479,7 @@ def forwarding(self, device: str, address: int): def reaches( self, current: str, owner: str, address: int, sid: LocalSid ) -> str | None: - from ngraph_sim.model import forwarding as fw + from netlab_sim.model import forwarding as fw # Iterative DFS detects loops without a Python recursion-depth limit. pending = [(current, frozenset())] @@ -1544,7 +1544,7 @@ def strict( # Check the declared owners/behaviors first (including symbolic intent). # Route selection below uses actual wire addresses: a compressed DA can # select a different more-specific route than its zero-argument SID. - from ngraph_sim.model.srv6_compress import csid_arg, shift_csid + from netlab_sim.model.srv6_compress import csid_arg, shift_csid current = self.head pending = list(reversed(segments)) @@ -1610,8 +1610,8 @@ def encoded(self, wire: tuple[int, ...], policy: SrPolicy) -> str | None: only a terminal's prefix misses malformed suffixes after that prefix. All route queries remain RIB-derived, independently of FIB programming. """ - from ngraph_sim.model import forwarding as fw - from ngraph_sim.model.packets import IPv4Packet, IPv6Packet, encapsulate + from netlab_sim.model import forwarding as fw + from netlab_sim.model.packets import IPv4Packet, IPv6Packet, encapsulate packet = encapsulate( IPv4Packet(0, 0, 17), @@ -1793,7 +1793,7 @@ def reaches( return 'ADJACENCY_DOWN_IN_VIEW' if owner == self.head: # Only local RIB state may corroborate a local behavior. - from ngraph_sim.model import forwarding as fw + from netlab_sim.model import forwarding as fw entry, _ = self.forwarding(self.head, address) return ( @@ -1830,14 +1830,14 @@ def forwarding(self, device: str, address: int): def derive_policy_states(state: NetworkState, device: str) -> Srv6Policies | None: - """RFC 9256 section 5.1 layers, then NetGraph-Sim's stronger end-to-end profile. + """RFC 9256 section 5.1 layers, then NetLab-Sim's stronger end-to-end profile. Literal metadata is used only for compression, never inferred from the DB. Strict results are exposed even when validation is disabled for trap studies. """ - from ngraph_sim.model.derive import DeviceContext - from ngraph_sim.model.routing import ResolutionPolicy, resolve_first_entry - from ngraph_sim.model.srv6_compress import compress + from netlab_sim.model.derive import DeviceContext + from netlab_sim.model.routing import ResolutionPolicy, resolve_first_entry + from netlab_sim.model.srv6_compress import compress dev = state.devices[device] view = agent_srdb_view(dev) diff --git a/ngraph_sim/model/srv6_compress.py b/netlab_sim/model/srv6_compress.py similarity index 97% rename from ngraph_sim/model/srv6_compress.py rename to netlab_sim/model/srv6_compress.py index b163812..e28609f 100644 --- a/ngraph_sim/model/srv6_compress.py +++ b/netlab_sim/model/srv6_compress.py @@ -1,7 +1,7 @@ """Pure NEXT-C-SID encoding and destination arithmetic (RFC 9800). The input and output of ``compress`` are in forwarding order. RFC 9800 -§6.2 S01-S16 is NetGraph-Sim's deterministic encoder; the SRH reverses the +§6.2 S01-S16 is NetLab-Sim's deterministic encoder; the SRH reverses the result only at encapsulation. No allocation or reachability is inferred. """ @@ -9,7 +9,7 @@ from collections.abc import Sequence -from ngraph_sim.model.srv6 import ( +from netlab_sim.model.srv6 import ( F3216_COMPOSITE, F3216_GIB, F3216_LIB, @@ -33,7 +33,7 @@ def _check_layout(structure: SidStructure) -> None: def csid_arg(da: int, structure: SidStructure) -> int: """DA bits after LBL+LNFL, before shifting (RFC 9800 §4.1.1). - This is the physical suffix, including for NetGraph-Sim's AL=0 terminal + This is the physical suffix, including for NetLab-Sim's AL=0 terminal structures. It is not the active C-SID and does not test the EOC marker. """ _check_address(da) diff --git a/ngraph_sim/model/state.py b/netlab_sim/model/state.py similarity index 99% rename from ngraph_sim/model/state.py rename to netlab_sim/model/state.py index a655f49..67f7649 100644 --- a/ngraph_sim/model/state.py +++ b/netlab_sim/model/state.py @@ -30,16 +30,16 @@ dataclass_transform, ) -from ngraph_sim.model.lpm import FrozenPrefixTable +from netlab_sim.model.lpm import FrozenPrefixTable if TYPE_CHECKING: - from ngraph_sim.model.srv6 import Srv6Policies, Srv6Sids + from netlab_sim.model.srv6 import Srv6Policies, Srv6Sids K = TypeVar('K', bound=Hashable) V = TypeVar('V') T = TypeVar('T') -DEBUG_VALIDATE: bool = os.environ.get('NGRAPH_SIM_DEBUG', '') not in ('', '0') +DEBUG_VALIDATE: bool = os.environ.get('NETLAB_SIM_DEBUG', '') not in ('', '0') """When set, ``Network.update`` validates transitive immutability of the candidate root.""" @@ -612,7 +612,7 @@ def _classify(o: Any, p: str, records: dict[type, frozenset[str]]) -> int: ``__dict__``, no non-empty slots: ``MacAddress``, ``NamedTuple``), an enum member (its value is walked), a class decorated itself as a frozen dataclass, a ``PMap``, a frozen prefix table or a type that declares - ``__ngraph_sim_immutable__``. Everything else (mutable builtins, C-level + ``__netlab_sim_immutable__``. Everything else (mutable builtins, C-level containers such as ``deque``, iterators, subclasses with attribute storage, arbitrary objects) is rejected. """ @@ -680,7 +680,7 @@ def _classify(o: Any, p: str, records: dict[type, frozenset[str]]) -> int: f'{extra[0]!r} at {p}' ) return _RECORD - if getattr(t, '__ngraph_sim_immutable__', False): + if getattr(t, '__netlab_sim_immutable__', False): return _LEAF raise TypeError(f'unrecognized object {t.__name__} at {p}') diff --git a/ngraph_sim/py.typed b/netlab_sim/py.typed similarity index 100% rename from ngraph_sim/py.typed rename to netlab_sim/py.typed diff --git a/ngraph_sim/resources.py b/netlab_sim/resources.py similarity index 99% rename from ngraph_sim/resources.py rename to netlab_sim/resources.py index bb8bf3a..a45fbf0 100644 --- a/ngraph_sim/resources.py +++ b/netlab_sim/resources.py @@ -8,7 +8,7 @@ from heapq import heappop, heappush from typing import Any, Callable, Iterator, NamedTuple, Protocol -from ngraph_sim.core import Environment, Event, Process, SimTime +from netlab_sim.core import Environment, Event, Process, SimTime class RequestQueue(Protocol): diff --git a/ngraph_sim/runtime/__init__.py b/netlab_sim/runtime/__init__.py similarity index 70% rename from ngraph_sim/runtime/__init__.py rename to netlab_sim/runtime/__init__.py index 5b28369..58d0341 100644 --- a/ngraph_sim/runtime/__init__.py +++ b/netlab_sim/runtime/__init__.py @@ -1,6 +1,6 @@ """Runtime: binds the clock-free model to the DES engine.""" -from ngraph_sim.runtime.failures import ( +from netlab_sim.runtime.failures import ( Distribution, Draws, FailureSet, @@ -9,8 +9,8 @@ Process, Schedule, ) -from ngraph_sim.runtime.simulation import Simulation -from ngraph_sim.runtime.timeline import Timeline +from netlab_sim.runtime.simulation import Simulation +from netlab_sim.runtime.timeline import Timeline __all__ = [ 'Distribution', diff --git a/ngraph_sim/runtime/agents.py b/netlab_sim/runtime/agents.py similarity index 98% rename from ngraph_sim/runtime/agents.py rename to netlab_sim/runtime/agents.py index 98c025f..e2b658d 100644 --- a/ngraph_sim/runtime/agents.py +++ b/netlab_sim/runtime/agents.py @@ -12,7 +12,7 @@ discards parked tickets together with the generation's inbox. Budget counters distinguish runnable ``pending_runs`` from ``parked_runs``. -Contract between this runtime and ``ngraph_sim.runtime.transport`` (both sides +Contract between this runtime and ``netlab_sim.runtime.transport`` (both sides are implemented by their own slice; the method names below are fixed): - ``AgentRuntime.deliver(device, agent, entry)`` appends an inbox entry for @@ -59,23 +59,23 @@ from dataclasses import dataclass, fields, replace from typing import TYPE_CHECKING, Any -from ngraph_sim.model import contracts as c -from ngraph_sim.model import derive, interfaces, nht, routing, srv6 -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.network import mark_published -from ngraph_sim.model.prng import Prng -from ngraph_sim.model.state import ( +from netlab_sim.model import contracts as c +from netlab_sim.model import derive, interfaces, nht, routing, srv6 +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.network import mark_published +from netlab_sim.model.prng import Prng +from netlab_sim.model.state import ( NetworkState, PMap, StateDelta, validate_admitted, validate_immutable, ) -from ngraph_sim.runtime.pipeline import COALESCE, Kind -from ngraph_sim.runtime.subscriptions import SubscriptionIndex +from netlab_sim.runtime.pipeline import COALESCE, Kind +from netlab_sim.runtime.subscriptions import SubscriptionIndex if TYPE_CHECKING: - from ngraph_sim.runtime.simulation import Simulation + from netlab_sim.runtime.simulation import Simulation def _future(now: float, delay: float) -> float: diff --git a/ngraph_sim/runtime/channels.py b/netlab_sim/runtime/channels.py similarity index 94% rename from ngraph_sim/runtime/channels.py rename to netlab_sim/runtime/channels.py index a41ccac..b3aaf4d 100644 --- a/ngraph_sim/runtime/channels.py +++ b/netlab_sim/runtime/channels.py @@ -11,12 +11,12 @@ from math import isfinite from typing import Any -from ngraph_sim.model.addressing import MacAddress, is_link_local_v6 -from ngraph_sim.model.contracts import Endpoint -from ngraph_sim.model.interfaces import EthernetNode, PortChannelNode, l3_usable -from ngraph_sim.model.links import transfer_blocked -from ngraph_sim.model.network import _View -from ngraph_sim.model.state import NetworkState +from netlab_sim.model.addressing import MacAddress, is_link_local_v6 +from netlab_sim.model.contracts import Endpoint +from netlab_sim.model.interfaces import EthernetNode, PortChannelNode, l3_usable +from netlab_sim.model.links import transfer_blocked +from netlab_sim.model.network import _View +from netlab_sim.model.state import NetworkState def future(now: float, delay: float) -> float: diff --git a/ngraph_sim/runtime/events.py b/netlab_sim/runtime/events.py similarity index 98% rename from ngraph_sim/runtime/events.py rename to netlab_sim/runtime/events.py index 70a0bd8..8fb22d8 100644 --- a/ngraph_sim/runtime/events.py +++ b/netlab_sim/runtime/events.py @@ -12,8 +12,8 @@ from dataclasses import dataclass from typing import Any, Callable -from ngraph_sim import core -from ngraph_sim.model.state import NetworkState, StateDelta +from netlab_sim import core +from netlab_sim.model.state import NetworkState, StateDelta SETTLED = core.DEFERRED + 9 diff --git a/ngraph_sim/runtime/failures.py b/netlab_sim/runtime/failures.py similarity index 98% rename from ngraph_sim/runtime/failures.py rename to netlab_sim/runtime/failures.py index 4af94ce..b896914 100644 --- a/ngraph_sim/runtime/failures.py +++ b/netlab_sim/runtime/failures.py @@ -19,8 +19,8 @@ from typing import TYPE_CHECKING, Any if TYPE_CHECKING: - from ngraph_sim.model.network import Network - from ngraph_sim.runtime.simulation import Simulation + from netlab_sim.model.network import Network + from netlab_sim.runtime.simulation import Simulation Entity = tuple[str, str] @@ -397,7 +397,7 @@ def enumerate( groups = resolve_groups( risk_groups if risk_groups is not None - else getattr(network, 'ngraph_sim_risk_groups', {}) + else getattr(network, 'netlab_sim_risk_groups', {}) ) return cls( FailureSet(risk_groups=tuple(c)).resolve(groups) @@ -531,7 +531,7 @@ def __init__( @classmethod def from_network(cls, network: Network, *, seed: int | None = None) -> Process: return cls( - getattr(network, 'ngraph_sim_failure_parameters', {}), + getattr(network, 'netlab_sim_failure_parameters', {}), seed=network.seed if seed is None else seed, ) diff --git a/ngraph_sim/runtime/pipeline.py b/netlab_sim/runtime/pipeline.py similarity index 99% rename from ngraph_sim/runtime/pipeline.py rename to netlab_sim/runtime/pipeline.py index 4c137c7..edbba5d 100644 --- a/ngraph_sim/runtime/pipeline.py +++ b/netlab_sim/runtime/pipeline.py @@ -15,11 +15,11 @@ from heapq import heapify, heappop, heappush from typing import Any, Callable, Iterable -from ngraph_sim import core -from ngraph_sim.model import derive, srv6 -from ngraph_sim.model.interfaces import EthernetNode, PortChannelNode -from ngraph_sim.model.network import mark_published, published_failure -from ngraph_sim.model.state import NetworkState, StateDelta +from netlab_sim import core +from netlab_sim.model import derive, srv6 +from netlab_sim.model.interfaces import EthernetNode, PortChannelNode +from netlab_sim.model.network import mark_published, published_failure +from netlab_sim.model.state import NetworkState, StateDelta ROUND_END = core.DEFERRED + 8 SETTLED = core.DEFERRED + 9 diff --git a/ngraph_sim/runtime/simulation.py b/netlab_sim/runtime/simulation.py similarity index 93% rename from ngraph_sim/runtime/simulation.py rename to netlab_sim/runtime/simulation.py index f9ce7ea..b7ccadb 100644 --- a/ngraph_sim/runtime/simulation.py +++ b/netlab_sim/runtime/simulation.py @@ -4,16 +4,16 @@ from typing import Any, Callable -from ngraph_sim import core -from ngraph_sim.model import derive -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import NetworkState -from ngraph_sim.runtime.agents import AgentRuntime -from ngraph_sim.runtime.events import EventBus, Stats -from ngraph_sim.runtime.failures import Entity, LeaseRegistry, Process, Schedule -from ngraph_sim.runtime.pipeline import Pipeline, build_kinds, dirty_everything -from ngraph_sim.runtime.timeline import Timeline -from ngraph_sim.runtime.transport import TransportRuntime +from netlab_sim import core +from netlab_sim.model import derive +from netlab_sim.model.network import Network +from netlab_sim.model.state import NetworkState +from netlab_sim.runtime.agents import AgentRuntime +from netlab_sim.runtime.events import EventBus, Stats +from netlab_sim.runtime.failures import Entity, LeaseRegistry, Process, Schedule +from netlab_sim.runtime.pipeline import Pipeline, build_kinds, dirty_everything +from netlab_sim.runtime.timeline import Timeline +from netlab_sim.runtime.transport import TransportRuntime class BudgetExceeded(RuntimeError): @@ -158,7 +158,7 @@ def run_derivations(self, max_steps: int = 100_000) -> int: def run_until(self, time: float) -> None: if time > self.env.now: # The urgent horizon marker also advances an otherwise idle clock. - from ngraph_sim.runtime.pipeline import StageEvent + from netlab_sim.runtime.pipeline import StageEvent StageEvent( self.env, core.URGENT, time - self.env.now, lambda _: None, -1, time, 0 @@ -215,10 +215,10 @@ def failures( self, risk_groups=risk_groups if risk_groups is not None - else getattr(self.network, 'ngraph_sim_risk_groups', {}), + else getattr(self.network, 'netlab_sim_risk_groups', {}), ) elif risk_groups is not None: - from ngraph_sim.runtime.failures import resolve_groups + from netlab_sim.runtime.failures import resolve_groups if resolve_groups(risk_groups) != self._failure_registry.risk_groups: raise ValueError('risk groups cannot change within a simulation') @@ -237,8 +237,8 @@ def state(self) -> NetworkState: def send(self, device: str, packet: Any, max_hops: int = 64) -> core.Process: """Deliver a packet hop by hop through the DES, waiting ``link.delay`` per hop, so mid-flight state changes are honoured.""" - from ngraph_sim.model import forwarding as fw - from ngraph_sim.model.packets import ( + from netlab_sim.model import forwarding as fw + from netlab_sim.model.packets import ( ETHERTYPE_IPV4, ORIGINATED, EthernetFrame, diff --git a/ngraph_sim/runtime/subscriptions.py b/netlab_sim/runtime/subscriptions.py similarity index 97% rename from ngraph_sim/runtime/subscriptions.py rename to netlab_sim/runtime/subscriptions.py index 783519a..e7bd6bd 100644 --- a/ngraph_sim/runtime/subscriptions.py +++ b/netlab_sim/runtime/subscriptions.py @@ -10,8 +10,8 @@ from dataclasses import dataclass, field from typing import Any -from ngraph_sim.model.contracts import Path -from ngraph_sim.model.state import PMap, diff_pmap +from netlab_sim.model.contracts import Path +from netlab_sim.model.state import PMap, diff_pmap @dataclass(slots=True) diff --git a/ngraph_sim/runtime/timeline.py b/netlab_sim/runtime/timeline.py similarity index 99% rename from ngraph_sim/runtime/timeline.py rename to netlab_sim/runtime/timeline.py index ada1e74..7296524 100644 --- a/ngraph_sim/runtime/timeline.py +++ b/netlab_sim/runtime/timeline.py @@ -23,17 +23,17 @@ from dataclasses import field from typing import Any, Callable, Iterable, Iterator -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import routing, srv6 -from ngraph_sim.model.addressing import IPV4, IPV6, to_address -from ngraph_sim.model.interfaces import ( +from netlab_sim.model import forwarding as fw +from netlab_sim.model import routing, srv6 +from netlab_sim.model.addressing import IPV4, IPV6, to_address +from netlab_sim.model.interfaces import ( EthernetNode, OperState, PortChannelNode, StateReason, ) -from ngraph_sim.model.links import LINK_UP -from ngraph_sim.model.state import ( +from netlab_sim.model.links import LINK_UP +from netlab_sim.model.state import ( FloatArray, NetworkState, PMap, diff --git a/ngraph_sim/runtime/transport.py b/netlab_sim/runtime/transport.py similarity index 99% rename from ngraph_sim/runtime/transport.py rename to netlab_sim/runtime/transport.py index 5edd68d..50622c2 100644 --- a/ngraph_sim/runtime/transport.py +++ b/netlab_sim/runtime/transport.py @@ -8,7 +8,7 @@ rejections. The TRANSPORT kind derives path reachability in ``NetworkState.transport``. -The runtime interface used by publication (``ngraph_sim.runtime.agents``): +The runtime interface used by publication (``netlab_sim.runtime.agents``): ``send_datagram``, ``send_message``, ``session_op`` and ``cancel_agent``; deliveries call back ``AgentRuntime.deliver``. @@ -55,20 +55,20 @@ from heapq import heapify from typing import TYPE_CHECKING, Any, Callable -from ngraph_sim import core -from ngraph_sim.model import contracts as c -from ngraph_sim.model import derive -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.network import _View -from ngraph_sim.model.packets import IPv4Packet, IPv6Packet, L4Header -from ngraph_sim.model.state import ( +from netlab_sim import core +from netlab_sim.model import contracts as c +from netlab_sim.model import derive +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.network import _View +from netlab_sim.model.packets import IPv4Packet, IPv6Packet, L4Header +from netlab_sim.model.state import ( NetworkState, StateDelta, diff_pmap, validate_immutable, ) -from ngraph_sim.runtime.channels import ( +from netlab_sim.runtime.channels import ( Wire, configured, eligible, @@ -78,10 +78,10 @@ source_address, wires, ) -from ngraph_sim.runtime.pipeline import COALESCE, Kind +from netlab_sim.runtime.pipeline import COALESCE, Kind if TYPE_CHECKING: - from ngraph_sim.runtime.simulation import Simulation + from netlab_sim.runtime.simulation import Simulation @dataclass(slots=True) diff --git a/ngraph_sim/study.py b/netlab_sim/study.py similarity index 98% rename from ngraph_sim/study.py rename to netlab_sim/study.py index 32adca2..ae29c8e 100644 --- a/ngraph_sim/study.py +++ b/netlab_sim/study.py @@ -19,12 +19,12 @@ from time import perf_counter from typing import Any -from ngraph_sim.core import Environment -from ngraph_sim.model.addressing import to_address -from ngraph_sim.model.network import Network -from ngraph_sim.model.srv6 import policy_status -from ngraph_sim.model.state import NetworkState, StateDelta -from ngraph_sim.runtime.failures import ( +from netlab_sim.core import Environment +from netlab_sim.model.addressing import to_address +from netlab_sim.model.network import Network +from netlab_sim.model.srv6 import policy_status +from netlab_sim.model.state import NetworkState, StateDelta +from netlab_sim.runtime.failures import ( Draws, FailureSet, FaultEvent, @@ -34,8 +34,8 @@ _nonnegative, resolve_groups, ) -from ngraph_sim.runtime.simulation import Simulation -from ngraph_sim.runtime.timeline import Event, PlacementEvent, Record +from netlab_sim.runtime.simulation import Simulation +from netlab_sim.runtime.timeline import Event, PlacementEvent, Record class Stability(str, Enum): @@ -534,14 +534,14 @@ def __init__( if unknown: raise ValueError(f'unknown keep options: {sorted(unknown)}') self.risk_groups = resolve_groups( - getattr(network, 'ngraph_sim_risk_groups', {}) + getattr(network, 'netlab_sim_risk_groups', {}) ) self.failure_parameters = deepcopy( - getattr(network, 'ngraph_sim_failure_parameters', {}) + getattr(network, 'netlab_sim_failure_parameters', {}) ) - self.capacity_unit = float(getattr(network, 'ngraph_sim_capacity_unit', 1.0)) - self.destinations = dict(getattr(network, 'ngraph_sim_demand_destinations', {})) - self.priorities = dict(getattr(network, 'ngraph_sim_demand_priorities', {})) + self.capacity_unit = float(getattr(network, 'netlab_sim_capacity_unit', 1.0)) + self.destinations = dict(getattr(network, 'netlab_sim_demand_destinations', {})) + self.priorities = dict(getattr(network, 'netlab_sim_demand_priorities', {})) # Many demands share a destination. Cache only baseline address strings; # iteration-specific demands use a fallback without growing this cache. self._addresses = { @@ -594,7 +594,7 @@ def describe( @classmethod def from_scenario(cls, scenario: Any, **adapter_kwargs: Any) -> Study: - from ngraph_sim.adapters.ngraph import from_scenario + from netlab_sim.adapters.ngraph import from_scenario keep = adapter_kwargs.pop('keep', None) network, _, _ = from_scenario(scenario, **adapter_kwargs) diff --git a/ngraph_sim/__main__.py b/ngraph_sim/__main__.py deleted file mode 100644 index 751b7cd..0000000 --- a/ngraph_sim/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from ngraph_sim.cli import main - -raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml index c750076..775fab0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=77", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "ngraph-sim" +name = "netlab-sim" version = "0.1.0" description = "Discrete-event simulation for IP networks." readme = "README.md" @@ -32,16 +32,16 @@ classifiers = [ dependencies = [] [project.urls] -Homepage = "https://github.com/networmix/NetGraph-Sim" -Documentation = "https://github.com/networmix/NetGraph-Sim/blob/main/docs/reference.md" -Issues = "https://github.com/networmix/NetGraph-Sim/issues" +Homepage = "https://github.com/networmix/NetLab-Sim" +Documentation = "https://github.com/networmix/NetLab-Sim/blob/main/docs/reference.md" +Issues = "https://github.com/networmix/NetLab-Sim/issues" [project.scripts] -ngraph-sim = "ngraph_sim.cli:main" +netlab-sim = "netlab_sim.cli:main" [project.optional-dependencies] dev = [ - "pytest>=8", + "pytest>=8,<9.2", "pytest-cov", "pytest-benchmark", "pytest-mock", @@ -54,14 +54,14 @@ dev = [ ] [tool.setuptools.packages.find] -include = ["ngraph_sim*"] +include = ["netlab_sim*"] exclude = ["tests*"] [tool.setuptools.package-data] -"ngraph_sim" = ["py.typed"] +"netlab_sim" = ["py.typed"] [tool.pytest.ini_options] -addopts = "--cov=ngraph_sim --cov-fail-under=85 --cov-report term-missing --benchmark-disable --benchmark-disable-gc --benchmark-min-rounds=5 --benchmark-warmup=on" +addopts = "--cov=netlab_sim --cov-fail-under=85 --cov-report term-missing --benchmark-disable --benchmark-disable-gc --benchmark-min-rounds=5 --benchmark-warmup=on" timeout = 60 # a hang guard: shared CI runners take up to 10x longer than a workstation markers = [ "slow: marks tests as slow", @@ -69,7 +69,7 @@ markers = [ ] [tool.coverage.run] -source = ["ngraph_sim"] +source = ["netlab_sim"] omit = ["*/tests/*", "*/test_*"] [tool.coverage.report] @@ -89,7 +89,7 @@ select = ["E4", "E7", "E9", "F", "B", "I"] fixable = ["ALL"] [tool.ruff.lint.isort] -known-first-party = ["ngraph_sim"] +known-first-party = ["netlab_sim"] [tool.ruff.format] quote-style = "single" diff --git a/tests/adapters/test_ngraph.py b/tests/adapters/test_ngraph.py index 04b89b0..eeb1162 100644 --- a/tests/adapters/test_ngraph.py +++ b/tests/adapters/test_ngraph.py @@ -5,10 +5,10 @@ import pytest -from ngraph_sim.adapters import ngraph as adapter -from ngraph_sim.adapters.core import edge_arrays -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import to_int +from netlab_sim.adapters import ngraph as adapter +from netlab_sim.adapters.core import edge_arrays +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import to_int @dataclass @@ -109,7 +109,7 @@ def test_import_routes_and_places(self, addressing): ) ids = adapter.demands_from(g, net, scenario.demand_set.sets, capacity_unit=1e6) assert ids == ['traffic:0:R1>*'] # combine: one anycast destination - assert net.ngraph_sim_demand_destinations[ids[0]] == '{R4}' + assert net.netlab_sim_demand_destinations[ids[0]] == '{R4}' net.converge() rep = net.placement assert rep.delivered_total == pytest.approx(100e6) @@ -129,10 +129,10 @@ def test_disabled_and_failures(self): assert net.links[net.ngraph_link_ids['R1|R3|0']].state == 0 assert net.placement.delivered_total == pytest.approx(100e6) # all via Po1 schedule = adapter.FailureSchedule((adapter.FailureIteration(0, ('R2',), ()),)) - import ngraph_sim - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.runtime import Simulation - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) schedule.apply(net, sim, start=10, dwell=2) sim.run_until(10) @@ -232,8 +232,8 @@ def test_real_ngraph_readme_topology(): def test_adapter_bulk_construction_commits_once(entry, monkeypatch): from contextlib import contextmanager - from ngraph_sim.model.network import Network - from ngraph_sim.model.state import tree_equal + from netlab_sim.model.network import Network + from netlab_sim.model.state import tree_equal graph = diamond_stub() sets = {'traffic': [TrafficDemand('^R1$', '^R[234]$', 100)]} @@ -274,11 +274,11 @@ def unbatched(self): def test_failure_schedules_share_overlapping_leases(): - import ngraph_sim - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.runtime import Simulation net = adapter.from_network(diamond_stub()) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) lid = 'R1|R3|0' schedule = adapter.FailureSchedule((adapter.FailureIteration(0, (), (lid,)),)) schedule.apply(net, sim, start=1, dwell=8) @@ -320,8 +320,8 @@ def test_combine_reaches_only_reachable_targets_like_netgraph(): def test_netgraph_priority_direction_is_translated(): - """NetGraph serves lower priority numbers first; NetGraph-Sim higher ones.""" - from ngraph_sim.model.flows import LOSSY + """NetGraph serves lower priority numbers first; NetLab-Sim higher ones.""" + from netlab_sim.model.flows import LOSSY graph = diamond_stub() net = adapter.from_network(graph, capacity_unit=1e6) @@ -342,7 +342,7 @@ def test_netgraph_priority_direction_is_translated(): later = net.placement.demands['p:0:R1>R4'] assert urgent.delivered == pytest.approx(150e6) assert later.delivered < 150e6 - assert net.ngraph_sim_demand_priorities == {'p:0:R1>R4': 10, 'p:1:R1>R4': 0} + assert net.netlab_sim_demand_priorities == {'p:0:R1>R4': 10, 'p:1:R1>R4': 0} assert net.state.demands['p:1:R1>R4'].priority == 0 assert net.state.demands['p:0:R1>R4'].priority == -10 @@ -451,10 +451,10 @@ def test_fork_keeps_the_allocator_and_the_labels(self): capacity_unit=1.0, ) assert fork.state.demands[ids2[0]].dst != net.state.demands[ids[0]].dst - assert fork.ngraph_sim_demand_priorities[ids[0]] == 3 - assert fork.ngraph_sim_demand_destinations[ids[0]] == '{R4}' - assert ids[0] not in net.ngraph_sim_demand_destinations or 'b' not in str( - net.ngraph_sim_anycast.keys() + assert fork.netlab_sim_demand_priorities[ids[0]] == 3 + assert fork.netlab_sim_demand_destinations[ids[0]] == '{R4}' + assert ids[0] not in net.netlab_sim_demand_destinations or 'b' not in str( + net.netlab_sim_anycast.keys() ) fork.converge() assert fork.placement.demands[ids2[0]].delivered == pytest.approx(30.0) @@ -479,7 +479,7 @@ def test_metadata_rolls_back_when_an_import_aborts(self): {'p': [TrafficDemand('^R1$', '^R4$', 20.0, mode='pairwise', priority=1)]}, capacity_unit=1.0, ) - before = dict(net.ngraph_sim_demand_priorities) + before = dict(net.netlab_sim_demand_priorities) root = net.state with pytest.raises(ValueError): adapter.demands_from( @@ -494,7 +494,7 @@ def test_metadata_rolls_back_when_an_import_aborts(self): capacity_unit=1.0, ) assert net.state is root - assert net.ngraph_sim_demand_priorities == before + assert net.netlab_sim_demand_priorities == before def test_untranslated_options_are_rejected(self): graph = diamond_stub() @@ -541,16 +541,16 @@ def boom(*args): capacity_unit=1.0, ) assert net.state.demands['p:0:R1>R4'].priority == -9 # the commit stood - assert net.ngraph_sim_demand_priorities['p:0:R1>R4'] == 9 # and so does the label + assert net.netlab_sim_demand_priorities['p:0:R1>R4'] == 9 # and so does the label def test_fork_detaches_nested_adapter_metadata(): graph = diamond_stub() net = adapter.from_network(graph) - net.ngraph_sim_failure_parameters[('device', 'R1')] = {'mtbf': 10, 'mttr': 1} + net.netlab_sim_failure_parameters[('device', 'R1')] = {'mtbf': 10, 'mttr': 1} fork = net.fork() - fork.ngraph_sim_failure_parameters[('device', 'R1')]['mtbf'] = 2 - assert net.ngraph_sim_failure_parameters[('device', 'R1')]['mtbf'] == 10 + fork.netlab_sim_failure_parameters[('device', 'R1')]['mtbf'] = 2 + assert net.netlab_sim_failure_parameters[('device', 'R1')]['mtbf'] == 10 def test_settings_are_read_only_from_the_sim_namespace(): diff --git a/tests/adapters/test_ngraph_srv6.py b/tests/adapters/test_ngraph_srv6.py index 205eb8a..918ae53 100644 --- a/tests/adapters/test_ngraph_srv6.py +++ b/tests/adapters/test_ngraph_srv6.py @@ -4,8 +4,8 @@ import pytest -from ngraph_sim.adapters.ngraph import demands_from, from_scenario -from ngraph_sim.model import srv6 as sr +from netlab_sim.adapters.ngraph import demands_from, from_scenario +from netlab_sim.model import srv6 as sr from tests.adapters.test_ngraph import ( DemandSet, Link, @@ -157,14 +157,14 @@ def test_static_path_requires_srv6_and_ipv6(): def test_bad_followup_import_rolls_back_policies_and_metadata(): net, _, _ = from_scenario(bundle_scenario(), srv6=True) - root, metadata = net.state, dict(net.ngraph_sim_demand_destinations) + root, metadata = net.state, dict(net.netlab_sim_demand_destinations) sc = bundle_scenario() good = sc.demand_set.sets['traffic'][0] bad = scenario(path=('R1', 'R4')).demand_set.sets['traffic'][0] with pytest.raises(ValueError, match='no enabled link'): demands_from(sc.network, net, {'new': [good, bad]}) assert net.state is root - assert net.ngraph_sim_demand_destinations == metadata + assert net.netlab_sim_demand_destinations == metadata def real_pinned(): @@ -393,7 +393,7 @@ def test_bundle_opt_in_is_per_demand_and_rejected_import_is_atomic(): with pytest.raises(ValueError, match='allow_bundle_pins'): demands_from(sc.network, net, {'rejected': [td]}) assert net.state is before - assert net.ngraph_sim_demand_destinations == {} + assert net.netlab_sim_demand_destinations == {} td.attrs = {'sim': {'allow_bundle_pins': True}} ids = demands_from(sc.network, net, {'accepted': [td]}) assert net.state.demands[ids[0]].steer is not None diff --git a/tests/adapters/test_sonic.py b/tests/adapters/test_sonic.py index 625c279..f4f0bac 100644 --- a/tests/adapters/test_sonic.py +++ b/tests/adapters/test_sonic.py @@ -7,11 +7,11 @@ import pytest -from ngraph_sim.adapters import sonic -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import tree_equal +from netlab_sim.adapters import sonic +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.network import Network +from netlab_sim.model.state import tree_equal def config(): diff --git a/tests/adapters/test_study_ngraph.py b/tests/adapters/test_study_ngraph.py index 54a41d5..d83ed19 100644 --- a/tests/adapters/test_study_ngraph.py +++ b/tests/adapters/test_study_ngraph.py @@ -7,7 +7,7 @@ from ngraph.analysis.failure_manager import FailureManager from ngraph.scenario import Scenario -from ngraph_sim.adapters.ngraph import failure_schedule +from netlab_sim.adapters.ngraph import failure_schedule def scenario_doc(): @@ -87,9 +87,9 @@ def test_draws_match_actual_square_mesh_monte_carlo_and_replay(tmp_path): from ngraph.results.flow import FlowEntry, FlowIterationResult, FlowSummary - from ngraph_sim import Environment - from ngraph_sim.runtime import Draws, Schedule, Simulation - from ngraph_sim.study import Study + from netlab_sim import Environment + from netlab_sim.runtime import Draws, Schedule, Simulation + from netlab_sim.study import Study doc = square_doc() step = next(x for x in doc['workflow'] if x['type'] == 'TrafficMatrixPlacement') @@ -158,8 +158,8 @@ def test_draws_match_actual_square_mesh_monte_carlo_and_replay(tmp_path): def test_seed_formula_and_policy_process_reproducibility(): from ngraph.utils.seed_manager import SeedManager - from ngraph_sim.runtime import Process - from ngraph_sim.runtime.failures import derive_seed + from netlab_sim.runtime import Process + from netlab_sim.runtime.failures import derive_seed assert derive_seed(42, 'link', 'x') == SeedManager(42).derive_seed( 'sim', 'link', 'x' @@ -239,7 +239,7 @@ def test_workflow_iterations_process_and_replay_inside_scenario(): def test_no_policy_and_bad_workflow_mode(): - from ngraph_sim.runtime import Draws + from netlab_sim.runtime import Draws doc = scenario_doc() scenario = scenario_from(doc) @@ -255,9 +255,9 @@ def test_attrs_sim_timing_and_nested_risk_groups(): from ngraph import Link, Network, Node from ngraph.model.network import RiskGroup - from ngraph_sim.adapters.ngraph import from_network - from ngraph_sim.runtime import Draws, Process - from ngraph_sim.study import Study + from netlab_sim.adapters.ngraph import from_network + from netlab_sim.runtime import Draws, Process + from netlab_sim.study import Study graph = Network() graph.add_node( @@ -298,7 +298,7 @@ def test_attrs_sim_timing_and_nested_risk_groups(): assert net.device('a').node.config.fib_delay == 0.02 assert net.device('a').node.config.fast_failover assert net.device('a')['port0'].config.carrier_delay_down == 0.1 - assert net.ngraph_sim_risk_groups['outer'] == (('device', 'a'), ('link', lid)) + assert net.netlab_sim_risk_groups['outer'] == (('device', 'a'), ('link', lid)) assert list(Draws.enumerate(net, 'risk_groups'))[0].excluded_links == (lid,) source = Process.from_network(net) assert set(source.parameters) == {('device', 'a'), ('link', lid)} @@ -330,13 +330,13 @@ def test_cli_square_mesh_console_entry(tmp_path): output = tmp_path / 'results.json' root = Path(__file__).resolve().parents[2] # Exercise the actual installed console script under NetGraph's interpreter. - script = root / 'venv-ft' / 'bin' / 'ngraph-sim' + script = root / 'venv-ft' / 'bin' / 'netlab-sim' if not script.exists(): - script = root / 'venv' / 'bin' / 'ngraph-sim' + script = root / 'venv' / 'bin' / 'netlab-sim' if script.exists(): command = [sys.executable, str(script)] else: - command = [sys.executable, '-m', 'ngraph_sim'] + command = [sys.executable, '-m', 'netlab_sim'] run = subprocess.run( [*command, 'run', str(source), '--results', str(output)], capture_output=True, diff --git a/tests/agents/fixtures.py b/tests/agents/fixtures.py index 811fcd9..b4c9290 100644 --- a/tests/agents/fixtures.py +++ b/tests/agents/fixtures.py @@ -1,12 +1,12 @@ """Independent protocol/oracle twins and forwarding-normalized comparisons.""" -from ngraph_sim import Environment -from ngraph_sim.agents import ReferenceAgent, ReferenceConfig -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation +from netlab_sim import Environment +from netlab_sim.agents import ReferenceAgent, ReferenceConfig +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation def topology( @@ -33,7 +33,7 @@ def topology( ipv6=[f'2001:db8::{i + 1}/128'] if 6 in families else (), ) if sr: - from ngraph_sim.model import srv6 + from netlab_sim.model import srv6 dev.add_locator('sr', prefix=f'2001:db8:{i + 1}::/64') dev.add_local_sid(srv6.END_DT46, structure=srv6.UNCOMPRESSED) diff --git a/tests/agents/test_locality.py b/tests/agents/test_locality.py index a622686..979790a 100644 --- a/tests/agents/test_locality.py +++ b/tests/agents/test_locality.py @@ -5,12 +5,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.agents import ReferenceAgent -from ngraph_sim.model import contracts as c -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.agents import AgentBatchError +from netlab_sim import Environment +from netlab_sim.agents import ReferenceAgent +from netlab_sim.model import contracts as c +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.agents import AgentBatchError from tests.agents.fixtures import assert_equivalent, topology, twins @@ -40,14 +40,14 @@ def guarded_device(self, *args, **kwargs): def test_no_oracle_imports_or_network_state_reads(): - import ngraph_sim.agents + import netlab_sim.agents - for path in Path(ngraph_sim.agents.__file__).parent.glob('*.py'): + for path in Path(netlab_sim.agents.__file__).parent.glob('*.py'): tree = ast.parse(path.read_text()) forbidden = ( - 'ngraph_sim.model.igp', - 'ngraph_sim.model.network', - 'ngraph_sim.model.entities', + 'netlab_sim.model.igp', + 'netlab_sim.model.network', + 'netlab_sim.model.entities', ) for node in ast.walk(tree): if isinstance(node, ast.Import): @@ -84,7 +84,7 @@ def test_reference_callbacks_are_local_on_discovery_failure_restart(monkeypatch) def test_cheating_plugin_fails_even_when_its_routes_match_oracle(monkeypatch, access): from dataclasses import replace - from ngraph_sim.model.igp import shortest_path_routes + from netlab_sim.model.igp import shortest_path_routes from tests.agents.fixtures import normalized_rows net = topology(agent=False) diff --git a/tests/agents/test_reference.py b/tests/agents/test_reference.py index 76b2576..6189359 100644 --- a/tests/agents/test_reference.py +++ b/tests/agents/test_reference.py @@ -2,9 +2,9 @@ import pytest -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.network import Network +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.network import Network from tests.runtime.inbox import deliver_now from tests.runtime.test_transport import bind, deliveries, register @@ -41,8 +41,8 @@ def test_link_local_control_datagram_on_numbered_interfaces(numbered_v6): @pytest.mark.parametrize('numbered', [False, True]) @pytest.mark.parametrize('families', [(4,), (6,), (4, 6)]) def test_cold_start_oracle_twin(numbered, families): - from ngraph_sim.agents.reference import Hello, LsUpdate - from ngraph_sim.model.state import validate_immutable + from netlab_sim.agents.reference import Hello, LsUpdate + from netlab_sim.model.state import validate_immutable from tests.agents.fixtures import assert_equivalent, state, twins sim, oracle = twins(numbered=numbered, families=families) @@ -70,8 +70,8 @@ def test_cold_start_oracle_twin(numbered, families): def test_rfc8950_ipv4_only_link_resolves_scoped_eui64(): - from ngraph_sim.model import forwarding as fw - from ngraph_sim.model.routing import Nexthop + from netlab_sim.model import forwarding as fw + from netlab_sim.model.routing import Nexthop net = Network() a, b = net.add_device('a'), net.add_device('b') @@ -115,7 +115,7 @@ def test_heartbeat_and_sequence_refresh_do_not_run_spf_fib_or_placement(): def test_local_down_at_ten_is_immediate_and_floods_oracle_result(): - from ngraph_sim.agents import ReferenceConfig + from netlab_sim.agents import ReferenceConfig from tests.agents.fixtures import assert_equivalent, state, twins sim, oracle = twins(config=ReferenceConfig(run_delay=0)) @@ -133,7 +133,7 @@ def test_local_down_at_ten_is_immediate_and_floods_oracle_result(): def test_muted_hello_channel_uses_hold_not_wire_or_session_rejection(): - from ngraph_sim.agents import ReferenceConfig + from netlab_sim.agents import ReferenceConfig from tests.agents.fixtures import state, twins sim, _ = twins(config=ReferenceConfig(run_delay=0)) @@ -152,7 +152,7 @@ def test_muted_hello_channel_uses_hold_not_wire_or_session_rejection(): def test_partition_expiry_and_heal_replace_finite_lsdb(): - from ngraph_sim.agents import ReferenceConfig + from netlab_sim.agents import ReferenceConfig from tests.agents.fixtures import assert_equivalent, state, twins config = ReferenceConfig(max_age=6, refresh_interval=2) @@ -196,7 +196,7 @@ def test_restart_replaces_stale_lsa_and_resynchronizes(): def inject(sim, name, lsas): - from ngraph_sim.agents.reference import LsUpdate + from netlab_sim.agents.reference import LsUpdate from tests.agents.fixtures import state connection = next(iter(state(sim, name).sessions.values())) @@ -319,7 +319,7 @@ def test_explicit_empty_body_purge_withdraws_on_every_router(): def test_route_publication_initial_sync_small_diff_and_large_sync(): - from ngraph_sim.agents import ReferenceConfig + from netlab_sim.agents import ReferenceConfig from tests.agents.fixtures import twins sim, _ = twins(numbered=False, config=ReferenceConfig(delta_limit=4)) @@ -358,7 +358,7 @@ def capture(state, device, client, output): def test_agent_rounds_publish_one_delta_with_all_successful_receipts(): - from ngraph_sim.runtime.timeline import AgentRunEvent + from netlab_sim.runtime.timeline import AgentRunEvent from tests.agents.fixtures import twins sim, _ = twins() @@ -409,8 +409,8 @@ def test_delayed_fib_exposes_pending_routes_and_transient_placement_drop(): def test_learned_sr_claims_and_literal_policy_follow_sid_advertisements(): - from ngraph_sim.model import srv6 as sr - from ngraph_sim.model.addressing import to_int + from netlab_sim.model import srv6 as sr + from netlab_sim.model.addressing import to_int from tests.agents.fixtures import state, twins sim, oracle = twins(sr=True) @@ -471,8 +471,8 @@ def test_learned_sr_claims_and_literal_policy_follow_sid_advertisements(): def test_fresh_runtime_resynchronizes_reference_fork(): - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.runtime import Simulation from tests.agents.fixtures import assert_equivalent, twins sim, oracle = twins() @@ -513,14 +513,14 @@ def test_64_router_ring_qualification(): ], ) def test_invalid_configuration(options): - from ngraph_sim.agents import ReferenceConfig + from netlab_sim.agents import ReferenceConfig with pytest.raises(ValueError): ReferenceConfig(**options) def test_invalid_link_control_family_and_lsa_metadata(): - from ngraph_sim.agents.reference import Lsa + from netlab_sim.agents.reference import Lsa with pytest.raises(ValueError, match='af=6'): c.Datagram('e0', 'hello', af=4, link_local=True) @@ -533,8 +533,8 @@ def test_invalid_link_control_family_and_lsa_metadata(): def test_out_of_order_refresh_does_not_extend_absolute_expiry(): from dataclasses import replace - from ngraph_sim.agents import ReferenceConfig - from ngraph_sim.agents.reference import Prefix + from netlab_sim.agents import ReferenceConfig + from netlab_sim.agents.reference import Prefix from tests.agents.fixtures import state, twins sim, _ = twins(config=ReferenceConfig(max_age=6, refresh_interval=2)) @@ -560,7 +560,7 @@ def test_out_of_order_refresh_does_not_extend_absolute_expiry(): def test_three_way_discovery_requires_our_id_in_peer_hello(): from dataclasses import replace - from ngraph_sim.agents.reference import Hello + from netlab_sim.agents.reference import Hello from tests.agents.fixtures import state, twins sim, _ = twins(size=2, edges=((0, 1),), numbered=False) diff --git a/tests/model/clos.py b/tests/model/clos.py index 20c113d..0e8f55c 100644 --- a/tests/model/clos.py +++ b/tests/model/clos.py @@ -1,7 +1,7 @@ """Clos fabric builder shared by tests and benchmarks (unnumbered, oracle IGP).""" -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network def build_clos( diff --git a/tests/model/test_addressing.py b/tests/model/test_addressing.py index f4ce85f..3dac3c1 100644 --- a/tests/model/test_addressing.py +++ b/tests/model/test_addressing.py @@ -2,7 +2,7 @@ import pytest -from ngraph_sim.model import addressing as a +from netlab_sim.model import addressing as a class TestMacAddress: diff --git a/tests/model/test_agent_contract.py b/tests/model/test_agent_contract.py index c2db20e..3255f0c 100644 --- a/tests/model/test_agent_contract.py +++ b/tests/model/test_agent_contract.py @@ -4,8 +4,8 @@ import pytest -from ngraph_sim.model import contracts as c -from ngraph_sim.model.contracts import ( +from netlab_sim.model import contracts as c +from netlab_sim.model.contracts import ( AgentConfig, AgentNode, AgentOutput, @@ -18,8 +18,8 @@ SessionOp, TimerOp, ) -from ngraph_sim.model.routing import Nexthop, Route -from ngraph_sim.model.state import StateDelta, validate_immutable +from netlab_sim.model.routing import Nexthop, Route +from netlab_sim.model.state import StateDelta, validate_immutable from tests.model.test_network import build_diamond REF = ClientId('ref', 0) @@ -114,7 +114,7 @@ def test_agent_node_compares_opaque_values_by_identity(self): calls = [] class Opaque: - __ngraph_sim_immutable__ = True + __netlab_sim_immutable__ = True def __eq__(self, other): calls.append(1) @@ -330,12 +330,12 @@ def fn(state): class TestRuntimeStubs: def test_simulation_binds_runtimes(self): - import ngraph_sim - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.runtime import Simulation net, R = build_diamond() net.add_agent('R1', Minimal()) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) assert sim.agents.generation('R1', 'ref') == ( net.state.devices['R1'].agents['ref'].generation ) diff --git a/tests/model/test_batch.py b/tests/model/test_batch.py index f47e833..e76197c 100644 --- a/tests/model/test_batch.py +++ b/tests/model/test_batch.py @@ -2,8 +2,8 @@ import pytest -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import tree_equal +from netlab_sim.model.network import Network +from netlab_sim.model.state import tree_equal def build(net): @@ -50,7 +50,7 @@ def test_construction_context(batched): def test_abort_restores_allocators_and_permanently_invalidates_handles(): - from ngraph_sim.model.entities import StaleHandleError + from netlab_sim.model.entities import StaleHandleError net = Network() existing = net.add_device('existing') @@ -126,7 +126,7 @@ def test_empty_and_reverted_batches_preserve_identity(): def test_snapshot_reads_are_immutable_and_read_your_writes(): - from ngraph_sim.model.state import validate_immutable + from netlab_sim.model.state import validate_immutable net = Network() with net.batch(): @@ -152,7 +152,7 @@ def test_snapshot_reads_are_immutable_and_read_your_writes(): def test_one_validation_delta_and_commit_time(monkeypatch): - import ngraph_sim.model.network as module + import netlab_sim.model.network as module net = Network() net.debug_validate = True @@ -198,7 +198,7 @@ def test_nested_batch_rejected_and_outer_aborts(): def test_final_validation_failure_aborts(monkeypatch): - import ngraph_sim.model.network as module + import netlab_sim.model.network as module net = Network() net.debug_validate = True @@ -253,8 +253,8 @@ def test_caught_operation_failure_does_not_leak_partial_link_or_allocators(): def test_bulk_routes_use_one_rib_apply_per_device_family(monkeypatch): - import ngraph_sim.model.routing as routing - from ngraph_sim.model.addressing import IPV4, IPV6 + import netlab_sim.model.routing as routing + from netlab_sim.model.addressing import IPV4, IPV6 original = routing.rib_apply calls = [] @@ -279,8 +279,8 @@ def apply(rib, **kw): def test_routes_sync_delete_upsert_match_sequential(): from dataclasses import replace - from ngraph_sim.model.addressing import IPV4 - from ngraph_sim.model.contracts import IGP + from netlab_sim.model.addressing import IPV4 + from netlab_sim.model.contracts import IGP def edit(net): d = net['a'] @@ -311,7 +311,7 @@ def edit(net): def test_builders_do_not_use_persistent_set_or_freeze_per_operation(monkeypatch): - from ngraph_sim.model.state import PMap, PMapBuilder + from netlab_sim.model.state import PMap, PMapBuilder net = Network() with net.batch(): @@ -339,7 +339,7 @@ def unexpected(*args, **kw): def test_pure_update_receives_immutable_staged_snapshot(): from dataclasses import replace - from ngraph_sim.model.state import validate_immutable + from netlab_sim.model.state import validate_immutable net = Network() with net.batch(): @@ -357,8 +357,8 @@ def update(root): def test_timed_runtime_sees_one_batch_commit(): - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.runtime import Simulation net = Network() build(net) @@ -380,7 +380,7 @@ def edit(): def test_update_boundaries_advance_inputs_after_each_staged_change(): - from ngraph_sim.model.addressing import IPV4 + from netlab_sim.model.addressing import IPV4 net = Network() a = net.add_device('a') @@ -403,8 +403,8 @@ def test_update_boundaries_advance_inputs_after_each_staged_change(): @pytest.mark.parametrize('af', [4, 6]) @pytest.mark.parametrize('method', ['converge', 'place']) def test_batch_rejects_derivations_without_changing_staged_inputs(timed, af, method): - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.runtime import Simulation net = Network() a = net.add_device('A') @@ -471,10 +471,10 @@ def test_uncaught_batch_derivation_aborts_provisional_entities(method): def test_batch_update_callback_invalidates_its_changed_inputs(timed, af): from dataclasses import replace - from ngraph_sim import Environment - from ngraph_sim.model.routing import rib_apply - from ngraph_sim.runtime import Simulation - from ngraph_sim.runtime.pipeline import fib_affected + from netlab_sim import Environment + from netlab_sim.model.routing import rib_apply + from netlab_sim.runtime import Simulation + from netlab_sim.runtime.pipeline import fib_affected net = Network() a = net.add_device('A', fib_delay=1) @@ -535,11 +535,11 @@ def add_route(root): @pytest.mark.parametrize('timed', [False, True]) @pytest.mark.parametrize('change', ['policy', 'link']) def test_reverted_batch_inputs_publish_no_delta(timed, change): - from ngraph_sim import Environment - from ngraph_sim.model.contracts import STATIC - from ngraph_sim.model.interfaces import OperState - from ngraph_sim.model.routing import ResolutionPolicy - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.model.contracts import STATIC + from netlab_sim.model.interfaces import OperState + from netlab_sim.model.routing import ResolutionPolicy + from netlab_sim.runtime import Simulation from tests.model.test_network import A, build_diamond net, devices = build_diamond() @@ -578,8 +578,8 @@ def test_reverted_batch_inputs_publish_no_delta(timed, change): def test_rib_snapshots_submit_only_pending_changed_rows(monkeypatch): from dataclasses import replace - import ngraph_sim.model.routing as routing - from ngraph_sim.model.addressing import IPV4, IPV6 + import netlab_sim.model.routing as routing + from netlab_sim.model.addressing import IPV4, IPV6 net = Network() a = net.add_device('A') @@ -624,8 +624,8 @@ def apply(rib, **kw): def test_rib_snapshot_add_delete_does_not_enumerate_existing_rows(monkeypatch): - from ngraph_sim.model.routing import RibState - from ngraph_sim.model.state import PMap + from netlab_sim.model.routing import RibState + from netlab_sim.model.state import PMap net = Network() a = net.add_device('A') @@ -691,8 +691,8 @@ def test_route_sync_fold_order_across_clients_matches_sequential(snapshot): from dataclasses import replace from random import Random - from ngraph_sim.model.contracts import IGP, STATIC - from ngraph_sim.model.routing import BLACKHOLE, Nexthop, Route + from netlab_sim.model.contracts import IGP, STATIC + from netlab_sim.model.routing import BLACKHOLE, Nexthop, Route rows = tuple( Route((0xC0000200 + i, 32), 4, client, 1, (Nexthop(special=BLACKHOLE),)) @@ -733,18 +733,18 @@ def test_reverted_inputs_inside_a_batch_still_resolve_in_the_timed_pipeline(): delta carries only the advanced epoch, which must still schedule the FIB.""" import dataclasses - import ngraph_sim - from ngraph_sim.model.routing import ResolutionPolicy - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.model.routing import ResolutionPolicy + from netlab_sim.runtime import Simulation from tests.model.test_network import build_diamond net, R = build_diamond() - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) original = net.state.devices['R1'].config.resolution_policy fib = R['R1'].fib(4) entry = fib.lookup( - __import__('ngraph_sim.model.addressing', fromlist=['to_int']).to_int( + __import__('netlab_sim.model.addressing', fromlist=['to_int']).to_int( '10.0.0.4' )[0] ) @@ -768,8 +768,8 @@ def edit(): sim.at(5, edit) sim.run_until(6) - from ngraph_sim.model.addressing import to_int - from ngraph_sim.model.contracts import STATIC + from netlab_sim.model.addressing import to_int + from netlab_sim.model.contracts import STATIC fib = R['R1'].fib(4) entry = fib.lookup(to_int('10.0.0.4')[0]) diff --git a/tests/model/test_flows.py b/tests/model/test_flows.py index b08f489..28378d1 100644 --- a/tests/model/test_flows.py +++ b/tests/model/test_flows.py @@ -1,9 +1,9 @@ import pytest -from ngraph_sim.model import flows -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import to_int -from ngraph_sim.model.flows import HASH, LOSSY, UNCONSTRAINED +from netlab_sim.model import flows +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import to_int +from netlab_sim.model.flows import HASH, LOSSY, UNCONSTRAINED from tests.model.test_network import build_diamond @@ -148,7 +148,7 @@ def test_microflows_spread_and_agree_with_fluid(self): assert r.demands['h'].delivered == pytest.approx(100e6) def test_hash_ttl_drop(self): - from ngraph_sim.model.packets import PacketTemplate + from netlab_sim.model.packets import PacketTemplate net, R = build_diamond() t = PacketTemplate(4, A('10.0.0.1'), A('10.0.0.4'), ttl=1) @@ -241,12 +241,12 @@ def test_removing_the_last_demand_empties_the_report(self): assert rep.max_utilization() == 0.0 def test_removing_the_last_demand_timed(self): - import ngraph_sim - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.runtime import Simulation net, R = build_diamond(min_links=2) net.add_demand('d1', 'R1', '10.0.0.4', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(5, lambda: net.remove_demand('d1')) sim.run_until(6) @@ -294,7 +294,7 @@ def test_lossy_applies_to_hash_demands(self): ) == pytest.approx(200e6) def test_numeric_device_names_are_not_edges(self): - from ngraph_sim.model.network import Network + from netlab_sim.model.network import Network net = Network() a, b = net.add_device('123'), net.add_device('R2') diff --git a/tests/model/test_flows_srv6.py b/tests/model/test_flows_srv6.py index b44e448..34696ae 100644 --- a/tests/model/test_flows_srv6.py +++ b/tests/model/test_flows_srv6.py @@ -5,13 +5,13 @@ import pytest -from ngraph_sim.model import flows -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import to_int -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.model.packets import SRH, IPv6Packet, PacketTemplate -from ngraph_sim.model.srv6 import PolicyRef +from netlab_sim.model import flows +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import to_int +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.model.packets import SRH, IPv6Packet, PacketTemplate +from netlab_sim.model.srv6 import PolicyRef def _chain(): diff --git a/tests/model/test_forwarding_srv6.py b/tests/model/test_forwarding_srv6.py index 334c3a8..fb83087 100644 --- a/tests/model/test_forwarding_srv6.py +++ b/tests/model/test_forwarding_srv6.py @@ -6,12 +6,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import to_int -from ngraph_sim.model.hashing import flow_label_for -from ngraph_sim.model.network import Network -from ngraph_sim.model.packets import ( +from netlab_sim import Environment +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import to_int +from netlab_sim.model.hashing import flow_label_for +from netlab_sim.model.network import Network +from netlab_sim.model.packets import ( AFTER_ENCAP, ETHERTYPE_IPV4, ETHERTYPE_IPV6, @@ -30,8 +30,8 @@ encapsulate, ip_bytes, ) -from ngraph_sim.model.routing import SRV6_LOCAL_NH, Nexthop -from ngraph_sim.model.srv6 import ( +from netlab_sim.model.routing import SRV6_LOCAL_NH, Nexthop +from netlab_sim.model.srv6 import ( END, END_B6_ENCAPS, END_DT4, @@ -56,7 +56,7 @@ LocalSid, Srv6Encap, ) -from ngraph_sim.runtime import Simulation +from netlab_sim.runtime import Simulation def address(text): @@ -508,7 +508,7 @@ def test_timed_send_and_trace_share_interpreter(compressed): def test_invalid_csid_structure_becomes_modeled_drop(): - from ngraph_sim.model.srv6 import SidStructure + from netlab_sim.model.srv6 import SidStructure net, routers, _ = path_network(compressed=True) install_sid( @@ -537,7 +537,7 @@ def test_invalid_csid_structure_becomes_modeled_drop(): ], ) def test_next_csid_uses_matched_sid_width(structure, da, shifted): - from ngraph_sim.model import srv6 + from netlab_sim.model import srv6 net, routers, _ = path_network(compressed=True) layout = getattr(srv6, structure) @@ -627,7 +627,7 @@ def test_cross_connect_checks_l3_and_neighbor(): def test_headend_local_cross_connect_over_bundle_hashes_shifted_outer(): - from ngraph_sim.model.hashing import BalancerKind + from netlab_sim.model.hashing import BalancerKind net, routers, _ = path_network(compressed=True) net.add_lag( @@ -718,7 +718,7 @@ def test_sr_member_unavailable_precedes_mtu_without_changing_plain_ip(monkeypatc def srdb_path_network(*, compressed): """Use G1's public SR-DB API to produce the same acceptance path.""" - from ngraph_sim.model.contracts import STATIC + from netlab_sim.model.contracts import STATIC net, routers, encap = path_network(compressed=compressed) for name, router in routers.items(): @@ -754,7 +754,7 @@ def srdb_path_network(*, compressed): @pytest.mark.parametrize('compressed', [False, True]) @pytest.mark.parametrize('af', [4, 6]) def test_public_srdb_rows_drive_trace_and_timed_send(compressed, af): - from ngraph_sim.model.contracts import SRV6_LOCAL + from netlab_sim.model.contracts import SRV6_LOCAL net, routers, encap = srdb_path_network(compressed=compressed) assert net.validate() == [] @@ -799,7 +799,7 @@ def test_public_srdb_withdrawal_keeps_unknown_cover_and_restore_recovers(): @pytest.mark.parametrize('compressed,wire', [(False, 109.8e6), (True, 107.4e6)]) def test_public_srdb_hash_placement_uses_actual_transmitted_headers(compressed, wire): - from ngraph_sim.model import flows + from netlab_sim.model import flows net, _, _ = srdb_path_network(compressed=compressed) net.add_demand( diff --git a/tests/model/test_igp.py b/tests/model/test_igp.py index fd8c261..feaf5e5 100644 --- a/tests/model/test_igp.py +++ b/tests/model/test_igp.py @@ -4,14 +4,14 @@ import pytest -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import igp -from ngraph_sim.model.addressing import IPV4, IPV6, to_int -from ngraph_sim.model.contracts import IGP, IGP_PROFILE -from ngraph_sim.model.igp import oracle_igp, shortest_path_routes -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import Nexthop, RibState, Route, rib_apply -from ngraph_sim.model.state import NetworkState +from netlab_sim.model import forwarding as fw +from netlab_sim.model import igp +from netlab_sim.model.addressing import IPV4, IPV6, to_int +from netlab_sim.model.contracts import IGP, IGP_PROFILE +from netlab_sim.model.igp import oracle_igp, shortest_path_routes +from netlab_sim.model.network import Network +from netlab_sim.model.routing import Nexthop, RibState, Route, rib_apply +from netlab_sim.model.state import NetworkState from tests.model.clos import build_clos diff --git a/tests/model/test_interfaces.py b/tests/model/test_interfaces.py index d717995..4a12b23 100644 --- a/tests/model/test_interfaces.py +++ b/tests/model/test_interfaces.py @@ -1,8 +1,8 @@ import pytest -from ngraph_sim.model import interfaces as ifc -from ngraph_sim.model.addressing import IPV4, IPV6 -from ngraph_sim.model.interfaces import ( +from netlab_sim.model import interfaces as ifc +from netlab_sim.model.addressing import IPV4, IPV6 +from netlab_sim.model.interfaces import ( AdminState, BundleInput, EthernetConfig, @@ -23,7 +23,7 @@ derive_loopback, l3_usable, ) -from ngraph_sim.model.links import ( +from netlab_sim.model.links import ( LINK_FAILED, LINK_UP, LinkConfig, diff --git a/tests/model/test_l3_scoped.py b/tests/model/test_l3_scoped.py index e533a21..24462b4 100644 --- a/tests/model/test_l3_scoped.py +++ b/tests/model/test_l3_scoped.py @@ -5,15 +5,15 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import derive -from ngraph_sim.model.addressing import IPV4, IPV6, to_int -from ngraph_sim.model.contracts import CONNECTED, LOCAL -from ngraph_sim.model.interfaces import AdminState, OperState -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import PMap, StateDelta, tree_equal, validate_immutable -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.pipeline import carrier_affected, l3_affected, lag_affected +from netlab_sim import Environment +from netlab_sim.model import derive +from netlab_sim.model.addressing import IPV4, IPV6, to_int +from netlab_sim.model.contracts import CONNECTED, LOCAL +from netlab_sim.model.interfaces import AdminState, OperState +from netlab_sim.model.network import Network +from netlab_sim.model.state import PMap, StateDelta, tree_equal, validate_immutable +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.pipeline import carrier_affected, l3_affected, lag_affected from tests.model.test_network import build_diamond @@ -281,8 +281,8 @@ def test_carrier_and_lag_invalidation_do_not_enumerate_unrelated_interfaces( def no_scan(*args): pytest.fail('an interface change must use its direct bundle/peer lookup') - monkeypatch.setattr('ngraph_sim.runtime.pipeline._ethernets_of', no_scan) - monkeypatch.setattr('ngraph_sim.runtime.pipeline._bundles_of', no_scan) + monkeypatch.setattr('netlab_sim.runtime.pipeline._ethernets_of', no_scan) + monkeypatch.setattr('netlab_sim.runtime.pipeline._bundles_of', no_scan) assert carrier_affected(delta, net.state) == {('R1', 'eth1'), ('R2', 'eth1')} assert lag_affected(delta, net.state) == {('R1', 'Po1'), ('R2', 'Po1')} diff --git a/tests/model/test_lpm.py b/tests/model/test_lpm.py index 6b54e08..b4904f8 100644 --- a/tests/model/test_lpm.py +++ b/tests/model/test_lpm.py @@ -3,7 +3,7 @@ import pytest -from ngraph_sim.model.lpm import FrozenPrefixTable, PrefixTable +from netlab_sim.model.lpm import FrozenPrefixTable, PrefixTable def _brute(prefixes, addr_int, bits, *, exclude=(), min_len=0): @@ -114,7 +114,7 @@ def test_items_sorted(self): def test_frozen_shards_are_not_writable(): from types import MappingProxyType - from ngraph_sim.model.lpm import PrefixTable + from netlab_sim.model.lpm import PrefixTable t = PrefixTable(32) t.insert(10, 32, 'a') @@ -129,7 +129,7 @@ def test_frozen_shards_are_not_writable(): def test_frozen_table_copies_constructor_input(): - from ngraph_sim.model.lpm import FrozenPrefixTable + from netlab_sim.model.lpm import FrozenPrefixTable tables = {32: {10: 'a'}} frozen = FrozenPrefixTable(32, tables) @@ -140,7 +140,7 @@ def test_frozen_table_copies_constructor_input(): def test_persistent_prefix_shards_keep_frozen_contract(): - from ngraph_sim.model.state import PMap + from netlab_sim.model.state import PMap rows = PMap({i: str(i) for i in range(1000)}) frozen = FrozenPrefixTable._owned(32, {32: rows}) diff --git a/tests/model/test_lpm_scale.py b/tests/model/test_lpm_scale.py index 07e7e3e..dbc637a 100644 --- a/tests/model/test_lpm_scale.py +++ b/tests/model/test_lpm_scale.py @@ -5,7 +5,7 @@ import pytest -from ngraph_sim.model.lpm import PrefixTable +from netlab_sim.model.lpm import PrefixTable @pytest.mark.parametrize('bits', [32, 128]) diff --git a/tests/model/test_network.py b/tests/model/test_network.py index b987941..e7fd7b0 100644 --- a/tests/model/test_network.py +++ b/tests/model/test_network.py @@ -1,14 +1,14 @@ import pytest -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import IPV4, to_int -from ngraph_sim.model.contracts import CONNECTED, LOCAL, STATIC -from ngraph_sim.model.entities import StaleHandleError -from ngraph_sim.model.interfaces import OperState, StateReason -from ngraph_sim.model.links import LINK_FAILED -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import Nexthop -from ngraph_sim.model.state import PMap +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import IPV4, to_int +from netlab_sim.model.contracts import CONNECTED, LOCAL, STATIC +from netlab_sim.model.entities import StaleHandleError +from netlab_sim.model.interfaces import OperState, StateReason +from netlab_sim.model.links import LINK_FAILED +from netlab_sim.model.network import Network +from netlab_sim.model.routing import Nexthop +from netlab_sim.model.state import PMap def A(text): @@ -291,7 +291,7 @@ def test_handles_and_generations(self): assert isinstance(net.state.devices, PMap) def test_parse_nexthops(self): - from ngraph_sim.model.entities import parse_nexthop + from netlab_sim.model.entities import parse_nexthop assert parse_nexthop('10.0.0.2').is_recursive assert parse_nexthop('eth3') == Nexthop.via('eth3') diff --git a/tests/model/test_nht.py b/tests/model/test_nht.py index 23cec14..192badd 100644 --- a/tests/model/test_nht.py +++ b/tests/model/test_nht.py @@ -4,10 +4,10 @@ import pytest -import ngraph_sim -from ngraph_sim.model import nht -from ngraph_sim.model.addressing import IPV4, IPV6, prefix_to_int -from ngraph_sim.model.contracts import ( +import netlab_sim +from netlab_sim.model import nht +from netlab_sim.model.addressing import IPV4, IPV6, prefix_to_int +from netlab_sim.model.contracts import ( IGP, LOCAL, STATIC, @@ -15,10 +15,10 @@ ClientProfile, NhtKey, ) -from ngraph_sim.model.derive import DeviceContext, derive_fib -from ngraph_sim.model.routing import Nexthop, ResolutionPolicy, Route -from ngraph_sim.model.state import PMap, StateDelta, validate_immutable -from ngraph_sim.runtime import Simulation +from netlab_sim.model.derive import DeviceContext, derive_fib +from netlab_sim.model.routing import Nexthop, ResolutionPolicy, Route +from netlab_sim.model.state import PMap, StateDelta, validate_immutable +from netlab_sim.runtime import Simulation from tests.model.test_network import A, build_diamond @@ -238,7 +238,7 @@ def test_cost_only_change_keeps_identical_fib_but_new_result(diamond): def test_delayed_fib_rib_and_installed_are_separate(diamond): net, dev = diamond - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) dev.configure(fib_delay=2) sim.run_until(3) client, k = dev.nht_client(), key('192.0.2.1') @@ -428,8 +428,8 @@ def test_scoped_installed_answer_and_unregistered_client(diamond): def test_bounded_prefix_probes_on_large_rib(diamond): from collections.abc import Mapping - from ngraph_sim.model.lpm import FrozenPrefixTable - from ngraph_sim.model.routing import RibState, rib_apply + from netlab_sim.model.lpm import FrozenPrefixTable + from netlab_sim.model.routing import RibState, rib_apply net, dev = diamond base = A('198.18.0.0') @@ -485,8 +485,8 @@ def benchmark_refresh(): import statistics import time - from ngraph_sim.model.contracts import NhtTable - from ngraph_sim.model.routing import RibState, rib_apply + from netlab_sim.model.contracts import NhtTable + from netlab_sim.model.routing import RibState, rib_apply net, routers = build_diamond() net.converge() diff --git a/tests/model/test_nht_agent.py b/tests/model/test_nht_agent.py index 5e59259..a752a03 100644 --- a/tests/model/test_nht_agent.py +++ b/tests/model/test_nht_agent.py @@ -3,12 +3,12 @@ from dataclasses import dataclass, replace from ipaddress import IPv6Address -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.routing import Nexthop, Route -from ngraph_sim.model.state import validate_immutable -from ngraph_sim.runtime import Simulation +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model import srv6 as sr +from netlab_sim.model.routing import Nexthop, Route +from netlab_sim.model.state import validate_immutable +from netlab_sim.runtime import Simulation from tests.model.test_network import A, build_diamond from tests.model.test_nht import route from tests.model.test_nht_context import scoped_pair diff --git a/tests/model/test_nht_context.py b/tests/model/test_nht_context.py index 7c72882..c8d9e2f 100644 --- a/tests/model/test_nht_context.py +++ b/tests/model/test_nht_context.py @@ -5,17 +5,17 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import nht -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.contracts import STATIC, NhtKey -from ngraph_sim.model.derive import DeviceContext -from ngraph_sim.model.entities import Device -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import Nexthop, ResolutionPolicy -from ngraph_sim.model.state import DeviceState, NetworkState, validate_immutable -from ngraph_sim.runtime import Simulation +from netlab_sim import Environment +from netlab_sim.model import nht +from netlab_sim.model import srv6 as sr +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.contracts import STATIC, NhtKey +from netlab_sim.model.derive import DeviceContext +from netlab_sim.model.entities import Device +from netlab_sim.model.network import Network +from netlab_sim.model.routing import Nexthop, ResolutionPolicy +from netlab_sim.model.state import DeviceState, NetworkState, validate_immutable +from netlab_sim.runtime import Simulation from tests.model.test_network import A, build_diamond from tests.model.test_policies import diamond, policy diff --git a/tests/model/test_packets_hashing.py b/tests/model/test_packets_hashing.py index 950e105..04feb1b 100644 --- a/tests/model/test_packets_hashing.py +++ b/tests/model/test_packets_hashing.py @@ -3,10 +3,10 @@ import pytest -from ngraph_sim.model import hashing as h -from ngraph_sim.model import packets as pk -from ngraph_sim.model.addressing import IPV4, IPV6 -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model import hashing as h +from netlab_sim.model import packets as pk +from netlab_sim.model.addressing import IPV4, IPV6 +from netlab_sim.model.state import validate_immutable class TestPackets: diff --git a/tests/model/test_packets_srv6.py b/tests/model/test_packets_srv6.py index cbd2309..000f00e 100644 --- a/tests/model/test_packets_srv6.py +++ b/tests/model/test_packets_srv6.py @@ -4,10 +4,10 @@ import pytest -from ngraph_sim.model import packets as pk -from ngraph_sim.model.hashing import LoadBalancer, flow_label_for -from ngraph_sim.model.srv6 import H_ENCAPS, H_ENCAPS_RED -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model import packets as pk +from netlab_sim.model.hashing import LoadBalancer, flow_label_for +from netlab_sim.model.srv6 import H_ENCAPS, H_ENCAPS_RED +from netlab_sim.model.state import validate_immutable def inner_packet(af=4, ttl=64): diff --git a/tests/model/test_policies.py b/tests/model/test_policies.py index 7a7e563..6125ab2 100644 --- a/tests/model/test_policies.py +++ b/tests/model/test_policies.py @@ -5,15 +5,15 @@ import pytest -from ngraph_sim.model import flows -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.interfaces import EthernetNode, PortChannelNode -from ngraph_sim.model.network import Network -from ngraph_sim.model.packets import IPv4Packet -from ngraph_sim.model.routing import Nexthop, ResolutionPolicy +from netlab_sim.model import flows +from netlab_sim.model import forwarding as fw +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.interfaces import EthernetNode, PortChannelNode +from netlab_sim.model.network import Network +from netlab_sim.model.packets import IPv4Packet +from netlab_sim.model.routing import Nexthop, ResolutionPolicy from tests.model.test_network import A, build_diamond @@ -346,7 +346,7 @@ def test_strict_validation_queries_the_encoded_address_at_intermediate_owners(): assert net.placement.delivered_total == 100e6 status = state_of(routers, p) container = status.valid_lists[0][2][0] - from ngraph_sim.model.srv6_compress import shift_csid + from netlab_sim.model.srv6_compress import shift_csid head = next( s for s in routers['R1'].node.srv6_sids.sids.values() if s.interface == 'Po1' @@ -602,7 +602,7 @@ def test_candidate_ties_and_opt_in_installed_preference(): @pytest.mark.parametrize('size', [1000, 1220]) def test_production_fluid_encap_mtu_matches_hash(size): - from ngraph_sim.model import flows + from netlab_sim.model import flows from tests.model.test_forwarding_srv6 import path_network net, routers, _ = path_network() @@ -622,7 +622,7 @@ def test_production_fluid_encap_mtu_matches_hash(size): def test_fluid_class_sorting_optional_srh_and_inner_records(): - from ngraph_sim.model.packets import SRH, PacketTemplate + from netlab_sim.model.packets import SRH, PacketTemplate net, _ = diamond() base = PacketTemplate(6, A('2001:db8::1'), A('2001:db8::4')) @@ -640,9 +640,9 @@ def test_fluid_class_sorting_optional_srh_and_inner_records(): @pytest.mark.parametrize('mode', [1, 2]) @pytest.mark.parametrize('lossy', [False, True]) def test_nested_template_uses_innermost_payload_for_rate(mode, lossy): - from ngraph_sim.model import flows - from ngraph_sim.model.network import Network - from ngraph_sim.model.packets import SRH, PacketTemplate + from netlab_sim.model import flows + from netlab_sim.model.network import Network + from netlab_sim.model.packets import SRH, PacketTemplate net = Network() a, b = net.add_device('a'), net.add_device('b') @@ -665,8 +665,8 @@ def test_nested_template_uses_innermost_payload_for_rate(mode, lossy): def test_nested_template_validates_innermost_payload_only(): - from ngraph_sim.model.flows import Demand - from ngraph_sim.model.packets import PacketTemplate + from netlab_sim.model.flows import Demand + from netlab_sim.model.packets import PacketTemplate outer = PacketTemplate( 6, 1, 2, payload_size=0, inner=PacketTemplate(4, 1, 2, payload_size=2000) @@ -686,8 +686,8 @@ def test_nested_template_validates_innermost_payload_only(): def test_steering_precedence_and_demand_override(): - from ngraph_sim.model.network import _View - from ngraph_sim.model.packets import L4Header + from netlab_sim.model.network import _View + from netlab_sim.model.packets import L4Header net, routers = diamond() p = policy(routers) diff --git a/tests/model/test_routing.py b/tests/model/test_routing.py index 6c7c7ed..9fd6c5a 100644 --- a/tests/model/test_routing.py +++ b/tests/model/test_routing.py @@ -5,11 +5,11 @@ import pytest -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import routing as rt -from ngraph_sim.model.addressing import IPV4, IPV6, prefix_to_int, to_int -from ngraph_sim.model.contracts import CONNECTED, IGP, STATIC, ClientId, ClientProfile -from ngraph_sim.model.routing import ( +from netlab_sim.model import forwarding as fw +from netlab_sim.model import routing as rt +from netlab_sim.model.addressing import IPV4, IPV6, prefix_to_int, to_int +from netlab_sim.model.contracts import CONNECTED, IGP, STATIC, ClientId, ClientProfile +from netlab_sim.model.routing import ( Nexthop, ResolutionPolicy, RibState, @@ -18,7 +18,7 @@ rib_apply, row_status, ) -from ngraph_sim.model.state import PMap, validate_immutable +from netlab_sim.model.state import PMap, validate_immutable def P(text): @@ -49,9 +49,9 @@ def routing_fingerprints(kind): Used by the A/B/A harness too; no versions, object addresses or hashes. """ - import ngraph_sim - from ngraph_sim.runtime import Simulation - from ngraph_sim.runtime.timeline import RouteEvent + import netlab_sim + from netlab_sim.runtime import Simulation + from netlab_sim.runtime.timeline import RouteEvent from tests.model.clos import build_clos from tests.model.test_network import build_diamond @@ -62,7 +62,7 @@ def routing_fingerprints(kind): else: net = build_clos(8, 4) lid = sorted(net.links)[0] - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) fibs, placements = [], [] for time, op in ((0, None), (1, net.links[lid].fail), (2, net.links[lid].restore)): if op is not None: @@ -186,7 +186,7 @@ def test_route_validation(self): @pytest.mark.parametrize('mixed', [False, True]) @pytest.mark.parametrize('foreign', [ClientId('bgp', 7), ClientId('static', 1)]) def test_client_rejects_foreign_deletions_atomically(batched, mixed, foreign): - from ngraph_sim.model.network import Network + from netlab_sim.model.network import Network net = Network() net.register_client(ClientProfile(foreign, distance=20)) @@ -684,7 +684,7 @@ def test_row_status(self): def test_unchanged_inputs_are_not_re_resolved(monkeypatch): """A converge with no input change must not resolve any FIB again.""" - from ngraph_sim.model import derive + from netlab_sim.model import derive from tests.model.test_network import build_diamond net, R = build_diamond() @@ -714,7 +714,7 @@ class TestCrossFamily: @staticmethod def build(): - from ngraph_sim.model.network import Network + from netlab_sim.model.network import Network net = Network() a, b = net.add_device('A'), net.add_device('B') @@ -750,12 +750,12 @@ def test_clock_free(self): assert self.entry(a) is None def test_timed(self): - import ngraph_sim - from ngraph_sim.runtime import Simulation - from ngraph_sim.runtime.timeline import FibEvent + import netlab_sim + from netlab_sim.runtime import Simulation + from netlab_sim.runtime.timeline import FibEvent net, a = self.build() - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) assert self.entry(a) is not None names = [ @@ -772,7 +772,7 @@ def test_timed(self): def test_dependencies_are_per_prefix_not_cumulative(): """Independent routes must not inherit each other's dependencies.""" - from ngraph_sim.model import derive + from netlab_sim.model import derive from tests.model.test_network import build_diamond net, R = build_diamond() diff --git a/tests/model/test_routing_srv6.py b/tests/model/test_routing_srv6.py index 58aead7..78b2c88 100644 --- a/tests/model/test_routing_srv6.py +++ b/tests/model/test_routing_srv6.py @@ -4,15 +4,15 @@ import pytest -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.derive import DeviceContext -from ngraph_sim.model.routing import ( +from netlab_sim.model import forwarding as fw +from netlab_sim.model.derive import DeviceContext +from netlab_sim.model.routing import ( SRV6_LOCAL_NH, Nexthop, ResolutionPolicy, resolve_fib, ) -from ngraph_sim.model.srv6 import ( +from netlab_sim.model.srv6 import ( END, END_DT46, END_X, @@ -21,7 +21,7 @@ LocalSid, Srv6Encap, ) -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model.state import validate_immutable from tests.model.test_forwarding_srv6 import ( address, inner_packet, @@ -222,7 +222,7 @@ def test_deterministic_order_for_different_encaps_on_same_adjacency(): @pytest.mark.parametrize('forwarding_v4', [False, True]) @pytest.mark.parametrize('behavior', [END_X, END_DT46]) def test_headend_decap_compilation_respects_inner_family(af, forwarding_v4, behavior): - from ngraph_sim.model.srv6 import UNCOMPRESSED, USD + from netlab_sim.model.srv6 import UNCOMPRESSED, USD net, routers, _ = path_network() r1 = routers['R1'] diff --git a/tests/model/test_s0_locator_consumer.py b/tests/model/test_s0_locator_consumer.py index a372171..12d4a86 100644 --- a/tests/model/test_s0_locator_consumer.py +++ b/tests/model/test_s0_locator_consumer.py @@ -5,10 +5,10 @@ import pytest -from ngraph_sim.model import network as nw -from ngraph_sim.model import srv6 -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.state import PMap, validate_immutable +from netlab_sim.model import network as nw +from netlab_sim.model import srv6 +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.state import PMap, validate_immutable @pytest.mark.parametrize('ipv6', [False, True]) diff --git a/tests/model/test_scale_fingerprints.py b/tests/model/test_scale_fingerprints.py index dfc573b..22fcc39 100644 --- a/tests/model/test_scale_fingerprints.py +++ b/tests/model/test_scale_fingerprints.py @@ -11,8 +11,8 @@ import pytest -from ngraph_sim.model.flows import HASH -from ngraph_sim.model.state import PMap +from netlab_sim.model.flows import HASH +from netlab_sim.model.state import PMap from tests.model.clos import build_clos from tests.model.test_network import build_diamond diff --git a/tests/model/test_sharded_maps.py b/tests/model/test_sharded_maps.py index 91c700e..4bdf75f 100644 --- a/tests/model/test_sharded_maps.py +++ b/tests/model/test_sharded_maps.py @@ -7,8 +7,8 @@ import pytest -from ngraph_sim.model.derive import bump_epochs -from ngraph_sim.model.state import ( +from netlab_sim.model.derive import bump_epochs +from netlab_sim.model.state import ( Allocators, DeviceState, NetworkState, @@ -247,7 +247,7 @@ def test_iteration_handles_incomparable_keys_and_is_hash_seed_independent(monkey assert list(m.keys()) == keys assert list(m.values()) == list(range(4)) script = """ -from ngraph_sim.model.state import PMap +from netlab_sim.model.state import PMap m = PMap((f'r{i}', i) for i in range(700)) m = m.remove('r10').set('r10', -1).set('r1', 42) assert list(m) == [f'r{i}' for i in range(700) if i != 10] + ['r10'] @@ -264,7 +264,7 @@ def test_iteration_handles_incomparable_keys_and_is_hash_seed_independent(monkey def test_placement_cache_comparison_is_shard_scoped(): - from ngraph_sim.model.flows import DepToken, _same_cache + from netlab_sim.model.flows import DepToken, _same_cache from tests.model.test_network import build_diamond net, _ = build_diamond() @@ -292,9 +292,9 @@ def test_placement_cache_comparison_is_shard_scoped(): def test_timeline_route_comparison_does_not_enumerate_whole_row_map(monkeypatch): - from ngraph_sim.model.contracts import STATIC - from ngraph_sim.model.routing import Nexthop, RibState, Route, rib_apply - from ngraph_sim.runtime.timeline import RouteEvent, _route_events + from netlab_sim.model.contracts import STATIC + from netlab_sim.model.routing import Nexthop, RibState, Route, rib_apply + from netlab_sim.runtime.timeline import RouteEvent, _route_events rows = tuple( Route((i, 32), 4, STATIC, 1, (Nexthop.blackhole(),)) for i in range(2000) diff --git a/tests/model/test_srdb_source.py b/tests/model/test_srdb_source.py index b0db65e..4983381 100644 --- a/tests/model/test_srdb_source.py +++ b/tests/model/test_srdb_source.py @@ -4,9 +4,9 @@ import pytest -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import AgentNode, ClientId, RemoteSid, SrDbView -from ngraph_sim.model.state import PMap +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import AgentNode, ClientId, RemoteSid, SrDbView +from netlab_sim.model.state import PMap from tests.model.test_policies import diamond, policy, state_of @@ -31,7 +31,7 @@ def apply(state): def claims(routers): sids, locators = [], [] - from ngraph_sim.model.srv6 import _PolicyValidator + from netlab_sim.model.srv6 import _PolicyValidator oracle = _PolicyValidator(routers['R1'].network.state, 'R1') for name, dev in routers.items(): @@ -130,7 +130,7 @@ def test_view_advertisements_and_adjacency_down(compressed): def test_stale_view_stays_valid_when_oracle_rejects_remote_shadowing(): from ipaddress import IPv6Address - from ngraph_sim.model.routing import Nexthop + from netlab_sim.model.routing import Nexthop net, routers = diamond(compressed=False) p, terminal = literal_policy(routers) @@ -150,7 +150,7 @@ def test_stale_view_stays_valid_when_oracle_rejects_remote_shadowing(): def test_agent_validation_never_reads_remote_rib_or_interfaces(monkeypatch): - from ngraph_sim.model.derive import DeviceContext + from netlab_sim.model.derive import DeviceContext net, routers = diamond(compressed=False) p, _ = literal_policy(routers) @@ -186,7 +186,7 @@ def test_missing_locator_and_endpoint_claims_are_unknown(): def test_relaxed_local_resolution_never_upgrades_unknown_agent_claim(): - from ngraph_sim.model.routing import ResolutionPolicy + from netlab_sim.model.routing import ResolutionPolicy net, routers = diamond(compressed=False) p, _ = literal_policy(routers) @@ -202,7 +202,7 @@ def test_relaxed_local_resolution_never_upgrades_unknown_agent_claim(): def test_unpublished_view_and_nht_registration_do_not_advance_epochs(): - from ngraph_sim.model.contracts import STATIC, NhtKey + from netlab_sim.model.contracts import STATIC, NhtKey from tests.model.test_network import A net, routers = diamond(compressed=False) diff --git a/tests/model/test_srv6_compress.py b/tests/model/test_srv6_compress.py index 1334d8a..27bbad6 100644 --- a/tests/model/test_srv6_compress.py +++ b/tests/model/test_srv6_compress.py @@ -5,9 +5,9 @@ import pytest -from ngraph_sim.model import packets as pk -from ngraph_sim.model import srv6_compress as c -from ngraph_sim.model.srv6 import ( +from netlab_sim.model import packets as pk +from netlab_sim.model import srv6_compress as c +from netlab_sim.model.srv6 import ( F3216_COMPOSITE, F3216_GIB, F3216_LIB, diff --git a/tests/model/test_srv6_contract.py b/tests/model/test_srv6_contract.py index 8187965..f7fc5b7 100644 --- a/tests/model/test_srv6_contract.py +++ b/tests/model/test_srv6_contract.py @@ -4,8 +4,8 @@ import pytest -from ngraph_sim.model import srv6 -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model import srv6 +from netlab_sim.model.state import validate_immutable def test_structures_and_formats(): @@ -41,7 +41,7 @@ def test_records_are_immutable_tree_leaves(): ) policy = srv6.SrPolicy( srv6.SrPolicy.__dataclass_fields__['owner'].type - and __import__('ngraph_sim.model.contracts', fromlist=['STATIC']).STATIC, + and __import__('netlab_sim.model.contracts', fromlist=['STATIC']).STATIC, 10, 0x20010DB8 << 96 | 4, candidate_paths=( diff --git a/tests/model/test_srv6_db.py b/tests/model/test_srv6_db.py index b0d9fc7..fe5c9d9 100644 --- a/tests/model/test_srv6_db.py +++ b/tests/model/test_srv6_db.py @@ -5,14 +5,14 @@ import pytest -from ngraph_sim.model import derive, srv6 -from ngraph_sim.model.addressing import IPV6 -from ngraph_sim.model.contracts import SRV6_LOCAL, STATIC, ClientId, ClientProfile -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import SRV6_LOCAL_NH, UNREACHABLE -from ngraph_sim.model.srv6 import END, END_X, F3216_GIB, F3216_LIB, NEXT_CSID -from ngraph_sim.model.state import PMap, validate_immutable +from netlab_sim.model import derive, srv6 +from netlab_sim.model.addressing import IPV6 +from netlab_sim.model.contracts import SRV6_LOCAL, STATIC, ClientId, ClientProfile +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.model.routing import SRV6_LOCAL_NH, UNREACHABLE +from netlab_sim.model.srv6 import END, END_X, F3216_GIB, F3216_LIB, NEXT_CSID +from netlab_sim.model.state import PMap, validate_immutable def test_allocator_is_atomic_and_fork_local(): @@ -453,8 +453,8 @@ def test_policy_index_tracks_fork_batch_and_device_deletion(): def test_active_sid_takes_precedence_over_unknown_cover( ranges, structure, sid_text, cover_length ): - from ngraph_sim.model import forwarding as fw - from ngraph_sim.model import packets + from netlab_sim.model import forwarding as fw + from netlab_sim.model import packets net = Network() dev = f3216(net, ranges=ranges) @@ -567,7 +567,7 @@ def test_unknown_cover_subtracts_overlapping_exclusions_across_blocks(): def deletion_network(mode, dependent): - from ngraph_sim.model.packets import PacketTemplate + from netlab_sim.model.packets import PacketTemplate net = Network() victim, peer = net.add_device('R1'), net.add_device('R2') @@ -706,7 +706,7 @@ def test_device_deletion_uses_configured_ownership_even_when_unreachable( @pytest.mark.parametrize('mode', [1, 2], ids=['FLUID', 'HASH']) def test_deletion_does_not_claim_peer_subnet_or_overridden_destination(mode): - from ngraph_sim.model.packets import PacketTemplate + from netlab_sim.model.packets import PacketTemplate net, victim = deletion_network(mode, 'destination-v4') net.remove_demand('dependent') diff --git a/tests/model/test_srv6_invalidation.py b/tests/model/test_srv6_invalidation.py index 0049ad4..0e8d162 100644 --- a/tests/model/test_srv6_invalidation.py +++ b/tests/model/test_srv6_invalidation.py @@ -4,11 +4,11 @@ import pytest -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import Nexthop, RibState +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.model.routing import Nexthop, RibState from tests.model.test_network import A from tests.model.test_policies import diamond, state_of from tests.model.test_srdb_source import literal_policy diff --git a/tests/model/test_state.py b/tests/model/test_state.py index 43104a2..1c9fab8 100644 --- a/tests/model/test_state.py +++ b/tests/model/test_state.py @@ -2,8 +2,8 @@ import pytest -from ngraph_sim.model import state as st -from ngraph_sim.model.state import ( +from netlab_sim.model import state as st +from netlab_sim.model.state import ( Allocators, DeviceState, FloatArray, @@ -194,7 +194,7 @@ def test_canon_and_tree_equal(self): def test_builder_detaches_from_published_map(): - from ngraph_sim.model.state import PMap + from netlab_sim.model.state import PMap b = PMap({'a': 1}).builder() b.set('a', 2) @@ -222,7 +222,7 @@ def test_traffic_class_change_is_not_empty(): def test_debug_validation_accepts_frozen_prefix_tables(): - from ngraph_sim.model.addressing import to_int + from netlab_sim.model.addressing import to_int from tests.model.test_network import build_diamond net, R = build_diamond() @@ -235,8 +235,8 @@ def test_debug_validation_accepts_frozen_prefix_tables(): def test_debug_validation_rejects_mutable_prefix_table_builders(): import dataclasses - from ngraph_sim.model.lpm import PrefixTable - from ngraph_sim.model.state import validate_immutable + from netlab_sim.model.lpm import PrefixTable + from netlab_sim.model.state import validate_immutable from tests.model.test_network import build_diamond net, R = build_diamond() diff --git a/tests/model/test_trace.py b/tests/model/test_trace.py index 1edfb6b..2fd2873 100644 --- a/tests/model/test_trace.py +++ b/tests/model/test_trace.py @@ -1,7 +1,7 @@ -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import IPV4, to_int -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.packets import PacketTemplate +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import IPV4, to_int +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.packets import PacketTemplate from tests.model.test_network import build_diamond @@ -71,7 +71,7 @@ def test_mac_mismatch_and_loop(self): net, R = build_diamond() net.add_source(oracle_igp) net.converge() - from ngraph_sim.model.packets import ETHERTYPE_IPV4, EthernetFrame + from netlab_sim.model.packets import ETHERTYPE_IPV4, EthernetFrame view = net.view('R3') frame = EthernetFrame(0x1234, 0x5678, ETHERTYPE_IPV4, probe()) diff --git a/tests/model/test_usid.py b/tests/model/test_usid.py index f332a62..c337cf7 100644 --- a/tests/model/test_usid.py +++ b/tests/model/test_usid.py @@ -10,13 +10,13 @@ import pytest -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.contracts import SRV6_LOCAL, STATIC -from ngraph_sim.model.hashing import flow_label_for -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network -from ngraph_sim.model.packets import ( +from netlab_sim.model import forwarding as fw +from netlab_sim.model import srv6 as sr +from netlab_sim.model.contracts import SRV6_LOCAL, STATIC +from netlab_sim.model.hashing import flow_label_for +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network +from netlab_sim.model.packets import ( ORIGINATED, TRANSIT, FlowKey, @@ -24,9 +24,9 @@ encapsulate, frame_bytes, ) -from ngraph_sim.model.routing import Nexthop -from ngraph_sim.model.srv6_compress import compress, csid_arg -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model.routing import Nexthop +from netlab_sim.model.srv6_compress import compress, csid_arg +from netlab_sim.model.state import validate_immutable from tests.model.test_forwarding_srv6 import interpreted_trace diff --git a/tests/runtime/test_agent_fresh_runtime.py b/tests/runtime/test_agent_fresh_runtime.py index 60cd5b9..d02e690 100644 --- a/tests/runtime/test_agent_fresh_runtime.py +++ b/tests/runtime/test_agent_fresh_runtime.py @@ -7,9 +7,9 @@ restarts them with a fresh generation and runs ``on_init`` again. """ -import ngraph_sim -from ngraph_sim.model import contracts as c -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model import contracts as c +from netlab_sim.runtime import Simulation from tests.model.test_network import build_diamond REF = c.ClientId('ref', 0) @@ -35,7 +35,7 @@ def running_network(): net, R = build_diamond() net.add_agent('R1', Counter()) net.add_agent('R2', Counter()) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) sim.run_until(2) return net, sim @@ -46,7 +46,7 @@ def test_fork_bound_to_a_new_simulation_restarts_agents_cold(): assert all(n.initialized and n.runs >= 2 for n in warm.values()) fork = net.fork() assert fork.state is net.state # nothing copied - env2 = ngraph_sim.Environment() + env2 = netlab_sim.Environment() sim2 = Simulation(env2, fork) fresh = {d: fork.state.devices[d].agents['ref'] for d in ('R1', 'R2')} for d in ('R1', 'R2'): @@ -69,7 +69,7 @@ def test_a_network_without_initialized_agents_is_not_rewritten(): net, R = build_diamond() net.add_agent('R1', Counter()) before = net.state - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) # Only derivations touched the tree: the agent node is the registered one. assert net.state.devices['R1'].agents['ref'] is before.devices['R1'].agents['ref'] sim.settle() @@ -81,7 +81,7 @@ def test_restart_is_deterministic_across_forks(): def outcome(): fork = net.fork() - sim2 = Simulation(ngraph_sim.Environment(), fork) + sim2 = Simulation(netlab_sim.Environment(), fork) sim2.run_until(1.2) return tuple( (d, fork.state.devices[d].agents['ref'].state) for d in ('R1', 'R2') diff --git a/tests/runtime/test_agent_integration.py b/tests/runtime/test_agent_integration.py index 36bd356..d269251 100644 --- a/tests/runtime/test_agent_integration.py +++ b/tests/runtime/test_agent_integration.py @@ -8,16 +8,16 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model import nht -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.network import published_failure -from ngraph_sim.model.routing import Nexthop, ResolutionPolicy, Route -from ngraph_sim.model.state import PMap, validate_immutable -from ngraph_sim.runtime.agents import AgentBatchError, AgentRuntime -from ngraph_sim.runtime.simulation import Simulation -from ngraph_sim.runtime.transport import TransportRuntime +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model import nht +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.network import published_failure +from netlab_sim.model.routing import Nexthop, ResolutionPolicy, Route +from netlab_sim.model.state import PMap, validate_immutable +from netlab_sim.runtime.agents import AgentBatchError, AgentRuntime +from netlab_sim.runtime.simulation import Simulation +from netlab_sim.runtime.transport import TransportRuntime from tests.model.test_network import A, build_diamond from tests.runtime.inbox import deliver_now diff --git a/tests/runtime/test_agent_prng.py b/tests/runtime/test_agent_prng.py index ba66f4d..ed3aaec 100644 --- a/tests/runtime/test_agent_prng.py +++ b/tests/runtime/test_agent_prng.py @@ -2,12 +2,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model.prng import Prng -from ngraph_sim.model.state import validate_admitted, validate_immutable -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.agents import AgentBatchError +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model.prng import Prng +from netlab_sim.model.state import validate_admitted, validate_immutable +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.agents import AgentBatchError from tests.runtime.inbox import deliver_now from tests.runtime.test_agents import Plugin, fixture diff --git a/tests/runtime/test_agent_prng_retention.py b/tests/runtime/test_agent_prng_retention.py index d5c4e9d..f1bd006 100644 --- a/tests/runtime/test_agent_prng_retention.py +++ b/tests/runtime/test_agent_prng_retention.py @@ -4,7 +4,7 @@ import pytest -from ngraph_sim.model import contracts as c +from netlab_sim.model import contracts as c from tests.runtime.inbox import deliver_now from tests.runtime.test_agents import Plugin, fixture diff --git a/tests/runtime/test_agent_retry.py b/tests/runtime/test_agent_retry.py index 088ba2c..1060fe9 100644 --- a/tests/runtime/test_agent_retry.py +++ b/tests/runtime/test_agent_retry.py @@ -2,12 +2,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model import derive -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation, pipeline -from ngraph_sim.runtime.agents import AgentBatchError +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model import derive +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation, pipeline +from netlab_sim.runtime.agents import AgentBatchError from tests.runtime.inbox import deliver_now, stamped from tests.runtime.test_agents import Plugin, fixture diff --git a/tests/runtime/test_agent_review.py b/tests/runtime/test_agent_review.py index bef4774..e9b4c98 100644 --- a/tests/runtime/test_agent_review.py +++ b/tests/runtime/test_agent_review.py @@ -6,16 +6,16 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model import nht, srv6 -from ngraph_sim.model.network import published_failure -from ngraph_sim.model.routing import Nexthop, Route -from ngraph_sim.model.state import NetworkState, PMap, StateDelta -from ngraph_sim.runtime import agents -from ngraph_sim.runtime.events import Stats -from ngraph_sim.runtime.pipeline import ConvergenceError -from ngraph_sim.runtime.simulation import Simulation +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model import nht, srv6 +from netlab_sim.model.network import published_failure +from netlab_sim.model.routing import Nexthop, Route +from netlab_sim.model.state import NetworkState, PMap, StateDelta +from netlab_sim.runtime import agents +from netlab_sim.runtime.events import Stats +from netlab_sim.runtime.pipeline import ConvergenceError +from netlab_sim.runtime.simulation import Simulation from tests.model.test_network import A, build_diamond from tests.model.test_policies import diamond, policy from tests.runtime.inbox import deliver_now, stamped @@ -604,7 +604,7 @@ class Counted(int): def test_validators_are_fail_closed(name): """RC3 finding 1: C-level containers, mutable PMap keys and scalar subclasses with instance attributes are rejected by both validators.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _mutable_values()[name] with pytest.raises(TypeError): @@ -676,8 +676,8 @@ def callback(ctx): def test_nht_cost_change_while_parked_is_delivered_after_retry(): from dataclasses import replace - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.runtime import Simulation from tests.model.test_network import A, build_diamond from tests.model.test_nht import route @@ -782,7 +782,7 @@ class Update(Enum): ) def test_classifier_rejects_storage_carrying_subclasses_and_enum_values(name): """RC4: absence of __dict__ is not immutability; enum values are walked.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _round4_cases()[name] with pytest.raises(TypeError): @@ -804,8 +804,8 @@ def test_classifier_accepts_audited_leaves_records_and_named_tuples(): from fractions import Fraction from typing import NamedTuple - from ngraph_sim.model.addressing import MacAddress - from ngraph_sim.model.state import FloatArray, validate_admitted, validate_immutable + from netlab_sim.model.addressing import MacAddress + from netlab_sim.model.state import FloatArray, validate_admitted, validate_immutable class Pair(NamedTuple): a: int @@ -830,8 +830,8 @@ class Kind(IntEnum): def test_prefix_table_owns_exact_keys_and_float_array_exact_bytes(): """RC4: keys and array bytes never alias caller subclasses.""" - from ngraph_sim.model.lpm import FrozenPrefixTable, PrefixTable - from ngraph_sim.model.state import FloatArray, validate_immutable + from netlab_sim.model.lpm import FrozenPrefixTable, PrefixTable + from netlab_sim.model.state import FloatArray, validate_immutable class Net(int): pass @@ -953,7 +953,7 @@ class IteratorSlots(float): def test_classifier_reads_real_storage_and_components(name): """RC5: enum instance attributes, Fraction components and descriptor-level slot storage are checked; a __slots__ declaration alone is not trusted.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _round5_cases()[name] if callable(value): @@ -973,8 +973,8 @@ def test_classifier_reads_real_storage_and_components(name): def test_prefix_table_bits_and_float_array_bytes_are_owned(): - from ngraph_sim.model.lpm import PrefixTable - from ngraph_sim.model.state import FloatArray, validate_immutable + from netlab_sim.model.lpm import PrefixTable + from netlab_sim.model.state import FloatArray, validate_immutable class Number(int): pass @@ -999,8 +999,8 @@ def __bytes__(self): def test_plain_enums_remain_admitted(): from enum import Enum, IntEnum - from ngraph_sim.model.interfaces import OperState - from ngraph_sim.model.state import validate_immutable + from netlab_sim.model.interfaces import OperState + from netlab_sim.model.state import validate_immutable class Kind(IntEnum): ONE = 1 @@ -1051,7 +1051,7 @@ class FractionTag(Enum): def test_classifier_composes_fraction_and_enum_rules(name): """RC6: component checks apply to every Fraction, enum values go through the classifier, and enum slot storage counts as instance attributes.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _round6_cases()[name] if callable(value): @@ -1073,8 +1073,8 @@ def test_classifier_composes_fraction_and_enum_rules(name): def test_prefix_table_metadata_is_exact_even_for_empty_shards(): - from ngraph_sim.model.lpm import FrozenPrefixTable - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.lpm import FrozenPrefixTable + from netlab_sim.model.state import validate_admitted, validate_immutable class Length(int): pass @@ -1137,7 +1137,7 @@ class MixedRecord(Mixin): ) def test_records_admit_only_field_storage(name): """RC7: a frozen record's instance storage must be its walked fields.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _round7_cases()[name] with pytest.raises(TypeError): @@ -1159,7 +1159,7 @@ def test_records_admit_only_field_storage(name): def test_legitimate_record_inheritance_still_validates(): from typing import Generic, TypeVar - from ngraph_sim.model.state import record, validate_admitted, validate_immutable + from netlab_sim.model.state import record, validate_admitted, validate_immutable T = TypeVar('T') @@ -1219,7 +1219,7 @@ def __init__(self, pending): @pytest.mark.parametrize('name', ['initvar-shadow', 'classvar-shadow']) def test_inherited_slots_must_be_effective_fields(name): """RC8: a slot left behind by a redeclared field is unvisited storage.""" - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable value = _round8_cases()[name] assert dataclasses.fields(value) == () and value.pending == [1] @@ -1240,7 +1240,7 @@ def test_inherited_slots_must_be_effective_fields(name): def test_slotted_record_inheritance_with_kept_fields_validates(): - from ngraph_sim.model.state import validate_admitted, validate_immutable + from netlab_sim.model.state import validate_admitted, validate_immutable @dataclass(frozen=True, slots=True) class Base: diff --git a/tests/runtime/test_agent_scale.py b/tests/runtime/test_agent_scale.py index f51dd4a..8b4ef35 100644 --- a/tests/runtime/test_agent_scale.py +++ b/tests/runtime/test_agent_scale.py @@ -11,17 +11,17 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import ( +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model.network import Network +from netlab_sim.model.state import ( Allocators, DeviceState, NetworkState, PMap, StateDelta, ) -from ngraph_sim.runtime.simulation import Simulation +from netlab_sim.runtime.simulation import Simulation from tests.runtime.test_agents import Plugin diff --git a/tests/runtime/test_agents.py b/tests/runtime/test_agents.py index b2dc287..2464c93 100644 --- a/tests/runtime/test_agents.py +++ b/tests/runtime/test_agents.py @@ -4,12 +4,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model import routing -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import Nexthop, Route -from ngraph_sim.runtime.simulation import Simulation +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model import routing +from netlab_sim.model.network import Network +from netlab_sim.model.routing import Nexthop, Route +from netlab_sim.runtime.simulation import Simulation from tests.runtime.inbox import deliver_now, stamped @@ -64,8 +64,8 @@ def test_registration_after_binding_indexes_before_commit_dispatch(): def test_partial_failure_retry_and_captured_prefix(monkeypatch): - from ngraph_sim.runtime.agents import AgentBatchError - from ngraph_sim.runtime.timeline import AgentRunEvent + from netlab_sim.runtime.agents import AgentBatchError + from netlab_sim.runtime.timeline import AgentRunEvent calls = [] sent = [] @@ -172,8 +172,8 @@ def callback(ctx): def test_subscriptions_refine_fields_families_and_ancestors(): from dataclasses import replace - from ngraph_sim.model.state import StateDelta - from ngraph_sim.runtime.subscriptions import SubscriptionIndex + from netlab_sim.model.state import StateDelta + from netlab_sim.runtime.subscriptions import SubscriptionIndex sim = fixture() r = sim.network.device('r') @@ -217,9 +217,9 @@ def test_context_is_detached_read_only_and_immutable_projections(): import dataclasses import random - from ngraph_sim.model.entities import Device - from ngraph_sim.model.network import _View - from ngraph_sim.model.state import NetworkState, PMap, validate_immutable + from netlab_sim.model.entities import Device + from netlab_sim.model.network import _View + from netlab_sim.model.state import NetworkState, PMap, validate_immutable contexts = [] sim = fixture( @@ -297,8 +297,8 @@ def test_timers_reset_removal_and_stale_generation(monkeypatch): def test_same_time_loop_and_positive_delay_event_budget(): - from ngraph_sim.runtime.pipeline import ConvergenceError - from ngraph_sim.runtime.simulation import BudgetExceeded + from netlab_sim.runtime.pipeline import ConvergenceError + from netlab_sim.runtime.simulation import BudgetExceeded loop = Plugin(paths=(('agents', 'test', 'state'),)) sim = fixture(loop, max_rounds_per_timestamp=3) @@ -315,7 +315,7 @@ def test_same_time_loop_and_positive_delay_event_budget(): def test_inbox_limit_and_float_deadlines(): - from ngraph_sim.runtime.agents import AgentBatchError, AgentInboxOverflow + from netlab_sim.runtime.agents import AgentBatchError, AgentInboxOverflow sim = fixture(Plugin(config=c.AgentConfig(run_delay=1, inbox_limit=1))) sim.settle() @@ -407,8 +407,8 @@ def callback(ctx): 'bad', ['owner', 'family', 'mutable', 'callback', 'allocation'] ) def test_invalid_output_rolls_back_only_its_journal(bad, monkeypatch): - from ngraph_sim.model import srv6 - from ngraph_sim.runtime.agents import AgentBatchError + from netlab_sim.model import srv6 + from netlab_sim.runtime.agents import AgentBatchError def callback(ctx): ctx.rng.random() @@ -469,8 +469,8 @@ def callback(ctx): def test_nht_sid_results_routes_causes_and_purge(): - from ngraph_sim.model import srv6 - from ngraph_sim.model.state import PMap + from netlab_sim.model import srv6 + from netlab_sim.model.state import PMap contexts = [] @@ -594,8 +594,8 @@ def test_device_removal_cancels_registered_agents(): def test_policy_ops_and_purge_keep_other_client(): - from ngraph_sim.model import srv6 - from ngraph_sim.model.srv6 import ipv6 + from netlab_sim.model import srv6 + from netlab_sim.model.srv6 import ipv6 sim = fixture(Plugin()) sim.settle() @@ -648,8 +648,8 @@ def test_policy_ops_and_purge_keep_other_client(): def test_link_neighbor_and_connection_projections(monkeypatch): - from ngraph_sim.model.addressing import MacAddress - from ngraph_sim.model.state import PMap + from netlab_sim.model.addressing import MacAddress + from netlab_sim.model.state import PMap net = Network() a, b = net.add_device('a'), net.add_device('b') @@ -769,7 +769,7 @@ def test_remove_agent_and_device_in_aborted_batch_restore_registries(): def test_retry_at_later_time_captures_same_prefix_with_fresh_due_work(): - from ngraph_sim.runtime.agents import AgentBatchError + from netlab_sim.runtime.agents import AgentBatchError seen = [] bad = [True] @@ -795,7 +795,7 @@ def callback(ctx): @pytest.mark.parametrize('method', ['settle', 'run_derivations', 'run']) def test_event_budget_all_drivers(method): - from ngraph_sim.runtime.simulation import BudgetExceeded + from netlab_sim.runtime.simulation import BudgetExceeded sim = fixture(Plugin(), event_budget=0) with pytest.raises(BudgetExceeded): @@ -804,7 +804,7 @@ def test_event_budget_all_drivers(method): def test_replacement_invalidates_descendant_subscription_even_equal_values(): - from ngraph_sim.runtime.subscriptions import SubscriptionIndex + from netlab_sim.runtime.subscriptions import SubscriptionIndex sim = fixture() sim.network.device('r').add_ethernet('eth') @@ -842,7 +842,7 @@ def callback(ctx): def test_immediate_partial_retry_uses_successor_round(): - from ngraph_sim.runtime.agents import AgentBatchError + from netlab_sim.runtime.agents import AgentBatchError bad = [True] diff --git a/tests/runtime/test_equivalence.py b/tests/runtime/test_equivalence.py index f79994f..d00efe2 100644 --- a/tests/runtime/test_equivalence.py +++ b/tests/runtime/test_equivalence.py @@ -3,11 +3,11 @@ import pytest -import ngraph_sim -from ngraph_sim.model.addressing import IPV4, IPV6, to_int -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.state import tree_equal -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model.addressing import IPV4, IPV6, to_int +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.state import tree_equal +from netlab_sim.runtime import Simulation from tests.model.test_network import build_diamond @@ -35,7 +35,7 @@ def test_converge_equals_timed_pipeline(with_igp): if with_igp: net.add_source(oracle_igp) net_a.converge() - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net_b) assert tree_equal(net_a.state, net_b.state) for i, (op_a, op_b) in enumerate( diff --git a/tests/runtime/test_failures.py b/tests/runtime/test_failures.py index f1fb18d..7b1fbe3 100644 --- a/tests/runtime/test_failures.py +++ b/tests/runtime/test_failures.py @@ -4,9 +4,9 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import ( +from netlab_sim import Environment +from netlab_sim.model.network import Network +from netlab_sim.runtime import ( Distribution, Draws, FailureSet, @@ -15,7 +15,7 @@ Schedule, Simulation, ) -from ngraph_sim.runtime.failures import derive_seed, resolve_groups +from netlab_sim.runtime.failures import derive_seed, resolve_groups from tests.model.test_network import build_diamond @@ -276,7 +276,7 @@ def test_lease_post_commit_observer_error_preserves_consistency(operation): @pytest.mark.parametrize('operation', ['acquire', 'release']) def test_lease_pre_commit_validation_error_aborts_all_entities(monkeypatch, operation): - import ngraph_sim.model.network as network_module + import netlab_sim.model.network as network_module net, lid = small_net() sim = Simulation(Environment(), net) @@ -324,7 +324,7 @@ def test_scheduled_committed_fault_arms_repair_even_when_observer_raises(): def test_scheduled_pre_commit_abort_does_not_arm_repair(monkeypatch): - import ngraph_sim.model.network as network_module + import netlab_sim.model.network as network_module net, lid = small_net() sim = Simulation(Environment(), net) @@ -382,7 +382,7 @@ def test_lease_change_inside_existing_batch_is_rejected_without_registry_mutatio @pytest.mark.parametrize('failure', ['abort', 'observer']) def test_failed_acquire_preserves_preexisting_overlap(monkeypatch, failure): - import ngraph_sim.model.network as network_module + import netlab_sim.model.network as network_module net, lid = small_net() sim = Simulation(Environment(), net) diff --git a/tests/runtime/test_invariants_runtime.py b/tests/runtime/test_invariants_runtime.py index a53ea05..7e26338 100644 --- a/tests/runtime/test_invariants_runtime.py +++ b/tests/runtime/test_invariants_runtime.py @@ -2,23 +2,23 @@ import inspect -import ngraph_sim -from ngraph_sim.runtime import events, pipeline +import netlab_sim +from netlab_sim.runtime import events, pipeline def _event_subclasses(): found = [] for module in (pipeline, events): for _, cls in inspect.getmembers(module, inspect.isclass): - if issubclass(cls, ngraph_sim.Event) and cls.__module__ == module.__name__: + if issubclass(cls, netlab_sim.Event) and cls.__module__ == module.__name__: found.append(cls) return found def test_runtime_event_types_declare_slots_and_set_every_slot(): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() instances = [ - pipeline.StageEvent(env, ngraph_sim.DEFERRED, 0, lambda e: None, 0, 0.0, 0), + pipeline.StageEvent(env, netlab_sim.DEFERRED, 0, lambda e: None, 0, 0.0, 0), events._Delivery(env, lambda e: None, None), ] covered = {type(i) for i in instances} @@ -27,12 +27,12 @@ def test_runtime_event_types_declare_slots_and_set_every_slot(): assert cls in covered, f'add {cls.__name__} to the instances list' for evt in instances: assert not hasattr(evt, '__dict__') - for slot in ngraph_sim.Event.__slots__: + for slot in netlab_sim.Event.__slots__: assert hasattr(evt, slot), f'{type(evt).__name__} missing {slot}' def test_band_constants(): assert ( - ngraph_sim.NORMAL < ngraph_sim.DEFERRED < pipeline.ROUND_END < pipeline.SETTLED + netlab_sim.NORMAL < netlab_sim.DEFERRED < pipeline.ROUND_END < pipeline.SETTLED ) assert pipeline.SETTLED == events.SETTLED diff --git a/tests/runtime/test_packet_loss.py b/tests/runtime/test_packet_loss.py index 9e3c92b..253db67 100644 --- a/tests/runtime/test_packet_loss.py +++ b/tests/runtime/test_packet_loss.py @@ -7,12 +7,12 @@ import pytest -import ngraph_sim -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import IPV4, to_int -from ngraph_sim.model.network import Network -from ngraph_sim.model.packets import PacketTemplate -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import IPV4, to_int +from netlab_sim.model.network import Network +from netlab_sim.model.packets import PacketTemplate +from netlab_sim.runtime import Simulation FAIL, RESTORE = 0.500, 0.550 # 50 ms outage @@ -39,7 +39,7 @@ def build(links: int, **dev): def send_train(net, n=100, spacing=0.01, offset=0.005, **kw): """*n* packets, distinct flows, one every *spacing* s; returns traces by send time.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) link0 = net.links['R1:eth0--R2:eth0'] sim.at(FAIL, link0.fail) @@ -127,7 +127,7 @@ def test_fluid_prunes_the_dead_leg_only_with_fast_failover(self): for ff, expect_drop in ((False, True), (True, False)): net = build(2, fib_delay=0.1, fast_failover=ff) net.add_demand('d', 'R1', '10.0.0.2', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(FAIL, net.links['R1:eth0--R2:eth0'].fail) sim.run_until(0.52) # inside the outage, before the FIB reacts diff --git a/tests/runtime/test_pipeline.py b/tests/runtime/test_pipeline.py index bef76e6..5bda0fa 100644 --- a/tests/runtime/test_pipeline.py +++ b/tests/runtime/test_pipeline.py @@ -4,11 +4,11 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import StateDelta -from ngraph_sim.runtime import pipeline as coordinator -from ngraph_sim.runtime.pipeline import COALESCE, DEBOUNCE, Kind, Pipeline, build_kinds +from netlab_sim import Environment +from netlab_sim.model.network import Network +from netlab_sim.model.state import StateDelta +from netlab_sim.runtime import pipeline as coordinator +from netlab_sim.runtime.pipeline import COALESCE, DEBOUNCE, Kind, Pipeline, build_kinds def pipeline(mode=DEBOUNCE, run=None): diff --git a/tests/runtime/test_prng.py b/tests/runtime/test_prng.py index f545e6e..03e6c58 100644 --- a/tests/runtime/test_prng.py +++ b/tests/runtime/test_prng.py @@ -10,8 +10,8 @@ import pytest -from ngraph_sim.model.prng import Prng, _splitmix64 -from ngraph_sim.model.state import validate_admitted, validate_immutable +from netlab_sim.model.prng import Prng, _splitmix64 +from netlab_sim.model.state import validate_admitted, validate_immutable def test_splitmix64_reference_known_answers(): @@ -345,7 +345,7 @@ def sequence(seed): def test_subprocess_hash_seed_does_not_change_streams(): script = """ import json -from ngraph_sim.model.prng import Prng +from netlab_sim.model.prng import Prng state = None values = [] for run in range(3): diff --git a/tests/runtime/test_sessions.py b/tests/runtime/test_sessions.py index 3f730c1..d240679 100644 --- a/tests/runtime/test_sessions.py +++ b/tests/runtime/test_sessions.py @@ -4,9 +4,9 @@ import pytest -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.state import validate_immutable +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.state import validate_immutable from tests.model.test_network import A, build_diamond from tests.runtime.test_transport import bind, deliveries, pair, register @@ -388,7 +388,7 @@ def test_listener_reset_during_handshake_does_not_accept_old_request(): def test_transport_publication_survives_observer_failure_exactly_once(): - from ngraph_sim.model.network import published_failure + from netlab_sim.model.network import published_failure sim, ga, _, cid = open_pair() diff --git a/tests/runtime/test_simulation.py b/tests/runtime/test_simulation.py index 76522ee..e4e6899 100644 --- a/tests/runtime/test_simulation.py +++ b/tests/runtime/test_simulation.py @@ -1,13 +1,13 @@ import pytest -import ngraph_sim -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model.addressing import IPV4, to_int -from ngraph_sim.model.contracts import STATIC -from ngraph_sim.model.interfaces import OperState, StateReason -from ngraph_sim.model.packets import PacketTemplate -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.pipeline import ConvergenceError +import netlab_sim +from netlab_sim.model import forwarding as fw +from netlab_sim.model.addressing import IPV4, to_int +from netlab_sim.model.contracts import STATIC +from netlab_sim.model.interfaces import OperState, StateReason +from netlab_sim.model.packets import PacketTemplate +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.pipeline import ConvergenceError from tests.model.test_flows import WIRE, _loads from tests.model.test_network import build_diamond @@ -20,7 +20,7 @@ def bound(min_links=2, demand=True, **kw): net, R = build_diamond(min_links=min_links, **kw) if demand: net.add_demand('d1', 'R1', '10.0.0.4', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) return env, net, R, sim @@ -195,12 +195,12 @@ def test_round_bookkeeping_does_not_grow_with_time(): def test_kind_that_dirties_itself_runs_again_in_a_successor_round(): import dataclasses - from ngraph_sim.model.network import Network - from ngraph_sim.runtime.pipeline import COALESCE, Kind, Pipeline + from netlab_sim.model.network import Network + from netlab_sim.runtime.pipeline import COALESCE, Kind, Pipeline net = Network() net.add_device('A') - env = ngraph_sim.Environment() + env = netlab_sim.Environment() runs = [] def run(state, now, entities): @@ -235,14 +235,14 @@ def test_observer_failure_after_commit_does_not_re_execute_the_run(): retry() has nothing to re-run and the committed state stands.""" import dataclasses - from ngraph_sim.model import derive - from ngraph_sim.model.network import Network, published_failure - from ngraph_sim.runtime.pipeline import COALESCE, Kind, Pipeline + from netlab_sim.model import derive + from netlab_sim.model.network import Network, published_failure + from netlab_sim.runtime.pipeline import COALESCE, Kind, Pipeline net = Network() net.add_device('R') net.converge() - env = ngraph_sim.Environment() + env = netlab_sim.Environment() runs = [] def run(root, now, due): diff --git a/tests/runtime/test_srv6_diamond.py b/tests/runtime/test_srv6_diamond.py index 82ed8c3..ccb95a9 100644 --- a/tests/runtime/test_srv6_diamond.py +++ b/tests/runtime/test_srv6_diamond.py @@ -4,13 +4,13 @@ import pytest -import ngraph_sim -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.routing import Nexthop -from ngraph_sim.model.state import tree_equal -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.timeline import PolicyEvent +import netlab_sim +from netlab_sim.model import forwarding as fw +from netlab_sim.model import srv6 as sr +from netlab_sim.model.routing import Nexthop +from netlab_sim.model.state import tree_equal +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.timeline import PolicyEvent from tests.model.test_policies import diamond, policy, state_of @@ -22,7 +22,7 @@ def test_timed_failover_preserves_old_program_and_visible_drops(backup): [sr.SteeringRule('class', p.key, dscp=10)] ) net.add_demand('d', 'R1', '10.0.0.4', 100e6, dscp=10) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) routers['R1'].configure(fib_delay=0.05) sim.run_until(1) old_fib = routers['R1'].fib(6) @@ -74,7 +74,7 @@ def test_owner_blackhole_validates_rib_before_delayed_fib_programming(): ) p = policy(routers, lists=(sr.SegmentList((sr.TermSeg('R4'),)),)) net.add_demand('d', 'R1', '10.0.0.4', 100e6, steer=sr.PolicyRef(*p.key)) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) routers['R1'].configure(fib_delay=2) routers['R4'].configure(fib_delay=0.5) sim.run_until(3) @@ -117,7 +117,7 @@ def test_policy_clock_free_equals_settled_timed_execution(): p = policy(routers, backup=True) net.add_demand('d', 'R1', '10.0.0.4', 100e6, steer=sr.PolicyRef(*p.key)) instant.converge() - sim = Simulation(ngraph_sim.Environment(), timed) + sim = Simulation(netlab_sim.Environment(), timed) assert tree_equal(instant.state, timed.state) for t, action in ((10, 'fail'), (20, 'restore')): getattr(instant.links['R1:eth1--R2:eth1'], action)() @@ -130,8 +130,8 @@ def test_policy_clock_free_equals_settled_timed_execution(): def test_study_exports_failure_policy_status_and_observed_delivery(): import json - from ngraph_sim.runtime.failures import FailureSet - from ngraph_sim.study import Study + from netlab_sim.runtime.failures import FailureSet + from netlab_sim.study import Study net, routers = diamond() p = policy(routers) @@ -153,7 +153,7 @@ def test_study_exports_failure_policy_status_and_observed_delivery(): def test_prefer_installed_uses_fib_identity_during_failure_and_restore(): from dataclasses import replace - from ngraph_sim.model.routing import ResolutionPolicy + from netlab_sim.model.routing import ResolutionPolicy from tests.model.test_policies import path net, routers = diamond() @@ -166,7 +166,7 @@ def test_prefer_installed_uses_fib_identity_during_failure_and_restore(): routers['R1'].policy_client().replace(replace(p, candidate_paths=(first, second))) net.converge() assert state_of(routers, p).active_path == 0 - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) routers['R1'].configure(fib_delay=2) sim.run_until(3) link = net.links['R1:eth1--R2:eth1'] diff --git a/tests/runtime/test_srv6_events.py b/tests/runtime/test_srv6_events.py index 0dcd76b..8082016 100644 --- a/tests/runtime/test_srv6_events.py +++ b/tests/runtime/test_srv6_events.py @@ -4,16 +4,16 @@ import pytest -import ngraph_sim -from ngraph_sim.model import derive, srv6 -from ngraph_sim.model.addressing import IPV4, IPV6 -from ngraph_sim.model.contracts import SRV6_LOCAL, STATIC -from ngraph_sim.model.network import Network -from ngraph_sim.model.routing import SRV6_LOCAL_NH -from ngraph_sim.model.state import StateDelta -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.pipeline import fib_affected, placement_affected -from ngraph_sim.runtime.timeline import LocatorEvent, PolicyEvent, SidEvent, Timeline +import netlab_sim +from netlab_sim.model import derive, srv6 +from netlab_sim.model.addressing import IPV4, IPV6 +from netlab_sim.model.contracts import SRV6_LOCAL, STATIC +from netlab_sim.model.network import Network +from netlab_sim.model.routing import SRV6_LOCAL_NH +from netlab_sim.model.state import StateDelta +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.pipeline import fib_affected, placement_affected +from netlab_sim.runtime.timeline import LocatorEvent, PolicyEvent, SidEvent, Timeline def topology(): @@ -60,7 +60,7 @@ def test_adjacency_withdrawal_persists_sid_and_invalidates_remote_consumer(): def test_timed_pipeline_schedules_both_families_and_honors_delay(): net, head, a, _, link, sid = topology() - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) epochs = head.node.resolver_input_epoch sim.at(10, link.fail) sim.run_until(10.5) @@ -221,8 +221,8 @@ def test_numbered_neighbor_required_and_scoped_l3(): def test_unknown_cover_returns_on_sid_withdrawal_and_yields_on_restore(): - from ngraph_sim.model import forwarding as fw - from ngraph_sim.model import packets + from netlab_sim.model import forwarding as fw + from netlab_sim.model import packets net = Network() a, b = net.add_device('a'), net.add_device('b') @@ -250,7 +250,7 @@ def test_unknown_cover_returns_on_sid_withdrawal_and_yields_on_restore(): flow_label=0, transit=False, ) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) assert net.trace('a', packet).outcome == fw.DELIVER assert a.fib(IPV6).lookup(adjacency.sid).action == fw.SRV6_LOCAL sim.at(10, link.fail) diff --git a/tests/runtime/test_study.py b/tests/runtime/test_study.py index 6169e19..6eb82a8 100644 --- a/tests/runtime/test_study.py +++ b/tests/runtime/test_study.py @@ -4,8 +4,8 @@ import pytest -from ngraph_sim.runtime import Draws, FailureSet, Process, Schedule -from ngraph_sim.study import Study +from netlab_sim.runtime import Draws, FailureSet, Process, Schedule +from netlab_sim.study import Study from tests.model.test_network import build_diamond @@ -114,7 +114,7 @@ def test_enumerate_replay_retention_and_empty_cases(tmp_path): assert study.iterations([]).flow_results == [] assert study.process(Process({}), 1).sim['per_demand']['d']['unavailability'] == 0 empty = Study( - __import__('ngraph_sim.model.network', fromlist=['Network']).Network() + __import__('netlab_sim.model.network', fromlist=['Network']).Network() ) assert ( empty.iterations([FailureSet()]).flow_results[0]['summary']['overall_ratio'] @@ -145,8 +145,8 @@ def test_core_import_and_native_study_without_site_packages(): sys.executable, '-S', '-c', - 'import sys; from ngraph_sim.study import Study; ' - 'from ngraph_sim.runtime import Process; ' + 'import sys; from netlab_sim.study import Study; ' + 'from netlab_sim.runtime import Process; ' 'assert not any(m == "ngraph" or m.startswith("ngraph.") for m in sys.modules)', ], capture_output=True, @@ -157,7 +157,7 @@ def test_core_import_and_native_study_without_site_packages(): def test_cli_missing_optional_dependency(): result = subprocess.run( - [sys.executable, '-S', '-m', 'ngraph_sim', 'run', 'unused.yaml'], + [sys.executable, '-S', '-m', 'netlab_sim', 'run', 'unused.yaml'], capture_output=True, text=True, ) @@ -166,7 +166,7 @@ def test_cli_missing_optional_dependency(): def two_rate_network(rates=(15, 7)): - from ngraph_sim.model.network import Network + from netlab_sim.model.network import Network net = Network() with net.batch(): @@ -201,9 +201,9 @@ def test_healthy_roundoff_is_not_loss_or_downtime(): def test_metrics_visit_delivery_tuples_linearly(size): from dataclasses import replace - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation - from ngraph_sim.runtime.timeline import PlacementEvent + from netlab_sim import Environment + from netlab_sim.runtime import Simulation + from netlab_sim.runtime.timeline import PlacementEvent class Visits: def __init__(self, pairs): @@ -276,7 +276,7 @@ def test_same_shortfall_tolerance_for_exports_and_integrals( ): from dataclasses import replace - from ngraph_sim.study import _DeliveryIntegrals + from netlab_sim.study import _DeliveryIntegrals study = Study(two_rate_network([rate])) study.capacity_unit = capacity_unit @@ -303,7 +303,7 @@ def test_same_shortfall_tolerance_for_exports_and_integrals( def test_integrals_timestamp_coalescing_missing_demand_and_window_edges(): - from ngraph_sim.study import _DeliveryIntegrals + from netlab_sim.study import _DeliveryIntegrals integral = _DeliveryIntegrals({'large': 1e12, 'small': 1}, 1) integral.sample(0, [('large', 1e12), ('small', 1)]) @@ -329,9 +329,9 @@ def test_retention_keys_have_no_aliases(key): def test_iterations_end_at_the_observation_window_despite_recurring_timers(): """A periodic timer (a protocol hello) never empties the heap; the iteration must stop at t0 + horizon, not drain the queue.""" - from ngraph_sim.model.network import Network - from ngraph_sim.runtime.failures import FailureSet - from ngraph_sim.study import Study + from netlab_sim.model.network import Network + from netlab_sim.runtime.failures import FailureSet + from netlab_sim.study import Study net = Network() net.add_device('R') diff --git a/tests/runtime/test_study_srv6.py b/tests/runtime/test_study_srv6.py index e03aa4f..384d4a7 100644 --- a/tests/runtime/test_study_srv6.py +++ b/tests/runtime/test_study_srv6.py @@ -4,10 +4,10 @@ import json from dataclasses import replace -from ngraph_sim.adapters.ngraph import from_scenario -from ngraph_sim.model import srv6 as sr -from ngraph_sim.runtime.failures import FailureSet -from ngraph_sim.study import Study, StudyResult, _policy_rows +from netlab_sim.adapters.ngraph import from_scenario +from netlab_sim.model import srv6 as sr +from netlab_sim.runtime.failures import FailureSet +from netlab_sim.study import Study, StudyResult, _policy_rows from tests.adapters.test_ngraph_srv6 import bundle_scenario diff --git a/tests/runtime/test_study_windows.py b/tests/runtime/test_study_windows.py index 9bb0534..dadf956 100644 --- a/tests/runtime/test_study_windows.py +++ b/tests/runtime/test_study_windows.py @@ -2,8 +2,8 @@ import pytest -from ngraph_sim.runtime import FailureSet, Schedule -from ngraph_sim.study import Study +from netlab_sim.runtime import FailureSet, Schedule +from netlab_sim.study import Study from tests.runtime.test_study import diamond, two_rate_network @@ -78,7 +78,7 @@ def test_periodic_normal_timers_do_not_prevent_convergence(selected): def test_quiet_begins_on_output_change_and_includes_deadline_events(): - from ngraph_sim.study import Stability + from netlab_sim.study import Stability net, _ = diamond(fib_delay=0.25) draws = [FailureSet(excluded_links=('R1:eth1--R2:eth1',))] @@ -179,8 +179,8 @@ def test_process_window_after_warmup_uses_same_failure_clock(): def test_fresh_agent_runtime_uses_configuration_and_warms_every_iteration(monkeypatch): from dataclasses import replace - from ngraph_sim.model.contracts import TransportState - from ngraph_sim.runtime.agents import AgentRuntime + from netlab_sim.model.contracts import TransportState + from netlab_sim.runtime.agents import AgentRuntime from tests.model.test_agent_contract import Minimal net = two_rate_network() @@ -322,7 +322,7 @@ def test_repeatability_fingerprint(): import hashlib import json - from ngraph_sim.runtime import Process + from netlab_sim.runtime import Process def run(): return Study(two_rate_network(), keep={'events': 1, 'records': 1}).process( @@ -408,8 +408,8 @@ def test_selected_delivery_and_routing_are_independent(): def test_programming_requires_installed_policies(): from dataclasses import replace - from ngraph_sim.model import srv6 - from ngraph_sim.study import Stability, _StabilityWindow + from netlab_sim.model import srv6 + from netlab_sim.study import Stability, _StabilityWindow from tests.runtime.test_study_srv6 import network net, _ = network() @@ -560,7 +560,7 @@ def test_real_initialized_agents_restart_and_warm_repeatably(): def test_default_processing_delay_delivers_during_real_agent_warmup(): - from ngraph_sim.model import contracts as c + from netlab_sim.model import contracts as c from tests.model.test_agent_contract import Minimal class Hello(Minimal): @@ -604,8 +604,8 @@ def on_run(self, ctx): def test_reference_baseline_matches_prepared_no_fault_iteration( mode, initialized_until ): - from ngraph_sim import Environment - from ngraph_sim.runtime import Simulation + from netlab_sim import Environment + from netlab_sim.runtime import Simulation from tests.agents.fixtures import topology network = topology(numbered=False) @@ -686,7 +686,7 @@ def run(budget=None): # even when subsequent observation needs another event and exhausts its budget. budget = run().baseline['data']['sim']['engine_events'] times = iter((10.0, 13.0, 20.0, 25.0)) - monkeypatch.setattr('ngraph_sim.study.perf_counter', lambda: next(times)) + monkeypatch.setattr('netlab_sim.study.perf_counter', lambda: next(times)) result = run(budget) baseline = result.baseline['data']['sim'] assert baseline['baseline_complete'] is True diff --git a/tests/runtime/test_timeline.py b/tests/runtime/test_timeline.py index bbabb1f..8f29594 100644 --- a/tests/runtime/test_timeline.py +++ b/tests/runtime/test_timeline.py @@ -6,10 +6,10 @@ import pytest -import ngraph_sim -from ngraph_sim.model.addressing import IPV4 -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.timeline import ( +import netlab_sim +from netlab_sim.model.addressing import IPV4 +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.timeline import ( CarrierRawEvent, ConfigEvent, DemandEvent, @@ -33,7 +33,7 @@ def flap(t_fail=10, t_restore=None, **sim_kw): net, R = build_diamond(min_links=2) net.add_demand('d1', 'R1', '10.0.0.4', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net, **sim_kw) link = net.links[LINK] sim.at(t_fail, link.fail) @@ -84,7 +84,7 @@ class TestEvents: def test_earlier_raising_hook_cannot_hide_committed_outage(self, batched): from contextlib import nullcontext - from ngraph_sim.model.interfaces import OperState + from netlab_sim.model.interfaces import OperState net, devices = build_diamond() link = net.links[LINK] @@ -95,7 +95,7 @@ def fail_on_link_change(time, origin, delta): raise error net.on_delta.append(fail_on_link_change) - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) def fail(): with net.batch() if batched else nullcontext(): @@ -162,7 +162,7 @@ def test_fib_events_only_when_forwarding_changes(self): def test_carrier_debounce_is_two_events(self): net, R = build_diamond(min_links=2) R['R1'].interface('eth1').configure(carrier_delay_down=0.5) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(10, net.links[LINK].fail) sim.run_until(20) @@ -225,7 +225,7 @@ def test_keep_reports(self): tl = Timeline(keep_reports=True) net, R = build_diamond(min_links=2) net.add_demand('d1', 'R1', '10.0.0.4', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.timeline = tl sim.at(10, net.links[LINK].fail) @@ -338,7 +338,7 @@ def test_peer_admin_down_during_carrier_delay_recomputes_class(self): net, R = build_diamond(min_links=1) R['R1'].interface('eth3').configure(carrier_delay_down=5) net.add_demand('d1', 'R1', '10.0.0.3', 100e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) before = net.state.placement key = next(iter(before.classes)) @@ -373,11 +373,11 @@ class TestReviewRegressions: """Defects found by the logging review, each pinned here.""" def test_fib_event_when_only_group_weights_change(self): - from ngraph_sim.model.addressing import to_int - from ngraph_sim.model.routing import Nexthop + from netlab_sim.model.addressing import to_int + from netlab_sim.model.routing import Nexthop net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) h13, _ = to_int('10.1.13.1') h12, _ = to_int('10.1.12.1') @@ -411,7 +411,7 @@ def test_fib_event_when_only_group_weights_change(self): def test_distinct_rows_have_distinct_route_events(self): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at( 5, @@ -436,7 +436,7 @@ def test_device_and_link_lifecycle_events(self): net, R = build_diamond(min_links=2) net.add_device('R9') # standalone: nothing references it - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(5, lambda: net.links[LINK].configure(capacity=5e6, delay=0.001)) sim.at( @@ -463,7 +463,7 @@ def test_device_and_link_lifecycle_events(self): def test_config_events_carry_values(self): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(5, lambda: R['R1'].interface('eth3').configure(mtu=1400, metric=7)) sim.run_until(6) @@ -475,7 +475,7 @@ def test_config_events_carry_values(self): def test_demand_events_carry_endpoints(self): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(5, lambda: net.add_demand('d9', 'R1', '10.0.0.4', 5e6)) sim.run_until(6) @@ -500,7 +500,7 @@ def test_baseline_for_already_converged_network(self): net, R = build_diamond(min_links=2) net.add_demand('d1', 'R1', '10.0.0.4', 100e6) net.converge() - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) tl = sim.timeline assert [r.origin for r in tl.records] == [Origin('init', 'baseline')] @@ -511,7 +511,7 @@ def test_series_after_demand_removal_and_for_new_edges(self): net, R = build_diamond(min_links=2) net.add_demand('d1', 'R1', '10.0.0.4', 100e6) net.add_demand('d2', 'R3', '10.0.0.4', 10e6) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) sim.at(5, lambda: net.remove_demand('d2')) sim.at( @@ -534,7 +534,7 @@ def test_series_after_demand_removal_and_for_new_edges(self): def test_settled_delivery_without_a_round(self): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) seen = [] sim.bus.subscribe(lambda t, o, d, root: seen.append((t, o))) @@ -550,7 +550,7 @@ def test_event_records_are_slotted(self): def test_kind_generation_is_the_round(self): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) # a settled delivery that writes opens a second round at the same time @@ -568,7 +568,7 @@ def react(t, o, d, root): def test_event_and_record_budgets_bound_a_long_run(): net, R = build_diamond(min_links=2) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation( env, net, keep_events=200, keep_records=50, keep_roots=1, keep_deltas=0 ) diff --git a/tests/runtime/test_timeline_retention.py b/tests/runtime/test_timeline_retention.py index 648e1e6..9ca318b 100644 --- a/tests/runtime/test_timeline_retention.py +++ b/tests/runtime/test_timeline_retention.py @@ -4,12 +4,12 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation -from ngraph_sim.runtime.timeline import Timeline -from ngraph_sim.study import Study +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation +from netlab_sim.runtime.timeline import Timeline +from netlab_sim.study import Study class _Ticker: diff --git a/tests/runtime/test_transport.py b/tests/runtime/test_transport.py index 9ddd4a4..4026a21 100644 --- a/tests/runtime/test_transport.py +++ b/tests/runtime/test_transport.py @@ -2,12 +2,12 @@ import pytest -import ngraph_sim -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.interfaces import OperState -from ngraph_sim.model.network import Network -from ngraph_sim.runtime import Simulation +import netlab_sim +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.interfaces import OperState +from netlab_sim.model.network import Network +from netlab_sim.runtime import Simulation from tests.model.test_agent_contract import Minimal from tests.model.test_network import build_diamond @@ -47,7 +47,7 @@ def register(net, device, name='ref', **kwargs): def bind(net): - sim = Simulation(ngraph_sim.Environment(), net) + sim = Simulation(netlab_sim.Environment(), net) sim.agents = Fake(sim) return sim diff --git a/tests/runtime/test_transport_integration.py b/tests/runtime/test_transport_integration.py index 8955a53..505ddce 100644 --- a/tests/runtime/test_transport_integration.py +++ b/tests/runtime/test_transport_integration.py @@ -4,14 +4,14 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import contracts as c -from ngraph_sim.model.addressing import MacAddress -from ngraph_sim.model.interfaces import OperState -from ngraph_sim.model.network import Network -from ngraph_sim.model.state import StateDelta, validate_immutable -from ngraph_sim.runtime.agents import AgentRuntime -from ngraph_sim.runtime.simulation import Simulation +from netlab_sim import Environment +from netlab_sim.model import contracts as c +from netlab_sim.model.addressing import MacAddress +from netlab_sim.model.interfaces import OperState +from netlab_sim.model.network import Network +from netlab_sim.model.state import StateDelta, validate_immutable +from netlab_sim.runtime.agents import AgentRuntime +from netlab_sim.runtime.simulation import Simulation from tests.model.test_network import A, build_diamond diff --git a/tests/runtime/test_transport_review.py b/tests/runtime/test_transport_review.py index 5a9f984..064469a 100644 --- a/tests/runtime/test_transport_review.py +++ b/tests/runtime/test_transport_review.py @@ -4,9 +4,9 @@ import pytest -from ngraph_sim.model import contracts as c -from ngraph_sim.model.interfaces import OperState -from ngraph_sim.model.state import PMap, StateDelta +from netlab_sim.model import contracts as c +from netlab_sim.model.interfaces import OperState +from netlab_sim.model.state import PMap, StateDelta from tests.runtime.inbox import deliver_now from tests.runtime.test_sessions import message, open_pair from tests.runtime.test_transport import pair, send @@ -400,7 +400,7 @@ def test_data_drop_is_counted_even_when_sender_control_allowance_is_exhausted(): def test_listener_cleanup_uses_the_supplied_snapshot(): - from ngraph_sim.runtime.transport import _key + from netlab_sim.runtime.transport import _key from tests.runtime.test_transport_integration import local sim = session() diff --git a/tests/runtime/test_usid_diamond.py b/tests/runtime/test_usid_diamond.py index e125e21..56bc241 100644 --- a/tests/runtime/test_usid_diamond.py +++ b/tests/runtime/test_usid_diamond.py @@ -2,13 +2,13 @@ import pytest -from ngraph_sim import Environment -from ngraph_sim.model import flows -from ngraph_sim.model import forwarding as fw -from ngraph_sim.model import srv6 as sr -from ngraph_sim.model.hashing import flow_label_for -from ngraph_sim.model.packets import FlowKey, frame_bytes -from ngraph_sim.runtime import Simulation +from netlab_sim import Environment +from netlab_sim.model import flows +from netlab_sim.model import forwarding as fw +from netlab_sim.model import srv6 as sr +from netlab_sim.model.hashing import flow_label_for +from netlab_sim.model.packets import FlowKey, frame_bytes +from netlab_sim.runtime import Simulation from tests.model.test_usid import ( diamond, form_path, diff --git a/tests/test_advanced_scenarios.py b/tests/test_advanced_scenarios.py index 4779bdb..9eedc50 100644 --- a/tests/test_advanced_scenarios.py +++ b/tests/test_advanced_scenarios.py @@ -1,7 +1,7 @@ """Advanced scenario tests exercising complex multi-primitive interactions, emergent behavior, and real-world modeling patterns.""" -import ngraph_sim +import netlab_sim # --------------------------------------------------------------------------- # Circuit breaker: disable resource after too many failures @@ -12,8 +12,8 @@ class TestCircuitBreaker: """Monitor failure rate and disable/re-enable a service.""" def test_circuit_breaker_trips_and_recovers(self): - env = ngraph_sim.Environment() - service = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + service = netlab_sim.Resource(env, capacity=1) log = [] circuit_open = [False] @@ -78,7 +78,7 @@ class TestRetryWithBackoff: """Process retries a failing operation with increasing delays.""" def test_retry_succeeds_on_third_attempt(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] attempt_count = [0] @@ -112,7 +112,7 @@ def client(env): ] def test_retry_gives_up(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def always_fails(env): @@ -144,9 +144,9 @@ class TestMultiPhaseJob: """Job has multiple phases; failure mid-way triggers cleanup.""" def test_failure_triggers_cleanup(self): - env = ngraph_sim.Environment() - res_a = ngraph_sim.Resource(env, capacity=1) - res_b = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res_a = netlab_sim.Resource(env, capacity=1) + res_b = netlab_sim.Resource(env, capacity=1) log = [] def job(env, fail_at_phase): @@ -185,9 +185,9 @@ def job(env, fail_at_phase): assert res_b.count == 0 def test_successful_multi_phase(self): - env = ngraph_sim.Environment() - res_a = ngraph_sim.Resource(env, capacity=1) - res_b = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res_a = netlab_sim.Resource(env, capacity=1) + res_b = netlab_sim.Resource(env, capacity=1) log = [] def job(env, fail_at_phase): @@ -230,9 +230,9 @@ class TestWorkStealing: """Idle workers steal work from other workers' queues.""" def test_steal_balances_load(self): - env = ngraph_sim.Environment() - q1 = ngraph_sim.Store(env) - q2 = ngraph_sim.Store(env) + env = netlab_sim.Environment() + q1 = netlab_sim.Store(env) + q2 = netlab_sim.Store(env) log = [] def worker(env, name, own_queue, other_queue): @@ -281,8 +281,8 @@ class TestBackpressure: """Producer slows down when downstream buffer is nearly full.""" def test_producer_respects_buffer_depth(self): - env = ngraph_sim.Environment() - buffer = ngraph_sim.Store(env, capacity=5) + env = netlab_sim.Environment() + buffer = netlab_sim.Store(env, capacity=5) log = [] def producer(env): @@ -354,8 +354,8 @@ def test_mm1_steady_state(self): import random random.seed(42) - env = ngraph_sim.Environment() - server = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + server = netlab_sim.Resource(env, capacity=1) lam = 0.8 # arrival rate mu = 1.0 # service rate @@ -397,10 +397,10 @@ class TestAssemblyStation: """Assembly requires one part from each of N suppliers before proceeding.""" def test_assembly_waits_for_all_parts(self): - env = ngraph_sim.Environment() - part_a = ngraph_sim.Store(env) - part_b = ngraph_sim.Store(env) - part_c = ngraph_sim.Store(env) + env = netlab_sim.Environment() + part_a = netlab_sim.Store(env) + part_b = netlab_sim.Store(env) + part_c = netlab_sim.Store(env) log = [] def supplier(env, store, name, interval): @@ -442,8 +442,8 @@ class TestTokenBucket: Requests exceeding the rate are delayed until tokens are available.""" def test_burst_then_rate_limit(self): - env = ngraph_sim.Environment() - bucket = ngraph_sim.Container(env, capacity=5, init=5) # burst of 5 + env = netlab_sim.Environment() + bucket = netlab_sim.Container(env, capacity=5, init=5) # burst of 5 log = [] def token_refill(env): @@ -485,9 +485,9 @@ class TestLinkFailover: After repair, traffic returns to primary.""" def test_failover_and_recovery(self): - env = ngraph_sim.Environment() - primary = ngraph_sim.Store(env, capacity=10) - backup = ngraph_sim.Store(env, capacity=10) + env = netlab_sim.Environment() + primary = netlab_sim.Store(env, capacity=10) + backup = netlab_sim.Store(env, capacity=10) primary_up = [True] log = [] diff --git a/tests/test_benchmarks.py b/tests/test_benchmarks.py index 5923898..dd406c7 100644 --- a/tests/test_benchmarks.py +++ b/tests/test_benchmarks.py @@ -7,13 +7,13 @@ import pytest -import ngraph_sim +import netlab_sim pytestmark = pytest.mark.benchmark def _timeout_loop(n): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def p(env): for _ in range(n): @@ -25,8 +25,8 @@ def p(env): def _store_pingpong(n): - env = ngraph_sim.Environment() - st = ngraph_sim.Store(env, capacity=1) + env = netlab_sim.Environment() + st = netlab_sim.Store(env, capacity=1) def prod(env): for i in range(n): @@ -43,8 +43,8 @@ def cons(env): def _resource_backlog(n): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) def u(env): with res.request() as r: @@ -58,8 +58,8 @@ def u(env): def _anyof_timeout(n): - env = ngraph_sim.Environment() - st = ngraph_sim.Store(env) + env = netlab_sim.Environment() + st = netlab_sim.Store(env) def p(env): for _ in range(n): @@ -74,13 +74,13 @@ def p(env): def _interrupts(n): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def victim(env): while True: try: yield env.timeout(1000) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: pass def attacker(env, v): @@ -128,12 +128,12 @@ def _clos_converge(leaves, spines): def _clos_failure_cascade(leaves, spines): - import ngraph_sim - from ngraph_sim.runtime import Simulation + import netlab_sim + from netlab_sim.runtime import Simulation from tests.model.clos import build_clos net = build_clos(leaves, spines) - env = ngraph_sim.Environment() + env = netlab_sim.Environment() sim = Simulation(env, net) links = list(net.links.values()) for i, link in enumerate(links[:spines]): @@ -145,7 +145,7 @@ def _clos_failure_cascade(leaves, spines): def _lpm_lookups(n): import random - from ngraph_sim.model.lpm import PrefixTable + from netlab_sim.model.lpm import PrefixTable rng = random.Random(1) t = PrefixTable(32) @@ -185,8 +185,8 @@ def test_study_windows(benchmark, fixture): pytest.skip('study qualification requires --benchmark-enable') from dataclasses import asdict - from ngraph_sim.runtime import FailureSet - from ngraph_sim.study import Study + from netlab_sim.runtime import FailureSet + from netlab_sim.study import Study from tests.model.clos import build_clos from tests.runtime.test_study import diamond diff --git a/tests/test_condition.py b/tests/test_condition.py index a9ecca2..e32265f 100644 --- a/tests/test_condition.py +++ b/tests/test_condition.py @@ -2,12 +2,12 @@ import pytest -import ngraph_sim +import netlab_sim class TestAllOf: def test_all_events_must_trigger(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -26,7 +26,7 @@ def proc(env): class TestAnyOf: def test_any_event_triggers(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] times = [] @@ -46,7 +46,7 @@ def proc(env): class TestNestedConditions: def test_nested_all_of(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -65,7 +65,7 @@ def proc(env): class TestOperators: def test_and_operator(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -79,7 +79,7 @@ def proc(env): assert results == [[10, 20]] def test_or_operator(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -95,7 +95,7 @@ def proc(env): class TestEmptyCondition: def test_empty_allof_succeeds_immediately(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -108,7 +108,7 @@ def proc(env): assert env.now == 0 def test_empty_anyof_succeeds_immediately(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -122,7 +122,7 @@ def proc(env): class TestFailedEventInCondition: def test_failed_event_fails_condition(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() caught = [] def proc(env): @@ -142,7 +142,7 @@ def proc(env): class TestConditionValue: def test_keys_values_items(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = {} def proc(env): @@ -159,10 +159,10 @@ def proc(env): assert results['values'] == ['a', 'b'] assert len(results['items']) == 2 for evt, _val in results['items']: - assert isinstance(evt, ngraph_sim.Event) + assert isinstance(evt, netlab_sim.Event) def test_getitem(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): e1 = env.timeout(1, value='hello') @@ -175,7 +175,7 @@ def proc(env): env.run() def test_getitem_missing_key_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): e1 = env.timeout(1, value='a') @@ -188,7 +188,7 @@ def proc(env): env.run() def test_contains(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): e1 = env.timeout(1, value='a') @@ -201,7 +201,7 @@ def proc(env): env.run() def test_todict(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() result = {} def proc(env): @@ -219,19 +219,19 @@ def proc(env): class TestMixedEnvironmentsRaises: def test_mixed_environments_raises(self): - env1 = ngraph_sim.Environment() - env2 = ngraph_sim.Environment() + env1 = netlab_sim.Environment() + env2 = netlab_sim.Environment() e1 = env1.event() e2 = env2.event() with pytest.raises(ValueError, match='different environments'): - ngraph_sim.AllOf(env1, [e1, e2]) + netlab_sim.AllOf(env1, [e1, e2]) class TestConditionCheckSkipsAfterAlreadyTriggered: def test_condition_check_skips_after_already_triggered(self): """AnyOf with two events. Trigger both. The second _check call should be a no-op (no error, condition value unchanged).""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -251,7 +251,7 @@ def proc(env): class TestConditionValueEqWithDict: def test_condition_value_eq_with_dict(self): """cv == cv.todict() should be True.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -268,9 +268,9 @@ def proc(env): class TestConditionValueEqWithAnotherCV: def test_condition_value_eq_with_another_cv(self): """Two CVs with same events should be equal.""" - cv1 = ngraph_sim.ConditionValue() - cv2 = ngraph_sim.ConditionValue() - env = ngraph_sim.Environment() + cv1 = netlab_sim.ConditionValue() + cv2 = netlab_sim.ConditionValue() + env = netlab_sim.Environment() e = env.event() e.succeed(value=42) cv1.events.append(e) @@ -281,15 +281,15 @@ def test_condition_value_eq_with_another_cv(self): class TestConditionValueEqWithUnrelatedType: def test_condition_value_eq_with_unrelated_type(self): """cv.__eq__(42) returns NotImplemented.""" - cv = ngraph_sim.ConditionValue() + cv = netlab_sim.ConditionValue() assert cv.__eq__(42) is NotImplemented class TestConditionValueIter: def test_condition_value_iter(self): """list(cv) should return the events.""" - cv = ngraph_sim.ConditionValue() - env = ngraph_sim.Environment() + cv = netlab_sim.ConditionValue() + env = netlab_sim.Environment() e1 = env.event() e2 = env.event() cv.events.append(e1) diff --git a/tests/test_container.py b/tests/test_container.py index d9c925c..45960fe 100644 --- a/tests/test_container.py +++ b/tests/test_container.py @@ -2,13 +2,13 @@ import pytest -import ngraph_sim +import netlab_sim class TestContainerPutAndGet: def test_put_and_get_amounts(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=100, init=0) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=100, init=0) def proc(env): yield tank.put(30) @@ -22,8 +22,8 @@ def proc(env): class TestContainerLevelTracking: def test_level_tracks_correctly(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=50, init=20) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=50, init=20) assert tank.level == 20 def proc(env): @@ -38,15 +38,15 @@ def proc(env): class TestContainerCapacityLimits: def test_capacity_property(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=50) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=50) assert tank.capacity == 50 class TestContainerBlockingWhenFull: def test_blocks_when_full(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=10, init=8) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=10, init=8) log = [] def producer(env): @@ -69,8 +69,8 @@ def consumer(env): class TestContainerBlockingWhenEmpty: def test_blocks_when_empty(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=100, init=0) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=100, init=0) log = [] def consumer(env): @@ -91,52 +91,52 @@ def producer(env): class TestContainerInitLevel: def test_init_level(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=100, init=42) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=100, init=42) assert tank.level == 42 class TestContainerValidation: def test_capacity_zero_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='capacity'): - ngraph_sim.Container(env, capacity=0) + netlab_sim.Container(env, capacity=0) def test_capacity_negative_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='capacity'): - ngraph_sim.Container(env, capacity=-5) + netlab_sim.Container(env, capacity=-5) def test_init_negative_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='init'): - ngraph_sim.Container(env, capacity=10, init=-1) + netlab_sim.Container(env, capacity=10, init=-1) def test_init_exceeds_capacity_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='init'): - ngraph_sim.Container(env, capacity=10, init=20) + netlab_sim.Container(env, capacity=10, init=20) def test_amount_zero_put_raises(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=10) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=10) with pytest.raises(ValueError, match='amount'): tank.put(0) def test_amount_negative_put_raises(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=10) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=10) with pytest.raises(ValueError, match='amount'): tank.put(-1) def test_amount_zero_get_raises(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=10, init=5) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=10, init=5) with pytest.raises(ValueError, match='amount'): tank.get(0) def test_amount_negative_get_raises(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=10, init=5) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=10, init=5) with pytest.raises(ValueError, match='amount'): tank.get(-1) diff --git a/tests/test_environment.py b/tests/test_environment.py index 9e3ff9c..10539b7 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -2,12 +2,12 @@ import pytest -import ngraph_sim +import netlab_sim class TestRunUntilTime: def test_run_until_time(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): while True: @@ -18,7 +18,7 @@ def proc(env): assert env.now == 10 def test_run_until_time_no_overshoot(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def proc(env): @@ -33,7 +33,7 @@ def proc(env): class TestRunUntilEvent: def test_run_until_event(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(5) @@ -45,7 +45,7 @@ def proc(env): assert env.now == 5 def test_run_until_already_processed_event(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed(value='already') env.step() # process it @@ -55,7 +55,7 @@ def test_run_until_already_processed_event(self): class TestRunUntilEmpty: def test_run_until_no_events(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(5) @@ -67,44 +67,44 @@ def proc(env): class TestPeek: def test_peek_returns_next_event_time(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() env.timeout(5) # Timeout is scheduled at now + delay = 0 + 5 = 5 assert env.peek() == 5 def test_peek_infinity_when_empty(self): - env = ngraph_sim.Environment() - assert env.peek() == ngraph_sim.Infinity + env = netlab_sim.Environment() + assert env.peek() == netlab_sim.Infinity class TestStep: def test_step_advances_time(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() env.timeout(3) env.step() assert env.now == 3 def test_empty_schedule_raises(self): - env = ngraph_sim.Environment() - with pytest.raises(ngraph_sim.EmptySchedule): + env = netlab_sim.Environment() + with pytest.raises(netlab_sim.EmptySchedule): env.step() class TestRunUntilInvalid: def test_until_le_now_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='must be >'): env.run(until=0) def test_until_less_than_now_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() env.timeout(5) env.step() # now == 5 with pytest.raises(ValueError, match='must be >'): env.run(until=3) def test_until_equal_to_now_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() env.timeout(5) env.step() with pytest.raises(ValueError, match='must be >'): @@ -113,7 +113,7 @@ def test_until_equal_to_now_raises(self): class TestActiveProcess: def test_active_process_during_execution(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() active_procs = [] def proc(env): @@ -127,13 +127,13 @@ def proc(env): assert active_procs[1] is p def test_active_process_none_outside(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() assert env.active_process is None class TestInitialTime: def test_initial_time(self): - env = ngraph_sim.Environment(initial_time=100) + env = netlab_sim.Environment(initial_time=100) assert env.now == 100 def proc(env): @@ -148,7 +148,7 @@ class TestRunUntilUntriggeredEventRaises: def test_run_until_untriggered_event_raises_runtime_error(self): """Create a pending event (never triggered). Run env.run(until=event). Assert RuntimeError with 'No scheduled events left'.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() pending = env.event() # never triggered with pytest.raises(RuntimeError, match='No scheduled events left'): env.run(until=pending) @@ -158,7 +158,7 @@ class TestRunUntilFailedEventRaises: def test_run_until_failed_event_raises(self): """Create a process that raises ValueError. Run env.run(until=process). Assert ValueError propagates.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def bad_proc(env): yield env.timeout(1) @@ -173,7 +173,7 @@ class TestRunUntilRunsAllCallbacks: def test_stop_does_not_leave_waiters_stranded(self): """Stopping at the *until* event must not skip its other callbacks: a process that started waiting on it during run() is still resumed.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def worker(env): @@ -197,7 +197,7 @@ def waiter(env, w): def test_stale_until_event_does_not_stop_a_later_run(self): """An *until* event left over from an aborted run() is an ordinary event for later runs; only the current call's *until* stops it.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def crasher(env): yield env.timeout(1) @@ -217,7 +217,7 @@ def ticker(env): class TestRunUntilProcessedFailedEventRaises: def test_run_until_processed_failed_event_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('boom')) evt.defused = True @@ -227,7 +227,7 @@ def test_run_until_processed_failed_event_raises(self): def test_run_until_defused_failed_event_raises(self): """Even if a process handles the failure, run(until=evt) reports it.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() def handler(env): @@ -244,20 +244,20 @@ def handler(env): class TestRunUntilValidation: def test_until_nan_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='must be >'): env.run(until=float('nan')) def test_until_event_of_other_env_raises(self): - env1 = ngraph_sim.Environment() - env2 = ngraph_sim.Environment() + env1 = netlab_sim.Environment() + env2 = netlab_sim.Environment() with pytest.raises(ValueError, match='different environment'): env1.run(until=env2.event()) class TestStepReturnsEvent: def test_step_returns_processed_event(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() t = env.timeout(3, value='x') assert env.step() is t assert t.processed @@ -269,8 +269,8 @@ class TestRunMatchesStep: @staticmethod def _scenario(env, trace): - store = ngraph_sim.Store(env, capacity=1) - res = ngraph_sim.Resource(env, capacity=1) + store = netlab_sim.Store(env, capacity=1) + res = netlab_sim.Resource(env, capacity=1) def producer(env): for i in range(5): @@ -289,7 +289,7 @@ def consumer(env): def victim(env): try: yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: trace.append(('interrupted', e.cause, env.now)) def attacker(env, v): @@ -302,15 +302,15 @@ def attacker(env, v): env.process(attacker(env, v)) def test_run_and_step_loop_produce_identical_traces(self): - env_run = ngraph_sim.Environment() + env_run = netlab_sim.Environment() trace_run = [] self._scenario(env_run, trace_run) env_run.run() - env_step = ngraph_sim.Environment() + env_step = netlab_sim.Environment() trace_step = [] self._scenario(env_step, trace_step) - with pytest.raises(ngraph_sim.EmptySchedule): + with pytest.raises(netlab_sim.EmptySchedule): while True: env_step.step() diff --git a/tests/test_event.py b/tests/test_event.py index 142d253..3dec856 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -2,47 +2,47 @@ import pytest -import ngraph_sim +import netlab_sim class TestEventCreate: def test_new_event_is_pending(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() assert not evt.triggered assert not evt.processed assert not evt.ok def test_event_belongs_to_env(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() assert evt.env is env class TestEventSucceed: def test_succeed_sets_triggered(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed(value=42) assert evt.triggered assert evt.ok def test_succeed_with_default_value(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed() env.step() assert evt.value is None def test_succeed_with_value(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed(value='hello') env.step() assert evt.value == 'hello' def test_succeed_returns_self(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() result = evt.succeed() assert result is evt @@ -50,33 +50,33 @@ def test_succeed_returns_self(self): class TestEventFail: def test_fail_sets_triggered(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('boom')) assert evt.triggered assert not evt.ok def test_fail_value_is_exception(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() exc = ValueError('boom') evt.fail(exc) assert evt.value is exc def test_fail_requires_exception_instance(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() with pytest.raises(TypeError): evt.fail('not an exception') def test_fail_returns_self(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() result = evt.fail(RuntimeError('oops')) assert result is evt def test_undefused_failed_event_raises_on_step(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('boom')) with pytest.raises(ValueError, match='boom'): @@ -85,7 +85,7 @@ def test_undefused_failed_event_raises_on_step(self): class TestEventTrigger: def test_trigger_chains_success(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() source = env.event() target = env.event() source.callbacks.append(target.trigger) @@ -96,7 +96,7 @@ def test_trigger_chains_success(self): assert target.value == 99 def test_trigger_chains_failure(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() source = env.event() target = env.event() source.callbacks.append(target.trigger) @@ -111,21 +111,21 @@ def test_trigger_chains_failure(self): assert target.value is exc def test_double_trigger_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed() with pytest.raises(RuntimeError): evt.succeed() def test_double_fail_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('first')) with pytest.raises(RuntimeError): evt.fail(ValueError('second')) def test_succeed_after_fail_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('first')) with pytest.raises(RuntimeError): @@ -134,7 +134,7 @@ def test_succeed_after_fail_raises(self): class TestEventCallbacks: def test_callbacks_executed_on_processing(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() results = [] evt.callbacks.append(lambda e: results.append(e.value)) @@ -143,7 +143,7 @@ def test_callbacks_executed_on_processing(self): assert results == [10] def test_callbacks_set_to_none_after_processing(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.succeed() env.step() @@ -151,7 +151,7 @@ def test_callbacks_set_to_none_after_processing(self): assert evt.processed def test_multiple_callbacks_all_called(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() called = [] evt.callbacks.append(lambda e: called.append('a')) @@ -163,7 +163,7 @@ def test_multiple_callbacks_all_called(self): class TestEventValueAccess: def test_value_before_trigger_raises_attribute_error(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() with pytest.raises(AttributeError): _ = evt.value @@ -171,18 +171,18 @@ def test_value_before_trigger_raises_attribute_error(self): class TestEventDefused: def test_defused_flag_default(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() assert not evt.defused def test_defused_flag_can_be_set(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.defused = True assert evt.defused def test_defused_failed_event_does_not_raise(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.event() evt.fail(ValueError('boom')) evt.defused = True @@ -194,7 +194,7 @@ def test_defused_failed_event_does_not_raise(self): class TestTriggerDoubleTriggerRaises: def test_trigger_double_trigger_raises(self): """Calling event.trigger(source) on an already-triggered event raises RuntimeError.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() source = env.event() target = env.event() source.succeed(value=1) @@ -211,7 +211,7 @@ def test_trigger_double_trigger_raises(self): class TestTriggerUsedAsCallbackChaining: def test_trigger_used_as_callback_chaining(self): """Register target.trigger as a callback on source; after step, target has same value.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() source = env.event() target = env.event() source.callbacks.append(target.trigger) @@ -225,10 +225,10 @@ def test_trigger_used_as_callback_chaining(self): class TestTriggerRequiresTriggeredSource: def test_trigger_from_untriggered_source_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() src = env.event() dst = env.event() with pytest.raises(RuntimeError, match='not been triggered'): dst.trigger(src) assert not dst.triggered - assert env.peek() == ngraph_sim.Infinity + assert env.peek() == netlab_sim.Infinity diff --git a/tests/test_filter_store.py b/tests/test_filter_store.py index 3dbbdcf..7599646 100644 --- a/tests/test_filter_store.py +++ b/tests/test_filter_store.py @@ -1,12 +1,12 @@ """Tests for FilterStore resource.""" -import ngraph_sim +import netlab_sim class TestFilteredGet: def test_filter_matches(self): - env = ngraph_sim.Environment() - store = ngraph_sim.FilterStore(env) + env = netlab_sim.Environment() + store = netlab_sim.FilterStore(env) results = [] def producer(env): @@ -27,8 +27,8 @@ def consumer(env): class TestFilterNoMatchKeepsWaiting: def test_no_match_waits(self): - env = ngraph_sim.Environment() - store = ngraph_sim.FilterStore(env) + env = netlab_sim.Environment() + store = netlab_sim.FilterStore(env) results = [] def producer(env): @@ -50,8 +50,8 @@ class TestFilterStoreOutOfOrder: def test_out_of_order_service(self): """A later get request whose filter matches should be served before an earlier request that doesn't match yet.""" - env = ngraph_sim.Environment() - store = ngraph_sim.FilterStore(env) + env = netlab_sim.Environment() + store = netlab_sim.FilterStore(env) log = [] def producer(env): diff --git a/tests/test_fingerprints.py b/tests/test_fingerprints.py index 01223ac..748b418 100644 --- a/tests/test_fingerprints.py +++ b/tests/test_fingerprints.py @@ -6,8 +6,8 @@ import hashlib import json -from ngraph_sim.model.igp import oracle_igp -from ngraph_sim.model.network import Network +from netlab_sim.model.igp import oracle_igp +from netlab_sim.model.network import Network from tests.model.clos import build_clos from tests.model.test_network import build_diamond diff --git a/tests/test_integration.py b/tests/test_integration.py index bba2e3e..c099f42 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,12 +1,12 @@ """Integration tests: multi-process interactions and complex scenarios.""" -import ngraph_sim +import netlab_sim class TestProducerConsumerThroughStore: def test_multi_process_producer_consumer(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) produced = [] consumed = [] @@ -38,7 +38,7 @@ def consumer(env, name, count): class TestComplexSynchronization: def test_allof_anyof_sync(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def task(env, name, duration): @@ -68,8 +68,8 @@ def coordinator(env): class TestInterruptDuringResourceWait: def test_interrupt_while_waiting_for_resource(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) log = [] def holder(env): @@ -84,7 +84,7 @@ def waiter(env): try: yield req log.append(('waiter_acquired', env.now)) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: log.append(('waiter_interrupted', env.now, e.cause)) req.cancel() @@ -104,7 +104,7 @@ def interrupter(env, target): class TestProcessWaitingForProcess: def test_yield_process_gets_return_value(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def child1(env): @@ -133,9 +133,9 @@ def parent(env): class TestPipelineProcessing: def test_multi_stage_pipeline(self): - env = ngraph_sim.Environment() - stage1_out = ngraph_sim.Store(env) - stage2_out = ngraph_sim.Store(env) + env = netlab_sim.Environment() + stage1_out = netlab_sim.Store(env) + stage2_out = netlab_sim.Store(env) final_results = [] def stage1(env): @@ -164,8 +164,8 @@ def collector(env): class TestResourcePreemptionChain: def test_preemption_chain(self): - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def user(env, name, priority, duration): @@ -175,7 +175,7 @@ def user(env, name, priority, duration): log.append((name, 'start', env.now)) yield env.timeout(duration) log.append((name, 'finish', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append((name, 'preempted', env.now)) finally: res.release(req) diff --git a/tests/test_interrupt.py b/tests/test_interrupt.py index b9f55d4..7b7164d 100644 --- a/tests/test_interrupt.py +++ b/tests/test_interrupt.py @@ -2,18 +2,18 @@ import pytest -import ngraph_sim +import netlab_sim class TestInterruptWaitingProcess: def test_interrupt_a_waiting_process(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def victim(env): try: yield env.timeout(10) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: log.append(('interrupted', env.now, e.cause)) def attacker(env, target): @@ -28,13 +28,13 @@ def attacker(env, target): class TestInterruptCause: def test_cause_accessible(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() causes = [] def victim(env): try: yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: causes.append(e.cause) def attacker(env, target): @@ -47,13 +47,13 @@ def attacker(env, target): assert causes == [{'reason': 'test'}] def test_cause_default_is_none(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() causes = [] def victim(env): try: yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: causes.append(e.cause) def attacker(env, target): @@ -68,7 +68,7 @@ def attacker(env, target): class TestInterruptDeadProcess: def test_interrupt_dead_process_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def short_lived(env): yield env.timeout(1) @@ -81,7 +81,7 @@ def short_lived(env): class TestSelfInterrupt: def test_self_interrupt_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): myself = env.active_process @@ -98,13 +98,13 @@ def test_first_handled_second_ignored_if_process_dies(self): """If two _Interruption events are scheduled before either is processed, the second is silently ignored because the victim is already dead when the second _Interruption callback fires.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def victim(env): try: yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: log.append(e.cause) return # Process dies @@ -126,13 +126,13 @@ def attacker(env, target): class TestDefusedInterrupt: def test_defused_interrupt(self): """If an interrupt event is defused, it should not propagate.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def victim(env): try: yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: log.append(e.cause) yield env.timeout(1) log.append('continued') diff --git a/tests/test_invariants.py b/tests/test_invariants.py index fd9b7ab..b8e6422 100644 --- a/tests/test_invariants.py +++ b/tests/test_invariants.py @@ -14,27 +14,27 @@ import pytest -import ngraph_sim -from ngraph_sim import core, resources +import netlab_sim +from netlab_sim import core, resources def _event_subclasses(): found = [] for module in (core, resources): for _, cls in inspect.getmembers(module, inspect.isclass): - if issubclass(cls, ngraph_sim.Event) and cls.__module__ == module.__name__: + if issubclass(cls, netlab_sim.Event) and cls.__module__ == module.__name__: found.append(cls) return found def _build_event_instances(): """One instance of every Event type reachable through the public API.""" - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) - fstore = ngraph_sim.FilterStore(env) - res = ngraph_sim.Resource(env) - pres = ngraph_sim.PriorityResource(env) - cont = ngraph_sim.Container(env, capacity=10, init=5) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) + fstore = netlab_sim.FilterStore(env) + res = netlab_sim.Resource(env) + pres = netlab_sim.PriorityResource(env) + cont = netlab_sim.Container(env, capacity=10, init=5) def gen(env): yield env.timeout(1) @@ -72,9 +72,9 @@ def _do_get(self, event): interruption, resources.Put(stub), resources.Get(stub), - ngraph_sim.AllOf(env, [env.event()]), - ngraph_sim.AnyOf(env, [env.event()]), - ngraph_sim.Condition(env, ngraph_sim.Condition.all_events, []), + netlab_sim.AllOf(env, [env.event()]), + netlab_sim.AnyOf(env, [env.event()]), + netlab_sim.Condition(env, netlab_sim.Condition.all_events, []), store.put(1), store.get(), fstore.get(lambda x: True), @@ -101,7 +101,7 @@ def test_every_event_constructor_sets_every_event_slot(self): """Constructors inline ``Event.__init__`` for speed; make sure none of them forgets a slot (an unset slot raises AttributeError on read).""" for evt in _build_event_instances(): - for slot in ngraph_sim.Event.__slots__: + for slot in netlab_sim.Event.__slots__: assert hasattr(evt, slot), f'{type(evt).__name__} missing {slot}' def test_all_public_event_types_are_covered(self): @@ -115,17 +115,17 @@ class TestUserExtensibleObjects: 'factory', [ lambda env: env, - lambda env: ngraph_sim.Store(env), - lambda env: ngraph_sim.FilterStore(env), - lambda env: ngraph_sim.PriorityStore(env), - lambda env: ngraph_sim.Resource(env), - lambda env: ngraph_sim.PriorityResource(env), - lambda env: ngraph_sim.PreemptiveResource(env), - lambda env: ngraph_sim.Container(env), + lambda env: netlab_sim.Store(env), + lambda env: netlab_sim.FilterStore(env), + lambda env: netlab_sim.PriorityStore(env), + lambda env: netlab_sim.Resource(env), + lambda env: netlab_sim.PriorityResource(env), + lambda env: netlab_sim.PreemptiveResource(env), + lambda env: netlab_sim.Container(env), ], ) def test_accepts_arbitrary_attributes(self, factory): - obj = factory(ngraph_sim.Environment()) + obj = factory(netlab_sim.Environment()) obj.tag = 'x' assert obj.tag == 'x' @@ -134,30 +134,30 @@ class TestResourceQueues: @pytest.mark.parametrize( 'factory', [ - lambda env: ngraph_sim.Store(env), - lambda env: ngraph_sim.FilterStore(env), - lambda env: ngraph_sim.PriorityStore(env), - lambda env: ngraph_sim.Resource(env), - lambda env: ngraph_sim.Container(env), + lambda env: netlab_sim.Store(env), + lambda env: netlab_sim.FilterStore(env), + lambda env: netlab_sim.PriorityStore(env), + lambda env: netlab_sim.Resource(env), + lambda env: netlab_sim.Container(env), ], ) def test_fifo_queues_are_deques(self, factory): - r = factory(ngraph_sim.Environment()) + r = factory(netlab_sim.Environment()) assert isinstance(r.put_queue, deque) assert isinstance(r.get_queue, deque) def test_priority_put_queue_is_sorted(self): - r = ngraph_sim.PriorityResource(ngraph_sim.Environment()) + r = netlab_sim.PriorityResource(netlab_sim.Environment()) assert isinstance(r.put_queue, resources.SortedQueue) assert isinstance(r.get_queue, deque) def test_resource_queue_alias(self): - r = ngraph_sim.Resource(ngraph_sim.Environment()) + r = netlab_sim.Resource(netlab_sim.Environment()) assert r.queue is r.put_queue def test_large_backlog_drains_in_fifo_order(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) order = [] def user(env, i): @@ -222,7 +222,7 @@ def _do_get(self, event): return True def test_non_head_put_is_removed_from_the_middle_of_the_queue(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() store = self._MatchStore(env) got = [] done = [] @@ -248,7 +248,7 @@ def consumer(env): def test_queue_mutation_inside_do_put_is_detected(self): """A ``_do_put`` that reorders the queue under the loop's feet must be caught by the invariant guard rather than corrupt the queue.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() class Broken(resources.BaseResource): def _do_put(self, event): diff --git a/tests/test_priority_band.py b/tests/test_priority_band.py index eaada7d..6386cc3 100644 --- a/tests/test_priority_band.py +++ b/tests/test_priority_band.py @@ -2,8 +2,8 @@ work at the same simulation time, including ``NORMAL`` events scheduled while that time is being processed.""" -import ngraph_sim -from ngraph_sim import core +import netlab_sim +from netlab_sim import core def _deferred_event(env, callback, priority=core.DEFERRED, delay=0): @@ -20,10 +20,10 @@ def _deferred_event(env, callback, priority=core.DEFERRED, delay=0): class TestPriorityBand: def test_band_constants_are_ordered(self): assert core.URGENT < core.NORMAL < core.DEFERRED - assert ngraph_sim.DEFERRED is core.DEFERRED + assert netlab_sim.DEFERRED is core.DEFERRED def test_deferred_runs_after_normal_scheduled_during_processing(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() order = [] def normal_second(ev): @@ -41,7 +41,7 @@ def normal_first(ev): assert order == ['normal-1', 'normal-2', 'deferred'] def test_deferred_band_is_fifo_by_priority_then_eid(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() order = [] _deferred_event(env, lambda ev: order.append('b+1'), core.DEFERRED + 1) _deferred_event(env, lambda ev: order.append('b+0 first'), core.DEFERRED) @@ -50,7 +50,7 @@ def test_deferred_band_is_fifo_by_priority_then_eid(self): assert order == ['b+0 first', 'b+0 second', 'b+1'] def test_deferred_at_later_time_does_not_preempt_earlier_normal(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() order = [] _deferred_event(env, lambda ev: order.append(('deferred', env.now)), delay=1) env.timeout(2).callbacks.append(lambda ev: order.append(('normal', env.now))) @@ -60,7 +60,7 @@ def test_deferred_at_later_time_does_not_preempt_earlier_normal(self): def test_run_until_time_stops_before_deferred_work_at_that_time(self): """``run(until=t)`` inserts an URGENT stop event, so deferred work at exactly ``t`` has not run when ``run`` returns.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() ran = [] _deferred_event(env, lambda ev: ran.append(env.now), delay=5) env.run(until=5) diff --git a/tests/test_priority_resource.py b/tests/test_priority_resource.py index 4552e78..71899fc 100644 --- a/tests/test_priority_resource.py +++ b/tests/test_priority_resource.py @@ -1,12 +1,12 @@ """Tests for PriorityResource and PreemptiveResource.""" -import ngraph_sim +import netlab_sim class TestPriorityOrdering: def test_priority_ordering_of_requests(self): - env = ngraph_sim.Environment() - res = ngraph_sim.PriorityResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PriorityResource(env, capacity=1) log = [] def user(env, name, priority, hold_time): @@ -35,8 +35,8 @@ def user(env, name, priority, hold_time): class TestPreemption: def test_preemption_interrupts_lower_priority(self): - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def user_low(env): @@ -46,7 +46,7 @@ def user_low(env): log.append(('low', 'acquired', env.now)) yield env.timeout(100) log.append(('low', 'finished', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('low', 'preempted', env.now)) finally: res.release(req) @@ -60,7 +60,7 @@ def user_high(env): log.append(('high', 'acquired', env.now)) yield env.timeout(3) log.append(('high', 'finished', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: pass finally: res.release(req) @@ -77,8 +77,8 @@ def user_high(env): class TestPreemptedCause: def test_preempted_cause_attributes(self): - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) causes = [] def user_low(env): @@ -86,7 +86,7 @@ def user_low(env): try: yield req yield env.timeout(100) - except ngraph_sim.Interrupt as e: + except netlab_sim.Interrupt as e: causes.append(e.cause) finally: res.release(req) @@ -103,7 +103,7 @@ def user_high(env): assert len(causes) == 1 preempted = causes[0] - assert isinstance(preempted, ngraph_sim.Preempted) + assert isinstance(preempted, netlab_sim.Preempted) assert preempted.resource is res assert preempted.usage_since == 0 assert preempted.by is not None # The high-priority process @@ -113,8 +113,8 @@ class TestPreemptiveResourceNoPreemptFlag: def test_preemptive_resource_no_preempt_flag(self): """Request with priority=0, preempt=False arrives while a priority=10 user holds the resource. The priority=10 user should NOT be interrupted.""" - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def user_low(env): @@ -124,7 +124,7 @@ def user_low(env): log.append(('low', 'acquired', env.now)) yield env.timeout(5) log.append(('low', 'finished', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('low', 'preempted', env.now)) finally: res.release(req) @@ -137,7 +137,7 @@ def user_high_no_preempt(env): log.append(('high_no_preempt', 'acquired', env.now)) yield env.timeout(2) log.append(('high_no_preempt', 'finished', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('high_no_preempt', 'preempted', env.now)) finally: res.release(req) @@ -158,8 +158,8 @@ class TestPreemptionOfRequestOutsideProcess: def test_holder_without_process_is_not_preempted(self): """A request made outside any process has no process to interrupt, so it keeps its slot; the preempting request waits for release.""" - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) holder = res.request(priority=10) # env.active_process is None here log = [] @@ -181,8 +181,8 @@ def releaser(env): def test_preemption_skips_processless_user_and_picks_lowest_priority_process( self, ): - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=2) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=2) outside = res.request(priority=0) # highest priority, no process log = [] @@ -191,7 +191,7 @@ def low(env): try: yield req yield env.timeout(100) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('low_preempted', env.now)) finally: res.release(req) diff --git a/tests/test_priority_store.py b/tests/test_priority_store.py index 0378f2c..c0f3f22 100644 --- a/tests/test_priority_store.py +++ b/tests/test_priority_store.py @@ -1,12 +1,12 @@ """Tests for PriorityStore and PriorityItem.""" -import ngraph_sim +import netlab_sim class TestPriorityStoreOrder: def test_items_retrieved_in_priority_order(self): - env = ngraph_sim.Environment() - store = ngraph_sim.PriorityStore(env) + env = netlab_sim.Environment() + store = netlab_sim.PriorityStore(env) results = [] def producer(env): @@ -29,15 +29,15 @@ def consumer(env): class TestPriorityItem: def test_priority_item_for_unorderable_items(self): """PriorityItem wraps unorderable items so they can be stored.""" - env = ngraph_sim.Environment() - store = ngraph_sim.PriorityStore(env) + env = netlab_sim.Environment() + store = netlab_sim.PriorityStore(env) results = [] # Dicts are not orderable, so we wrap them in PriorityItem def producer(env): - yield store.put(ngraph_sim.PriorityItem(3, {'name': 'c'})) - yield store.put(ngraph_sim.PriorityItem(1, {'name': 'a'})) - yield store.put(ngraph_sim.PriorityItem(2, {'name': 'b'})) + yield store.put(netlab_sim.PriorityItem(3, {'name': 'c'})) + yield store.put(netlab_sim.PriorityItem(1, {'name': 'a'})) + yield store.put(netlab_sim.PriorityItem(2, {'name': 'b'})) def consumer(env): yield env.timeout(1) @@ -51,8 +51,8 @@ def consumer(env): assert results == ['a', 'b', 'c'] def test_priority_item_comparison(self): - a = ngraph_sim.PriorityItem(1, 'x') - b = ngraph_sim.PriorityItem(2, 'y') + a = netlab_sim.PriorityItem(1, 'x') + b = netlab_sim.PriorityItem(2, 'y') assert a < b assert not b < a @@ -61,9 +61,9 @@ class TestPriorityItemAllComparisons: def test_priority_item_all_comparisons(self): """Test that __lt__, __le__, __gt__, __ge__, __eq__ all compare by priority only (not by item).""" - a = ngraph_sim.PriorityItem(1, 'aaa') - b = ngraph_sim.PriorityItem(2, 'bbb') - c = ngraph_sim.PriorityItem(1, 'zzz') # same priority as a, different item + a = netlab_sim.PriorityItem(1, 'aaa') + b = netlab_sim.PriorityItem(2, 'bbb') + c = netlab_sim.PriorityItem(1, 'zzz') # same priority as a, different item # __lt__ assert a < b diff --git a/tests/test_process.py b/tests/test_process.py index 44929e5..345609e 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -2,12 +2,12 @@ import pytest -import ngraph_sim +import netlab_sim class TestProcessStartAndYield: def test_process_starts_immediately(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() started = [] def proc(env): @@ -19,7 +19,7 @@ def proc(env): assert started == [True] def test_process_yields_timeout(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(5) @@ -32,7 +32,7 @@ def proc(env): class TestProcessResumeWithValue: def test_yield_returns_event_value(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() received = [] def proc(env): @@ -46,7 +46,7 @@ def proc(env): class TestProcessReturn: def test_return_value_via_stop_iteration(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def child(env): yield env.timeout(1) @@ -61,7 +61,7 @@ def parent(env): def test_process_is_event_yield_gets_return(self): """Process IS Event: yielding a process from another gets the return value.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def worker(env): @@ -80,7 +80,7 @@ def boss(env): class TestProcessExceptionPropagation: def test_generator_exception_propagates(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def bad_proc(env): yield env.timeout(1) @@ -93,7 +93,7 @@ def bad_proc(env): class TestProcessName: def test_explicit_name(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def my_gen(env): yield env.timeout(0) @@ -102,7 +102,7 @@ def my_gen(env): assert p.name == 'custom' def test_name_from_generator(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def my_generator(env): yield env.timeout(0) @@ -113,7 +113,7 @@ def my_generator(env): class TestProcessIsAlive: def test_is_alive_before_completion(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(10) @@ -122,7 +122,7 @@ def proc(env): assert p.is_alive def test_is_alive_after_completion(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(1) @@ -134,7 +134,7 @@ def proc(env): class TestProcessTarget: def test_target_property(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(5) @@ -148,7 +148,7 @@ def proc(env): class TestProcessNotAGenerator: def test_non_generator_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='is not a generator'): env.process('not a generator') @@ -157,7 +157,7 @@ class TestProcessYieldsAlreadyProcessedEvent: def test_process_yields_already_processed_event(self): """A process that yields an already-processed event should immediately receive the value without blocking.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() results = [] def proc(env): @@ -176,7 +176,7 @@ def proc(env): class TestProcessYieldsNonEventRaisesRuntimeError: def test_process_yields_non_event_raises_runtime_error(self): """A process that yields a string (not an Event) should raise RuntimeError.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def bad_proc(env): yield 'not an event' @@ -189,7 +189,7 @@ def bad_proc(env): class TestProcessGeneratorClearedAfterTermination: def test_process_generator_cleared_after_termination(self): """After a process terminates, process._generator should be None.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): yield env.timeout(1) @@ -203,7 +203,7 @@ def proc(env): class TestProcessNameAfterGeneratorCleared: def test_process_name_after_generator_cleared(self): """After termination with no explicit name, process.name should not crash.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def my_proc(env): yield env.timeout(1) @@ -217,7 +217,7 @@ def my_proc(env): assert repr(p) == f'' def test_name_fallback_for_nameless_generator(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() class Gen: """A generator-like object without __name__.""" @@ -239,7 +239,7 @@ def throw(self, exc): class TestInvalidYieldResetsActiveProcess: def test_active_process_cleared_after_invalid_yield(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def bad_proc(env): yield 'not an event' @@ -252,7 +252,7 @@ def bad_proc(env): class TestExceptionCopy: def test_reconstructable_exception_is_copied_with_cause(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() original = ValueError('boom') caught = [] @@ -275,7 +275,7 @@ def parent(env): def test_unreconstructable_exception_is_passed_through_without_cycle(self): """An exception whose __init__ cannot be called with *args is reused as-is; it must not end up as its own __cause__.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() class Custom(Exception): def __init__(self, msg, *, code): @@ -303,7 +303,7 @@ def parent(env): assert e.__cause__ is not e def test_unreconstructable_exception_crashes_run_cleanly(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() class Custom(Exception): def __init__(self, msg, *, code): diff --git a/tests/test_resource.py b/tests/test_resource.py index 93b2035..b01caac 100644 --- a/tests/test_resource.py +++ b/tests/test_resource.py @@ -2,13 +2,13 @@ import pytest -import ngraph_sim +import netlab_sim class TestResourceRequestRelease: def test_request_and_release(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) log = [] def user(env, name): @@ -26,8 +26,8 @@ def user(env, name): class TestResourceQueuing: def test_queuing_when_at_capacity(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) log = [] def user(env, name, hold_time): @@ -51,8 +51,8 @@ def user(env, name, hold_time): class TestResourceMultipleUsers: def test_multiple_users_up_to_capacity(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=2) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=2) log = [] def user(env, name, hold_time): @@ -76,8 +76,8 @@ def user(env, name, hold_time): class TestResourceContextManager: def test_context_manager_auto_release(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) log = [] def user(env, name, hold_time): @@ -96,8 +96,8 @@ def user(env, name, hold_time): class TestResourceCount: def test_count_property(self): - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=2) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=2) counts = [] def proc(env): @@ -121,12 +121,12 @@ class TestResourceReleaseUnknownRequest: def test_resource_release_unknown_request(self): """Create a Request but don't yield it. Call resource.release(request). Should succeed silently (no error).""" - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) def proc(env): # Create a request without yielding it - from ngraph_sim.resources import Request + from netlab_sim.resources import Request req = Request(res) # Release it without ever acquiring -- should not error @@ -140,6 +140,6 @@ def proc(env): class TestResourceZeroCapacityRaises: def test_resource_zero_capacity_raises(self): """Resource(env, capacity=0) raises ValueError.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError): - ngraph_sim.Resource(env, capacity=0) + netlab_sim.Resource(env, capacity=0) diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index 5156653..b0cfbe0 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -3,7 +3,7 @@ import random -import ngraph_sim +import netlab_sim # --------------------------------------------------------------------------- # Renege pattern: request | timeout, then check which fired @@ -14,8 +14,8 @@ class TestRenegePattern: """Customer waits for a resource OR gives up after a patience timeout.""" def test_customer_served_when_resource_free(self): - env = ngraph_sim.Environment() - counter = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + counter = netlab_sim.Resource(env, capacity=1) log = [] def customer(env): @@ -31,8 +31,8 @@ def customer(env): assert log == [('served', 0)] def test_customer_reneges_when_resource_busy(self): - env = ngraph_sim.Environment() - counter = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + counter = netlab_sim.Resource(env, capacity=1) log = [] def holder(env): @@ -55,8 +55,8 @@ def customer(env): def test_renege_cancels_request(self): """After reneging, the request should be removed from the queue.""" - env = ngraph_sim.Environment() - counter = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + counter = netlab_sim.Resource(env, capacity=1) def holder(env): with counter.request() as req: @@ -85,7 +85,7 @@ class TestInterruptResume: """Process tracks remaining work across interrupts.""" def test_remaining_work_after_interrupt(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def worker(env): @@ -95,7 +95,7 @@ def worker(env): try: yield env.timeout(done_in) done_in = 0 - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: done_in -= env.now - start log.append(('interrupted', env.now, done_in)) yield env.timeout(5) # repair time @@ -115,7 +115,7 @@ def breaker(env, proc): assert log[2] == ('finished', 15) def test_multiple_interrupts_track_remaining(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def worker(env): @@ -125,7 +125,7 @@ def worker(env): try: yield env.timeout(done_in) done_in = 0 - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: done_in -= env.now - start log.append(('break', env.now, round(done_in, 1))) yield env.timeout(2) # repair @@ -155,9 +155,9 @@ class TestResourceAndContainer: """Processes use both a Resource (pump) and Container (fuel tank).""" def test_pump_and_fuel(self): - env = ngraph_sim.Environment() - pumps = ngraph_sim.Resource(env, capacity=2) - tank = ngraph_sim.Container(env, capacity=100, init=100) + env = netlab_sim.Environment() + pumps = netlab_sim.Resource(env, capacity=2) + tank = netlab_sim.Container(env, capacity=100, init=100) log = [] def refuel(env, name, amount): @@ -179,8 +179,8 @@ def refuel(env, name, amount): assert log == [('A', 15.0, 30), ('B', 20.0, 10), ('C', 25.0, 10)] def test_container_blocks_until_refilled(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=50, init=10) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=50, init=10) log = [] def consumer(env): @@ -210,8 +210,8 @@ class TestPreemptiveRepairCycle: """Machine breaks, preempts repairman's other job, gets repaired.""" def test_repair_preempts_other_job(self): - env = ngraph_sim.Environment() - repairman = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + repairman = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def other_job(env): @@ -221,7 +221,7 @@ def other_job(env): try: yield env.timeout(30) log.append(('other_done', env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('other_preempted', env.now)) def machine(env): @@ -248,8 +248,8 @@ class TestCarwashPatterns: def test_yield_process_while_holding_resource(self): """A process holds a resource and yields a sub-process inside.""" - env = ngraph_sim.Environment() - machine = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + machine = netlab_sim.Resource(env, capacity=1) log = [] def wash(env, name): @@ -278,7 +278,7 @@ def car(env, name): def test_continuous_spawning(self): """A generator process continuously spawns new processes.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() arrived = [] def visitor(env, name): @@ -311,7 +311,7 @@ class TestRepeatedFailures: """A worker process is repeatedly interrupted by a separate failure process.""" def test_worker_with_failure_generator(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() parts_made = [0] repairs = [0] @@ -323,7 +323,7 @@ def worker(env): try: yield env.timeout(done_in) done_in = 0 - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: done_in -= env.now - start yield env.timeout(5) # repair repairs[0] += 1 @@ -353,8 +353,8 @@ class TestMultipleCustomerRenege: def test_mixed_serve_and_renege(self): random.seed(42) - env = ngraph_sim.Environment() - counter = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + counter = netlab_sim.Resource(env, capacity=1) log = [] def customer(env, name, patience, service_time): @@ -398,8 +398,8 @@ class TestContainerMonitoring: """A monitoring process watches a container level and triggers refill.""" def test_monitor_triggers_refill(self): - env = ngraph_sim.Environment() - tank = ngraph_sim.Container(env, capacity=100, init=100) + env = netlab_sim.Environment() + tank = netlab_sim.Container(env, capacity=100, init=100) log = [] def consumer(env): @@ -439,9 +439,9 @@ class TestSequentialResources: """A job acquires multiple resources in sequence.""" def test_patient_registration_then_doctor(self): - env = ngraph_sim.Environment() - desk = ngraph_sim.Resource(env, capacity=1) - doctor = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + desk = netlab_sim.Resource(env, capacity=1) + doctor = netlab_sim.Resource(env, capacity=1) log = [] def patient(env, name): @@ -477,8 +477,8 @@ class TestFilterStoreScenario: """Processes request specific item types from a shared store.""" def test_workers_request_specific_parts(self): - env = ngraph_sim.Environment() - warehouse = ngraph_sim.FilterStore(env) + env = netlab_sim.Environment() + warehouse = netlab_sim.FilterStore(env) log = [] def supplier(env): @@ -510,7 +510,7 @@ class TestBarrierSync: """N workers must all complete before any proceeds to next phase.""" def test_barrier_with_processes(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def worker(env, name, duration): @@ -553,9 +553,9 @@ class TestMessagePassing: """Processes communicate by passing messages through a Store.""" def test_request_response(self): - env = ngraph_sim.Environment() - requests = ngraph_sim.Store(env) - responses = ngraph_sim.Store(env) + env = netlab_sim.Environment() + requests = netlab_sim.Store(env) + responses = netlab_sim.Store(env) log = [] def server(env): @@ -587,8 +587,8 @@ class TestBatchProcessing: """Accumulate items in a store, process them in batches.""" def test_batch_of_three(self): - env = ngraph_sim.Environment() - buffer = ngraph_sim.Store(env) + env = netlab_sim.Environment() + buffer = netlab_sim.Store(env) log = [] def producer(env): @@ -627,8 +627,8 @@ class TestDeterministicOrdering: def test_same_time_resource_claim(self): """Two processes arrive at t=0 for a capacity-1 resource. First created process wins.""" - env = ngraph_sim.Environment() - res = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.Resource(env, capacity=1) log = [] def worker(env, name): @@ -647,7 +647,7 @@ def worker(env, name): def test_timeout_and_event_at_same_time(self): """A timeout and a manual event trigger at the same time. Order follows scheduling order.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def waiter(env, evt): @@ -684,9 +684,9 @@ class TestCascadingStall: """A blockage in one stage stalls the entire pipeline.""" def test_blocked_stage_stalls_upstream(self): - env = ngraph_sim.Environment() - s1 = ngraph_sim.Store(env, capacity=2) - s2 = ngraph_sim.Store(env, capacity=2) + env = netlab_sim.Environment() + s1 = netlab_sim.Store(env, capacity=2) + s2 = netlab_sim.Store(env, capacity=2) log = [] def producer(env): @@ -732,9 +732,9 @@ class TestFirstAvailableResource: """Process waits for whichever of two resources is free first.""" def test_any_of_two_resources(self): - env = ngraph_sim.Environment() - res_a = ngraph_sim.Resource(env, capacity=1) - res_b = ngraph_sim.Resource(env, capacity=1) + env = netlab_sim.Environment() + res_a = netlab_sim.Resource(env, capacity=1) + res_b = netlab_sim.Resource(env, capacity=1) log = [] def holder(env, res, name, duration): @@ -777,8 +777,8 @@ class TestPreemptionChain: """Three priority levels: each preempts the one below.""" def test_three_level_preemption(self): - env = ngraph_sim.Environment() - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + res = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def job(env, name, prio, duration): @@ -787,7 +787,7 @@ def job(env, name, prio, duration): try: yield env.timeout(duration) log.append(('done', name, env.now)) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(('preempted', name, env.now)) # Low priority starts at t=0 @@ -821,8 +821,8 @@ class TestAdaptiveRate: """Consumer slows down when queue is deep, speeds up when shallow.""" def test_rate_adapts_to_queue_depth(self): - env = ngraph_sim.Environment() - queue = ngraph_sim.Store(env, capacity=100) + env = netlab_sim.Environment() + queue = netlab_sim.Store(env, capacity=100) rates = [] def producer(env): @@ -874,9 +874,9 @@ class TestConditionalDispatch: """Dispatcher assigns jobs to workers based on current load.""" def test_load_based_routing(self): - env = ngraph_sim.Environment() - q1 = ngraph_sim.Store(env, capacity=10) - q2 = ngraph_sim.Store(env, capacity=10) + env = netlab_sim.Environment() + q1 = netlab_sim.Store(env, capacity=10) + q2 = netlab_sim.Store(env, capacity=10) log = [] def worker(env, name, queue): @@ -919,7 +919,7 @@ class TestDynamicTopology: def test_result_driven_spawning(self): """Process return value determines what gets spawned next.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def probe(env, target): @@ -950,7 +950,7 @@ def controller(env): def test_fan_out_fan_in_with_dynamic_count(self): """Spawn variable number of workers, wait for all, use results.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def worker(env, wid, duration): @@ -979,13 +979,13 @@ def manager(env): def test_dynamic_resource_creation(self): """Resources created mid-simulation based on demand.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() pools = {} log = [] def get_pool(env, name): if name not in pools: - pools[name] = ngraph_sim.Resource(env, capacity=1) + pools[name] = netlab_sim.Resource(env, capacity=1) log.append(('created', name, env.now)) return pools[name] @@ -1014,7 +1014,7 @@ def scheduler(env): def test_process_death_triggers_respawn(self): """When a worker dies, a watcher spawns a replacement.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] generation = [0] @@ -1045,7 +1045,7 @@ def supervisor(env): def test_process_watching_multiple_processes(self): """A coordinator watches process A, then conditionally starts B or C.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() log = [] def fast_task(env): diff --git a/tests/test_sorted_queue.py b/tests/test_sorted_queue.py index dd0f8e2..252484a 100644 --- a/tests/test_sorted_queue.py +++ b/tests/test_sorted_queue.py @@ -2,7 +2,7 @@ import pytest -from ngraph_sim.resources import SortedQueue +from netlab_sim.resources import SortedQueue class _KeyItem: diff --git a/tests/test_store.py b/tests/test_store.py index 2d5521f..b279ef7 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -2,13 +2,13 @@ import pytest -import ngraph_sim +import netlab_sim class TestStorePutAndGet: def test_put_and_get_basic(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) results = [] def producer(env): @@ -29,8 +29,8 @@ def consumer(env): class TestStoreFIFO: def test_fifo_order(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) results = [] def producer(env): @@ -52,8 +52,8 @@ def consumer(env): class TestStoreBlockingWhenEmpty: def test_consumer_waits_for_producer(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) log = [] def consumer(env): @@ -78,8 +78,8 @@ def producer(env): class TestStoreCapacity: def test_producer_blocks_when_full(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env, capacity=2) + env = netlab_sim.Environment() + store = netlab_sim.Store(env, capacity=2) log = [] def producer(env): @@ -105,8 +105,8 @@ def consumer(env): class TestStoreUnlimitedCapacity: def test_unlimited_capacity(self): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) # default is inf + env = netlab_sim.Environment() + store = netlab_sim.Store(env) # default is inf results = [] def producer(env): @@ -129,8 +129,8 @@ class TestStorePutFireAndForget: def test_store_put_fire_and_forget(self): """Call store.put(item) without yielding. Then yield store.get(). Verify the item is retrieved.""" - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) results = [] def proc(env): @@ -146,17 +146,17 @@ def proc(env): class TestStoreZeroCapacityRaises: def test_store_zero_capacity_raises(self): """Store(env, capacity=0) raises ValueError.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError): - ngraph_sim.Store(env, capacity=0) + netlab_sim.Store(env, capacity=0) class TestStorePutCancel: def test_store_put_cancel(self): """Put into a full store (capacity=1, already has item). Cancel the pending put. Verify put_queue is empty.""" - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env, capacity=1) + env = netlab_sim.Environment() + store = netlab_sim.Store(env, capacity=1) results = [] def proc(env): @@ -175,8 +175,8 @@ def proc(env): class TestStoreGetCancel: def test_store_get_cancel(self): """Get from an empty store. Cancel the pending get. Verify get_queue is empty.""" - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env) + env = netlab_sim.Environment() + store = netlab_sim.Store(env) results = [] def proc(env): diff --git a/tests/test_threading.py b/tests/test_threading.py index 4906823..d55a2b5 100644 --- a/tests/test_threading.py +++ b/tests/test_threading.py @@ -11,13 +11,13 @@ import pytest -import ngraph_sim +import netlab_sim def _simulate(seed, n=2000): - env = ngraph_sim.Environment() - store = ngraph_sim.Store(env, capacity=3) - res = ngraph_sim.PreemptiveResource(env, capacity=1) + env = netlab_sim.Environment() + store = netlab_sim.Store(env, capacity=3) + res = netlab_sim.PreemptiveResource(env, capacity=1) log = [] def producer(env): @@ -33,7 +33,7 @@ def consumer(env): yield req yield env.timeout(1 + (i * seed) % 3) total += i * (seed + 1) - except ngraph_sim.Interrupt: + except netlab_sim.Interrupt: log.append(env.now) finally: res.release(req) diff --git a/tests/test_timeout.py b/tests/test_timeout.py index 2862773..b5e3c04 100644 --- a/tests/test_timeout.py +++ b/tests/test_timeout.py @@ -2,19 +2,19 @@ import pytest -import ngraph_sim +import netlab_sim class TestTimeoutBasic: def test_basic_delay(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.timeout(5) env.run() assert env.now == 5 assert evt.processed def test_timeout_value(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): val = yield env.timeout(3, value='result') @@ -25,7 +25,7 @@ def proc(env): assert env.now == 3 def test_zero_delay(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() evt = env.timeout(0) env.run() assert env.now == 0 @@ -33,24 +33,24 @@ def test_zero_delay(self): assert evt.ok def test_negative_delay_raises(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='non-negative'): env.timeout(-1) def test_nan_delay_raises(self): """NaN compares false with everything and would corrupt heap order.""" - env = ngraph_sim.Environment() + env = netlab_sim.Environment() with pytest.raises(ValueError, match='non-negative'): env.timeout(float('nan')) def test_infinite_delay_is_allowed(self): - env = ngraph_sim.Environment() - evt = env.timeout(ngraph_sim.Infinity) - assert env.peek() == ngraph_sim.Infinity + env = netlab_sim.Environment() + evt = env.timeout(netlab_sim.Infinity) + assert env.peek() == netlab_sim.Infinity assert not evt.processed def test_timeout_default_value_is_none(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() def proc(env): val = yield env.timeout(1) @@ -60,7 +60,7 @@ def proc(env): env.run() def test_multiple_timeouts_ordering(self): - env = ngraph_sim.Environment() + env = netlab_sim.Environment() order = [] def p1(env):