Skip to content

Commit b79ded7

Browse files
committed
modify pos
1 parent 3771b66 commit b79ded7

21 files changed

Lines changed: 595 additions & 497 deletions

.github/workflows/ci.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
smoke-tests:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
13+
- uses: actions/setup-node@v4
14+
with:
15+
node-version: "20"
16+
17+
- name: Run smoke tests (no deps)
18+
working-directory: ds-mutex
19+
run: npm test

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
Thumbs.db
33
.vscode/
44
*.zip
5+
# DS-Mutex: generated exports (evidence snapshots)
6+
ds-mutex/report/figures/export/**
7+
!ds-mutex/report/figures/export/README.md
8+
!ds-mutex/report/figures/export/.gitkeep

ds-mutex/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The project uses lightweight semantic versioning (pre-1.0): `vMAJOR.MINOR.PATCH`.
6+
7+
## [Unreleased]
8+
- Planned: evaluation write-up, report figures, and reproducibility polish.
9+
10+
## [0.3.1] - YYYY-MM-DD
11+
### Added
12+
- RA message fault controls: drop next in-flight message; arm/drop-next-send (drops next outgoing message).
13+
- Evidence exports: state JSON + trace TXT + preview PNG (timestamped).
14+
15+
### Improved
16+
- Trace clarity for stalled states (e.g., waiting for missing REPLY after a drop).
17+
18+
### Notes
19+
- Ricart–Agrawala module is a teaching-oriented prototype. Safety is prioritised; liveness may be violated under message loss, which is intentionally demonstrated.

ds-mutex/eval/test_plan.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Formal Test Plan (v0.3.x)
2+
3+
This document defines a **reproducible** test plan for the *Distributed Mutual Exclusion Explorer* (Variant 3).
4+
It is designed to support:
5+
- correctness arguments (especially **mutual exclusion / safety**),
6+
- fault + recovery demonstrations,
7+
- repeatable evidence capture for the final report.
8+
9+
> Scope: UI + core simulation behaviour for Token Ring (implemented) and Ricart–Agrawala (prototype).
10+
11+
---
12+
13+
## 1. Test environment
14+
15+
- Browser: Chrome / Edge latest (desktop).
16+
- Local server: `python -m http.server 5500` (or VS Code Live Server).
17+
- URL: `http://localhost:5500/ds-mutex/index.html`
18+
- Run speed: 350ms (default) unless stated.
19+
20+
---
21+
22+
## 2. Definitions / expected properties
23+
24+
### 2.1 Safety (must hold)
25+
- **Mutual exclusion**: at most one process is in the critical section (CS) at any time.
26+
- Safety indicator in UI should remain **OK** in normal runs.
27+
28+
### 2.2 Liveness (may not hold under faults)
29+
- In fault-free runs, requesting processes should eventually enter CS.
30+
- Under **message loss** (RA), liveness may fail (expected teaching outcome).
31+
32+
---
33+
34+
## 3. Evidence policy
35+
36+
For each test:
37+
1. Capture a short trace segment (copy/paste or export).
38+
2. Export evidence when relevant:
39+
- **Export evidence (JSON+trace+PNG)**.
40+
3. Use curated PNGs in `report/figures/` (not `report/figures/export/`).
41+
42+
---
43+
44+
## 4. Manual UI test cases
45+
46+
### TR-01: Token Ring — basic mutual exclusion
47+
**Setup**
48+
- Algorithm: Token Ring
49+
- Processes: 4
50+
- Mode: interactive
51+
52+
**Steps**
53+
1. Click `Request CS` on P1.
54+
2. Click `Run` until P1 enters CS (or `Step` until it happens).
55+
3. While P1 is in CS, click `Request CS` on P2.
56+
4. Click `Step` 3–5 times (do not release P1 yet).
57+
5. Confirm P2 does **not** enter CS while P1 is still in CS.
58+
6. Click `Release CS` on P1.
59+
7. Click `Run` / `Step` until P2 enters CS.
60+
61+
**Expected**
62+
- Safety: OK throughout.
63+
- Exactly one process in CS at a time.
64+
- Trace includes entries and token passes.
65+
66+
---
67+
68+
### TR-02: Token Ring — token loss stalls progress, regeneration recovers
69+
**Setup**
70+
- Algorithm: Token Ring
71+
- Processes: 4
72+
73+
**Steps**
74+
1. Click `Drop token`.
75+
2. Click `Request CS` on P1.
76+
3. Click `Step` 2–3 times (no entry should occur).
77+
4. Click `Regenerate token`.
78+
5. Click `Step` / `Run` until P1 enters CS.
79+
80+
**Expected**
81+
- Before regeneration: no progress due to lost token.
82+
- After regeneration: progress resumes and P1 can enter CS.
83+
- Safety: OK.
84+
85+
---
86+
87+
### TR-03: Token Ring — crash + recovery (demonstration)
88+
**Setup**
89+
- Algorithm: Token Ring
90+
- Processes: 4
91+
92+
**Steps**
93+
1. Click `Crash` on the current token holder (commonly P1 after reset).
94+
2. Observe token loss / stalled behaviour.
95+
3. Click `Recover` for the crashed process.
96+
4. Click `Regenerate token`.
97+
5. Click `Request CS` on any live process and confirm the system can progress again.
98+
99+
**Expected**
100+
- Demonstrates fault + recovery path.
101+
- Safety: OK (or clearly explained if crash in CS produces a warning/violation state in your implementation).
102+
103+
---
104+
105+
### RA-01: Ricart–Agrawala — basic request/reply and CS entry
106+
**Setup**
107+
- Algorithm: Ricart–Agrawala
108+
- Processes: 4
109+
- Mode: interactive
110+
111+
**Steps**
112+
1. Click `Request CS` on P1.
113+
2. Click `Step` repeatedly to deliver messages until P1 enters CS.
114+
3. Click `Release CS` on P1.
115+
4. Confirm deferred replies (if any) are sent and the queue drains.
116+
117+
**Expected**
118+
- Trace shows REQUEST broadcast, REPLY messages, and CS entry.
119+
- Safety: OK.
120+
121+
---
122+
123+
### RA-02: Ricart–Agrawala — tie-break by process ID (same timestamp)
124+
**Setup**
125+
- Algorithm: Ricart–Agrawala
126+
- Processes: 2
127+
- Mode: interactive
128+
129+
**Steps**
130+
1. Click `Request CS` on P1.
131+
2. Immediately click `Request CS` on P2.
132+
3. Click `Step` until one process enters CS.
133+
134+
**Expected**
135+
- With same logical timestamp, smaller numeric PID wins: **P1 enters before P2**.
136+
- Safety: OK.
137+
- Trace makes the tie-break visible (or is explained in report).
138+
139+
---
140+
141+
### RA-03: RA fault — Drop next in-flight message (queue head)
142+
**Purpose**
143+
Demonstrate that message loss can break liveness without breaking safety.
144+
145+
**Setup**
146+
- Algorithm: Ricart–Agrawala
147+
- Processes: 4
148+
149+
**Steps**
150+
1. Click `Request CS` on P1.
151+
2. Click `Step` once or twice until queue is non-empty.
152+
3. Click `Drop next in-flight msg`.
153+
4. Continue clicking `Step` until the queue becomes empty.
154+
155+
**Expected**
156+
- Safety: OK.
157+
- If the dropped message was a required REQUEST/REPLY, P1 may never enter CS.
158+
- Trace should explicitly explain who is waiting for whom (stalled reason).
159+
160+
---
161+
162+
### RA-04: RA fault — drop-next-send (drop next outgoing message)
163+
**Setup**
164+
- Algorithm: Ricart–Agrawala
165+
- Processes: 4
166+
167+
**Steps**
168+
1. Click `Arm drop-next-send`.
169+
2. Click `Request CS` on P1.
170+
3. Click `Step` until queue drains.
171+
172+
**Expected**
173+
- Safety: OK.
174+
- Progress may stall due to a missing message.
175+
- Trace clearly states the waiting condition (e.g., “P1 is waiting for REPLY from P2”).
176+
177+
---
178+
179+
## 5. Optional automated smoke tests (recommended)
180+
181+
Run locally:
182+
```bash
183+
cd ds-mutex
184+
npm test
185+
```
186+
187+
This runs `tools/smoke_tests.mjs` (no dependencies) and validates:
188+
- basic mutual exclusion sequences for Token Ring,
189+
- RA tie-break ordering (2 processes),
190+
- RA “drop-next-send” produces a stalled state (expected).
191+
192+
CI runs the same tests via GitHub Actions (see `.github/workflows/ci.yml`).

ds-mutex/index.html

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@
8888
th { background: #f3f3f3; }
8989
.ok { color: var(--ok); font-weight: 700; }
9090
.bad { color: var(--bad); font-weight: 700; }
91-
9291
#trace {
9392
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
9493
font-size: 12px;
@@ -100,26 +99,6 @@
10099
overflow: auto;
101100
white-space: pre;
102101
}
103-
104-
#nextEvents {
105-
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
106-
font-size: 12px;
107-
background: #fff;
108-
border: 1px solid #e3e3e3;
109-
border-radius: 10px;
110-
padding: 10px;
111-
max-height: 160px;
112-
overflow: auto;
113-
white-space: pre;
114-
margin-top: 8px;
115-
}
116-
117-
#scenarioDesc {
118-
color: var(--muted);
119-
font-size: 12px;
120-
margin-top: 6px;
121-
}
122-
123102
#previewCanvas {
124103
border: 1px dashed #bbb;
125104
border-radius: 10px;
@@ -172,14 +151,15 @@ <h1>Distributed Mutual Exclusion Explorer (v0.3)</h1>
172151
<div class="row">
173152
<button id="dropTokenBtn">Drop token</button>
174153
<button id="regenTokenBtn">Regenerate token</button>
175-
<button id="dropNextMsgBtn">Drop next message</button>
154+
<button id="dropNextMsgBtn">Drop next in-flight msg</button>
155+
<button id="toggleDropNextSendBtn">Arm drop-next-send</button>
176156
<button id="clearTraceBtn">Clear trace</button>
177157
</div>
178158
<div class="row">
179159
<div>Safety: <strong id="safetyLabel"></strong></div>
180160
<span class="pill" id="metricsPill"></span>
181161
</div>
182-
<p class="note">Token controls apply to Token Ring; message drop applies to Ricart–Agrawala.</p>
162+
<p class="note">Token controls apply to Token Ring. For Ricart–Agrawala, “Drop next in-flight msg” removes the queue head; “drop-next-send” drops the next outgoing message.</p>
183163
</fieldset>
184164
</div>
185165

@@ -218,34 +198,19 @@ <h1>Distributed Mutual Exclusion Explorer (v0.3)</h1>
218198

219199
<fieldset>
220200
<legend>Scenarios</legend>
221-
222201
<div class="row">
223202
<button id="exportBtn">Export JSON (state)</button>
224203
<button id="exportTraceBtn">Export trace (txt)</button>
204+
<button id="exportAllBtn">Export evidence (JSON+trace+PNG)</button>
225205
<input id="importFile" type="file" accept="application/json" />
226-
</div>
227-
228-
<div class="row">
229206
<button id="loadExampleInteractiveBtn">Load example (interactive)</button>
230207
<button id="loadExampleScriptBtn">Load example (scripted)</button>
231208
<button id="loadCrashDemoBtn">Load crash demo (scripted)</button>
232209
<button id="loadRaDemoBtn">Load RA conflict demo (scripted)</button>
233210
<button id="loadRaTieDemoBtn">Load RA tiebreak demo (scripted)</button>
234211
<button id="exitScriptBtn" disabled>Exit script mode</button>
235212
</div>
236-
237-
<div class="row">
238-
<span class="pill" id="scenarioPill">scenario: —</span>
239-
<span class="pill" id="scriptProgressPill">script: —</span>
240-
</div>
241-
242-
<div id="scenarioDesc"></div>
243-
<div class="note">Next events (script mode only):</div>
244-
<div id="nextEvents"></div>
245-
246-
<p class="note">
247-
Interactive mode lets you issue requests manually. Scripted mode replays a predefined event sequence from a JSON scenario file.
248-
</p>
213+
<p class="note">Interactive mode lets you issue requests manually. Scripted mode replays a predefined event sequence from a JSON scenario file. Exports use a session timestamp + snapshot counter for easier evidence management.</p>
249214
</fieldset>
250215

251216
<fieldset>

0 commit comments

Comments
 (0)