The simulator writes its own history, not yours
`--mock` is a fake radio, not a fake MeshTerm: what it adverted was recorded to `meshterm.db` like anything a real companion said, so its four invented contacts turned up in the mesh walk, the dashboard and the map of the mesh actually being run. A `--mock` run that names no database now records to `<config_dir>/meshterm-mock.db`, created on first use. `--db` still wins — where a run records and which radio it talks to are different questions, so an explicit path is a precedence rule and not the usage error `--mock --port` is. `$MESHTERM_HOME` remains the only thing that isolates a run whole: the contact and channel caches, the outbox and the remembered devices are untouched by this, and the docs say so where they used to warn that `--mock` recorded into the real history. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
bf29f73311
commit
ff86ff059f
6 files changed
+101
-13
No files matched your search
@@ -9,6 +9,16 @@ one caveat SemVer makes for a leading zero: while the major version is still `0`
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- **`--mock` keeps its invented mesh out of your history.** The simulator is a fake radio,
|
||||
not a fake MeshTerm: what it adverted was written to `meshterm.db` like anything a real
|
||||
companion said, and its four invented contacts then turned up in the mesh walk, the
|
||||
dashboard and the map of the mesh you actually run. A `--mock` run now records to
|
||||
`meshterm-mock.db` beside it, created on first use. Naming a database with `--db` still
|
||||
wins, and `$MESHTERM_HOME` is still the only thing that isolates a run whole — the
|
||||
contact and channel caches, the outbox and the remembered devices are untouched by this.
|
||||
|
||||
## [0.9.0] — 2026-09-22
|
||||
|
||||
**The first public release.** Everything in MeshTerm is new today, so instead of a list of
|
||||
|
||||
+12
-8
@@ -57,8 +57,8 @@ With no command, MeshTerm launches the interactive menu instead.
|
||||
| `--ble ADDRESS` | Bluetooth address of a companion; selects the BLE transport. |
|
||||
| `--ble-pin PIN` | Pairing PIN, if the Bluetooth companion asks for one. |
|
||||
| `--tcp HOST[:PORT]` | Network address of a TCP companion; selects the TCP transport. Default port 5000. |
|
||||
| `--mock` | Use the built-in simulator instead of real hardware. Nothing transmits. |
|
||||
| `--db PATH` | Use this SQLite database instead of `~/.meshterm/meshterm.db`. **It moves the database and nothing else** — see [Where MeshTerm keeps its state](#where-meshterm-keeps-its-state). |
|
||||
| `--mock` | Use the built-in simulator instead of real hardware. Nothing transmits, and the run records to `meshterm-mock.db` rather than your real history. |
|
||||
| `--db PATH` | Use this SQLite database instead of `~/.meshterm/meshterm.db` (or `meshterm-mock.db`, under `--mock`). **It moves the database and nothing else** — see [Where MeshTerm keeps its state](#where-meshterm-keeps-its-state). |
|
||||
| `--json` | Print the answer as JSON instead of aligned text. |
|
||||
| `--absolute` | Print times as ISO-8601 instants rather than relative ages, for this run. |
|
||||
| `-q`, `--quiet` | Suppress console logging entirely (the log file still records). |
|
||||
@@ -97,6 +97,7 @@ of two directories from the same shell.
|
||||
| File | What it holds |
|
||||
| --- | --- |
|
||||
| `meshterm.db` | The history: every packet overheard, every trace walked, every message. **The one file `--db` moves.** |
|
||||
| `meshterm-mock.db` | The same, for the simulator: where a `--mock` run records when it doesn't name a database itself. Absent until you run one. |
|
||||
| `config.toml` | Machine setup — device profiles, where the database lives. Yours to write; MeshTerm only reads it. |
|
||||
| `preferences.toml` | Your overrides of MeshTerm's own behaviour. Lists only what you changed. |
|
||||
| `courier.json` | The outbox — queued messages, waiting and finished. |
|
||||
@@ -114,7 +115,8 @@ weight but none of the identity: the contact and channel caches, the outbox, the
|
||||
admin passwords and the remembered device all live beside it in the config directory and
|
||||
would still be the ones you use every day. To run against a scratch state — a test, a
|
||||
demo, a second radio — set `MESHTERM_HOME`, and set `--db` inside it if you want the
|
||||
database somewhere else again.
|
||||
database somewhere else again. The same holds for the database `--mock` picks for itself:
|
||||
it keeps the simulator's invented mesh out of your history, not out of the caches.
|
||||
|
||||
---
|
||||
|
||||
@@ -140,11 +142,13 @@ Three things the simulator does that a radio does not, all visible in the sample
|
||||
*forced* path (`--path "a1,d4"`) resolves properly. The forced form is what the samples
|
||||
use, and what to build a golden file from.
|
||||
|
||||
> **`--mock` records into your real history unless you tell it not to.** The simulator is
|
||||
> a fake radio, not a fake MeshTerm: what it adverts is written to the database and the
|
||||
> caches like anything else, and invented nodes then turn up in the mesh walk, the
|
||||
> dashboard and the map. Give it its own home — `MESHTERM_HOME=... meshterm --mock …` —
|
||||
> or its own database with `--db`, and it leaves your mesh alone.
|
||||
> **`--mock` records into its own history, not yours — but it still writes the caches.**
|
||||
> The simulator is a fake radio, not a fake MeshTerm: what it adverts is written down like
|
||||
> anything else. The database it writes is `meshterm-mock.db`, so its invented nodes stay
|
||||
> out of your mesh walk, dashboard and map; naming a database with `--db` overrides that
|
||||
> choice. The contact and channel caches, the outbox and the remembered devices are still
|
||||
> the ones you use every day, so a demo that should touch nothing at all gets a home of
|
||||
> its own: `MESHTERM_HOME=... meshterm --mock …`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ Both live in `~/.meshterm`, along with everything else MeshTerm remembers: the S
|
||||
history, the outbox, the contact and channel caches, stored admin passwords, and the log.
|
||||
**`$MESHTERM_HOME` moves the whole directory**, which is the way to run a second radio —
|
||||
or a `--mock` session — without touching the one you use every day. `--db` moves the
|
||||
database alone; the rest stays where it was. [`docs/cli.md`](cli.md#where-meshterm-keeps-its-state)
|
||||
database alone; the rest stays where it was. A `--mock` run that names neither writes to
|
||||
`meshterm-mock.db` beside the real history, so the simulator's invented nodes never enter
|
||||
it. [`docs/cli.md`](cli.md#where-meshterm-keeps-its-state)
|
||||
lists every file.
|
||||
|
||||
Timestamps are stored as UTC and rendered in your local time. History older than the
|
||||
|
||||
+17
-3
@@ -22,7 +22,7 @@ from . import __version__
|
||||
from .context import AppContext
|
||||
from .core import exitcodes, win32dll
|
||||
from .core.admin_store import AdminStore
|
||||
from .core.config import Settings
|
||||
from .core.config import MOCK_DB_FILENAME, Settings
|
||||
from .core.connection import DeviceCommandError, is_connection_lost
|
||||
from .core.device_config import DeviceConfigError
|
||||
from .core.device_store import DeviceStore
|
||||
@@ -175,7 +175,9 @@ def main_callback(
|
||||
help="Network address host[:port] of a TCP companion (selects the TCP transport)",
|
||||
),
|
||||
mock: bool = typer.Option(False, "--mock", help="Use the built-in simulator"),
|
||||
db_path: Path | None = typer.Option(None, "--db", help="SQLite database path"),
|
||||
db_path: Path | None = typer.Option(
|
||||
None, "--db", help="SQLite database path (--mock records to meshterm-mock.db)"
|
||||
),
|
||||
json_output: bool = typer.Option(False, "--json", help="Machine-readable output"),
|
||||
absolute: bool = typer.Option(
|
||||
False, "--absolute", help="Print absolute timestamps instead of relative ages"
|
||||
@@ -198,7 +200,8 @@ def main_callback(
|
||||
ble_pin: Optional BLE pairing PIN for the Bluetooth companion.
|
||||
tcp: Explicit network address ``host[:port]``, selecting the TCP transport.
|
||||
mock: Whether to use the simulator instead of real hardware.
|
||||
db_path: Override the database location.
|
||||
db_path: Override the database location. Without it, a ``--mock`` run records to
|
||||
the simulator's own database rather than the real history.
|
||||
json_output: Print the answer as JSON instead of aligned text.
|
||||
absolute: Print times as ISO-8601 instants rather than relative ages, for this run.
|
||||
quiet: Suppress console logging (file logging continues).
|
||||
@@ -232,6 +235,17 @@ def main_callback(
|
||||
settings = Settings.load()
|
||||
if db_path is not None:
|
||||
settings.db_path = db_path
|
||||
elif mock:
|
||||
# The simulator is a fake radio, not a fake MeshTerm: everything it adverts was
|
||||
# written to the real history like anything a companion said, and its four
|
||||
# invented contacts then turned up in the mesh walk, the dashboard and the map of
|
||||
# the mesh you actually run. A pretend radio gets a pretend history —
|
||||
# ``<config_dir>/meshterm-mock.db``, created on first use — while ``--db`` still
|
||||
# wins, because naming a database is a deliberate claim about where a run records.
|
||||
# ``$MESHTERM_HOME`` remains the only thing that isolates a run whole: the contact
|
||||
# and channel caches, the outbox and the remembered devices live beside the
|
||||
# database either way (see docs/cli.md).
|
||||
settings.db_path = settings.config_dir / MOCK_DB_FILENAME
|
||||
|
||||
# Two front ends, two consoles, and which one this process gets is settled here — a
|
||||
# named subcommand is a scripted run, so it prints on the plain, colourless,
|
||||
|
||||
+12
-1
@@ -34,6 +34,17 @@ else: # pragma: no cover - exercised only on 3.10
|
||||
#: can move it between cases.
|
||||
CONFIG_DIR_ENV = "MESHTERM_HOME"
|
||||
|
||||
#: The history's filename inside the config directory, when ``config.toml`` and ``--db``
|
||||
#: both leave it alone.
|
||||
DB_FILENAME = "meshterm.db"
|
||||
|
||||
#: The simulator's history, kept beside the real one and used by ``--mock`` runs that did
|
||||
#: not name a database themselves. ``--mock`` is a fake radio, not a fake MeshTerm: what
|
||||
#: the simulator adverts is recorded like anything a real companion said, so without a
|
||||
#: database of its own its four invented contacts turn up in the mesh walk, the dashboard
|
||||
#: and the map of the mesh you actually run.
|
||||
MOCK_DB_FILENAME = "meshterm-mock.db"
|
||||
|
||||
|
||||
def default_config_dir() -> Path:
|
||||
"""Return the directory MeshTerm uses for config and data.
|
||||
@@ -138,7 +149,7 @@ class Settings:
|
||||
def __post_init__(self) -> None:
|
||||
"""Derive dependent paths that were not explicitly provided."""
|
||||
if self.db_path is None:
|
||||
self.db_path = self.config_dir / "meshterm.db"
|
||||
self.db_path = self.config_dir / DB_FILENAME
|
||||
|
||||
def resolve_profile(self, name: str | None) -> DeviceProfile | None:
|
||||
"""Look up a profile by name, falling back to the default profile.
|
||||
|
||||
@@ -707,6 +707,53 @@ def test_a_closing_message_goes_to_stderr_too(run) -> None: # noqa: ANN001
|
||||
assert "records stored" in result.stderr
|
||||
|
||||
|
||||
# -- the simulator's own history ------------------------------------------------------
|
||||
|
||||
|
||||
def test_mock_records_into_a_database_of_its_own(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""A pretend radio gets a pretend history, so a demo run leaves the real mesh alone.
|
||||
|
||||
The simulator is a fake radio, not a fake MeshTerm: what it adverts used to be written
|
||||
to ``meshterm.db`` like anything a companion said, and its invented contacts then sat
|
||||
in the mesh walk, the dashboard and the map of the mesh actually being run. The run
|
||||
still records — the history is how a ``--mock`` session's own tools read back what it
|
||||
heard — just not there.
|
||||
"""
|
||||
from meshterm.cli import app
|
||||
|
||||
home = tmp_path / "home"
|
||||
monkeypatch.setenv("MESHTERM_HOME", str(home))
|
||||
|
||||
result = CliRunner().invoke(app, ["--mock", "info"])
|
||||
assert result.exit_code == exitcodes.OK, result.output
|
||||
assert (home / "meshterm-mock.db").exists()
|
||||
assert not (home / "meshterm.db").exists()
|
||||
|
||||
|
||||
def test_an_explicit_db_still_wins_under_mock(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""``--db`` names one exact database, which is a claim the simulator does not override.
|
||||
|
||||
Unlike ``--port``, it is not a contradictory one: where a run records and which radio
|
||||
it talks to are different questions, so this is a precedence rule and not a usage
|
||||
error. It is also what the suite's own ``run`` fixture depends on.
|
||||
"""
|
||||
from meshterm.cli import app
|
||||
|
||||
home = tmp_path / "home"
|
||||
monkeypatch.setenv("MESHTERM_HOME", str(home))
|
||||
named = tmp_path / "named.db"
|
||||
|
||||
result = CliRunner().invoke(app, ["--mock", "--db", str(named), "info"])
|
||||
assert result.exit_code == exitcodes.OK, result.output
|
||||
assert named.exists()
|
||||
assert not (home / "meshterm-mock.db").exists()
|
||||
assert not (home / "meshterm.db").exists()
|
||||
|
||||
|
||||
# -- devices under --mock -------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user