1
0
mirror of https://github.com/gsi-upm/soil synced 2025-08-23 19:52:19 +00:00

Big refactor v0.30

All test pass, except for the TestConfig suite, which is not too critical as the
plan for this version onwards is to avoid configuration as much as possible.
This commit is contained in:
J. Fernando Sánchez
2023-04-09 04:19:24 +02:00
parent 2869b1e1e6
commit 73282530fd
45 changed files with 721 additions and 82265 deletions

View File

@@ -106,7 +106,7 @@ class TestAgents(TestCase):
"""
# There are two agents, they try to send pings
# This is arguably a very contrived example. In practice, the or
# This is arguably a very contrived example.
# There should be a delay of one step between agent 0 and 1
# On the first step:
# Agent 0 sends a PING, but blocks before a PONG

View File

@@ -1,4 +1,4 @@
from unittest import TestCase
from unittest import TestCase, skip
import os
import yaml
import copy
@@ -23,6 +23,7 @@ def isequal(a, b):
assert a == b
@skip("new versions of soil do not rely on configuration files")
class TestConfig(TestCase):
def test_conversion(self):
expected = serialization.load_file(join(ROOT, "complete_converted.yml"))[0]
@@ -59,16 +60,16 @@ class TestConfig(TestCase):
"""
cfg = {
"name": "CounterAgent",
"network_params": {"path": join(ROOT, "test.gexf")},
"agent_class": "CounterModel",
"model_params": {
"topology": join(ROOT, "test.gexf"),
"agent_class": "CounterModel",
},
# 'states': [{'times': 10}, {'times': 20}],
"max_time": 2,
"dry_run": True,
"num_trials": 1,
"environment_params": {},
}
conf = config.convert_old(cfg)
s = simulation.from_config(conf)
s = simulation.from_config(cfg)
env = s.get_env()
assert len(env.G.nodes) == 2

View File

@@ -3,7 +3,7 @@ import os
from os.path import join
from glob import glob
from soil import simulation, config
from soil import simulation, config, do_not_run
ROOT = os.path.abspath(os.path.dirname(__file__))
EXAMPLES = join(ROOT, "..", "examples")
@@ -12,6 +12,7 @@ FORCE_TESTS = os.environ.get("FORCE_TESTS", "")
class TestExamples(TestCase):
"""Empty class that will be populated with auto-discovery tests for every example"""
pass
@@ -45,7 +46,7 @@ def add_example_tests():
continue
for sim in simulation.iter_from_config(path):
sim_paths.append((sim, path))
for path in glob(join(EXAMPLES, '**', '*.py')):
for path in glob(join(EXAMPLES, '**', '*_sim.py')):
for sim in simulation.iter_from_py(path):
sim_paths.append((sim, path))

View File

@@ -6,6 +6,7 @@ import sqlite3
from unittest import TestCase
from soil import exporters
from soil import environment
from soil import simulation
from soil import agents
@@ -38,15 +39,14 @@ class Exporters(TestCase):
def test_basic(self):
# We need to add at least one agent to make sure the scheduler
# ticks every step
class SimpleEnv(environment.Environment):
def init(self):
self.add_agent(agent_class=agents.BaseAgent)
num_trials = 5
max_time = 2
config = {
"name": "exporter_sim",
"model_params": {"agents": [{"agent_class": agents.BaseAgent}]},
"max_time": max_time,
"num_trials": num_trials,
}
s = simulation.from_config(config)
s = simulation.Simulation(num_trials=num_trials, max_time=max_time, name="exporter_sim", dry_run=True, model=SimpleEnv)
for env in s.run_simulation(exporters=[Dummy], dry_run=True):
assert len(env.agents) == 1
@@ -64,12 +64,14 @@ class Exporters(TestCase):
n_trials = 5
config = {
"name": "exporter_sim",
"network_params": {"generator": "complete_graph", "n": 4},
"agent_class": "CounterModel",
"model_params": {
"network_generator": "complete_graph",
"network_params": {"n": 4},
"agent_class": "CounterModel",
},
"max_time": 2,
"num_trials": n_trials,
"dry_run": False,
"environment_params": {},
}
output = io.StringIO()
s = simulation.from_config(config)

View File

@@ -29,8 +29,8 @@ class TestMain(TestCase):
"""A simulation with a base behaviour should do nothing"""
config = {
"model_params": {
"network_params": {"path": join(ROOT, "test.gexf")},
"agent_class": "BaseAgent",
"topology": join(ROOT, "test.gexf"),
"agent_class": "NetworkAgent",
}
}
s = simulation.from_config(config)
@@ -62,27 +62,13 @@ class TestMain(TestCase):
"""
The initial states should be applied to the agent and the
agent should be able to update its state."""
config = {
"version": "2",
"name": "CounterAgent",
"dry_run": True,
"num_trials": 1,
"max_time": 2,
"model_params": {
"topology": {"path": join(ROOT, "test.gexf")},
"agents": {
"agent_class": "CounterModel",
"topology": True,
"fixed": [{"state": {"times": 10}}, {"state": {"times": 20}}],
},
},
}
s = simulation.from_config(config)
env = s.get_env()
assert isinstance(env.agents[0], agents.CounterModel)
assert env.agents[0].G == env.G
assert env.agents[0]["times"] == 10
env = Environment()
env.add_agent(agents.Ticker, times=10)
env.add_agent(agents.Ticker, times=20)
assert isinstance(env.agents[0], agents.Ticker)
assert env.agents[0]["times"] == 10
assert env.agents[1]["times"] == 20
env.step()
assert env.agents[0]["times"] == 11
assert env.agents[1]["times"] == 21
@@ -90,18 +76,8 @@ class TestMain(TestCase):
def test_init_and_count_agents(self):
"""Agents should be properly initialized and counting should filter them properly"""
# TODO: separate this test into two or more test cases
config = {
"max_time": 10,
"model_params": {
"agents": [
{"agent_class": CustomAgent, "weight": 1, "topology": True},
{"agent_class": CustomAgent, "weight": 3, "topology": True},
],
"topology": {"path": join(ROOT, "test.gexf")},
},
}
s = simulation.from_config(config)
env = s.run_simulation(dry_run=True)[0]
env = Environment(topology=join(ROOT, "test.gexf"))
env.populate_network([CustomAgent.w(weight=1), CustomAgent.w(weight=3)])
assert env.agents[0].weight == 1
assert env.count_agents() == 2
assert env.count_agents(weight=1) == 1
@@ -110,26 +86,28 @@ class TestMain(TestCase):
def test_torvalds_example(self):
"""A complete example from a documentation should work."""
config = serialization.load_file(join(EXAMPLES, "torvalds.yml"))[0]
config["model_params"]["network_params"]["path"] = join(
EXAMPLES, config["model_params"]["network_params"]["path"]
)
s = simulation.from_config(config)
env = s.run_simulation(dry_run=True)[0]
for a in env.network_agents:
skill_level = a.state["skill_level"]
if a.id == "Torvalds":
assert skill_level == "God"
assert a.state["total"] == 3
assert a.state["neighbors"] == 2
elif a.id == "balkian":
assert skill_level == "developer"
assert a.state["total"] == 3
assert a.state["neighbors"] == 1
else:
assert skill_level == "beginner"
assert a.state["total"] == 3
assert a.state["neighbors"] == 1
owd = os.getcwd()
pyfile = join(EXAMPLES, "torvalds_sim.py")
try:
os.chdir(os.path.dirname(pyfile))
s = simulation.from_py(pyfile)
env = s.run_simulation(dry_run=True)[0]
for a in env.network_agents:
skill_level = a["skill_level"]
if a.node_id == "Torvalds":
assert skill_level == "God"
assert a["total"] == 3
assert a["neighbors"] == 2
elif a.node_id == "balkian":
assert skill_level == "developer"
assert a["total"] == 3
assert a["neighbors"] == 1
else:
assert skill_level == "beginner"
assert a["total"] == 3
assert a["neighbors"] == 1
finally:
os.chdir(owd)
def test_serialize_class(self):
ser, name = serialization.serialize(agents.BaseAgent, known_modules=[])
@@ -166,11 +144,6 @@ class TestMain(TestCase):
assert ser == "BaseAgent"
pickle.dumps(ser)
def test_templates(self):
"""Loading a template should result in several configs"""
configs = serialization.load_file(join(EXAMPLES, "template.yml"))
assert len(configs) > 0
def test_until(self):
n_runs = 0
@@ -183,7 +156,7 @@ class TestMain(TestCase):
n_trials = 50
max_time = 2
s = simulation.Simulation(
model_params={"agents": [{"agent_class": CheckRun}]},
model_params=dict(agents=dict(agent_classes=[CheckRun], k=1)),
num_trials=n_trials,
max_time=max_time,
)

View File

@@ -19,13 +19,11 @@ class TestNetwork(TestCase):
Load a graph from file if the extension is known.
Raise an exception otherwise.
"""
config = {"network_params": {"path": join(ROOT, "test.gexf")}}
G = network.from_config(config["network_params"])
G = network.from_topology(join(ROOT, "test.gexf"))
assert G
assert len(G) == 2
with self.assertRaises(AttributeError):
config = {"network_params": {"path": join(ROOT, "unknown.extension")}}
G = network.from_config(config["network_params"])
G = network.from_topology(join(ROOT, "unknown.extension"))
print(G)
def test_generate_barabasi(self):
@@ -33,12 +31,12 @@ class TestNetwork(TestCase):
If no path is given, a generator and network parameters
should be used to generate a network
"""
cfg = {"params": {"generator": "barabasi_albert_graph"}}
cfg = {"generator": "barabasi_albert_graph"}
with self.assertRaises(Exception):
G = network.from_config(cfg)
cfg["params"]["n"] = 100
cfg["params"]["m"] = 10
G = network.from_config(cfg)
G = network.from_params(**cfg)
cfg["n"] = 100
cfg["m"] = 10
G = network.from_params(**cfg)
assert len(G) == 100
def test_save_geometric(self):
@@ -54,18 +52,8 @@ class TestNetwork(TestCase):
def test_networkenvironment_creation(self):
"""Networkenvironment should accept netconfig as parameters"""
model_params = {
"topology": {"path": join(ROOT, "test.gexf")},
"agents": {
"topology": True,
"distribution": [
{
"agent_class": CustomAgent,
}
],
},
}
env = environment.Environment(**model_params)
env = environment.Environment(topology=join(ROOT, "test.gexf"))
env.populate_network(CustomAgent)
assert env.G
env.step()
assert len(env.G) == 2
@@ -76,18 +64,9 @@ class TestNetwork(TestCase):
def test_custom_agent_neighbors(self):
"""Allow for search of neighbors with a certain state_id"""
config = {
"model_params": {
"topology": {"path": join(ROOT, "test.gexf")},
"agents": {
"topology": True,
"distribution": [{"weight": 1, "agent_class": CustomAgent}],
},
},
"max_time": 10,
}
s = simulation.from_config(config)
env = s.run_simulation(dry_run=True)[0]
env = environment.Environment()
env.create_network(join(ROOT, "test.gexf"))
env.populate_network(CustomAgent)
assert env.agents[1].count_agents(state_id="normal") == 2
assert env.agents[1].count_agents(state_id="normal", limit_neighbors=True) == 1
assert env.agents[0].count_neighbors() == 1
@@ -97,10 +76,8 @@ class TestNetwork(TestCase):
G = nx.Graph()
G.add_node(3)
G.add_edge(1, 2)
distro = agents.calculate_distribution(agent_class=agents.NetworkAgent)
aconfig = config.AgentConfig(distribution=distro, topology=True)
env = environment.Environment(name="Test", topology=G, agents=aconfig)
lst = list(env.network_agents)
env = environment.Environment(name="Test", topology=G)
env.populate_network(agents.NetworkAgent)
a2 = env.find_one(node_id=2)
a3 = env.find_one(node_id=3)

View File

@@ -46,7 +46,8 @@ class TestMain(TestCase):
break
done.append(self.now)
env = environment.Environment(agents=[{"agent_class": CondAgent}])
env = environment.Environment()
env.add_agent(CondAgent)
while env.schedule.time < 11:
times.append(env.now)