Skip to content

Commit

Permalink
Merge pull request #18 from daira/doc-and-tests
Browse files Browse the repository at this point in the history
Doc and test improvements
  • Loading branch information
daira authored Oct 20, 2023
2 parents 55c8871 + 6e2686e commit e726693
Show file tree
Hide file tree
Showing 16 changed files with 408 additions and 71 deletions.
12 changes: 11 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
[flake8]
exclude = .git, __pycache__
ignore = E302

# Justifications for each ignored error or warning:
# * E302: always requiring two blank lines rather than one between top-level items is too annoying and nitpicky.
# * E402: we want imports for tests to go between the main code and the tests.
# * W503, W504: these give false positives for the style of avoiding \ at the end of each line by using parens.
#
# References:
# - https://flake8.pycqa.org/en/latest/user/error-codes.html
# - https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
ignore = E302, E402, W503, W504

max-line-length = 120
1 change: 1 addition & 0 deletions .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
- uses: actions/checkout@v2

- name: Install gnome-keyring
# https://github.com/python-poetry/poetry/issues/2692
run: sudo apt-get install gnome-keyring

- name: Install poetry
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: tests

on: pull_request

jobs:
verify:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Install gnome-keyring
# https://github.com/python-poetry/poetry/issues/2692
run: sudo apt-get install gnome-keyring

- name: Install poetry
run: pip install --user poetry

- name: Install dependencies
run: poetry install --no-root

- name: Run tests
# -p '[a-z]*.py' avoids running tests from __init__.py files twice.
run: poetry run python -m unittest discover -s simtfl -t . -p '[a-z]*.py' --verbose --buffer
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
*.swp
*.save

# API docs
apidoc/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,26 @@ Note the caveats: *experimental*, *simulator*, *research*, *potential*.

poetry run demo

## Programming patterns
## Documentation

The code makes use of the [simpy](https://simpy.readthedocs.io/en/latest/)
discrete event simulation library. This means that functions representing
processes are implemented as generators, so that the library can simulate
timeouts and asynchronous communication (typically faster than real time).
Design documentation is under the `doc/` directory:

We use the convention of putting "(process)" in the doc comment of these
functions. They either must use the `yield` construct, *or* return the
result of calling another "(process)" function (not both).
* [Programming patterns for use of simpy](doc/patterns.md).

Objects that implement processes typically hold the `simpy.Environment` in
an instance variable `self.env`.
You can also generate API documentation by running `./gendoc.sh`. This assumes
that you have run `poetry install` as shown above. The starting point for the
generated documentation is <apidoc/simtfl.html>.

To wait for another process `f()` before continuing, use `yield from f()`.
(If it is the last thing to do in a function with no other `yield`
statements, `return f()` can be used as an optimization.)
## Contributing

A "(process)" function that does nothing should `return skip()`, using
`simtfl.util.skip`.
Please use `./check.sh` before submitting a PR. This currently runs `flake8`
and the unit tests locally.

## Contributing
You can use `./check.sh -k <substring>` to run `flake8` and then only tests
with names matching the given substring. This will not suppress output to
stdout or stderr (but `./check.sh -bk <substring>` will).

Please check `poetry run flake8` before submitting a PR.
To see other options for running unit tests, use `poetry run python -m unittest -h`.

## License

Expand Down
12 changes: 12 additions & 0 deletions check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

set -eu
cd -P -- "$(dirname -- "$(command -v -- "$0")")"

echo Running flake8...
poetry run flake8

echo
echo Running unit tests...
args="${*:---buffer}"
poetry run python -m unittest discover -s simtfl -t . -p '[a-z]*.py' --verbose ${args}
20 changes: 20 additions & 0 deletions doc/patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Programming patterns

The code makes use of the [simpy](https://simpy.readthedocs.io/en/latest/)
discrete event simulation library. This means that functions representing
processes are implemented as generators, so that the library can simulate
timeouts and asynchronous communication (typically faster than real time).

We use the convention of putting "(process)" in the doc comment of these
functions. They either must use the `yield` construct, *or* return the
result of calling another "(process)" function (not both).

Objects that implement processes typically hold the `simpy.Environment` in
an instance variable `self.env`.

To wait for another process `f()` before continuing, use `yield from f()`.
(If it is the last thing to do in a function with no other `yield`
statements, `return f()` can be used as an optimization.)

A "(process)" function that does nothing should `return skip()`, using
`simtfl.util.skip`.
5 changes: 5 additions & 0 deletions gendoc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

set -eu

poetry run pdoc simtfl -o apidoc --no-include-undocumented -d markdown
131 changes: 127 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ simpy = "^4"

[tool.poetry.dev-dependencies]
flake8 = "^6"
pdoc = "^14"

[tool.poetry.scripts]
demo = "simtfl.demo:run"
Expand Down
7 changes: 7 additions & 0 deletions simtfl/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
This is an experimental simulator for research into a potential
[Trailing Finality Layer](https://electric-coin-company.github.io/tfl-book/)
for Zcash.
See the [README](../README.md) for more information.
"""
13 changes: 4 additions & 9 deletions simtfl/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,9 @@ def run():
"""
Runs the demo.
"""
env = Environment()
network = Network(env, delay=4)
network = Network(Environment(), delay=4)
for i in range(10):
network.add_node(PongNode(i, env, network))
network.add_node(PongNode())

network.add_node(PingNode(10, env, network))

for i in range(network.num_nodes()):
env.process(network.start_node(i))

env.run()
network.add_node(PingNode())
network.run_all()
19 changes: 11 additions & 8 deletions simtfl/message.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
"""
Base classes for messages.
"""

from dataclasses import dataclass
from typing import Any


@dataclass(frozen=True)
class PayloadMessage:
"""
A message with an arbitrary payload.
"""
def __init__(self, payload):
"""
Constructs a `PayloadMessage` with the given payload.
"""
self.payload = payload

def __str__(self):
return f"{self.__class__.__name__}({self.payload})"
payload: Any
"""The payload."""
Loading

0 comments on commit e726693

Please sign in to comment.