Purple › Module 5 › Lesson 1
Unit Test Rules
Unit test rules literacy names positive and negative test cases, expected match counts, and CI integration — author tests on YOUR $PURPLE_LAB before rule deploy.
Visual · t35_unit_test_rules
Unit test rules literacy. $PURPLE_LAB only. Original Cyberlium.
Opening
Rules without tests are guesses — literacy teaches detection unit tests so Sigma logic validates against sample logs on lab repos you govern.
Detection unit tests pair rules with log fixtures — positive case: log that should match, expected alert. Negative case: benign log that should not match, expected zero alerts. CI runs tests on every PR — pytest with sigma-test or custom replay harness. Failed test blocks merge. Cyberlium writes unit test spec on YOUR $PURPLE_LAB — one positive and one negative case for fictional T1059 rule. Next: Replay Logs.
1. Unit test components (named)
Positive fixture: sample log with malicious CommandLine, expect match=true. Negative fixture: benign admin script log, expect match=false. Test runner: CI job that loads rule and replays fixtures. Assertion: match count, field values, no false match on negative.
On $PURPLE_LAB, write test row — fixture name, expect match, rule ID for one fictional T1059 test.
Command guide
Try these commands — Unit test components (named)
═══ TOOLS & WEBSITES ═══ Browse / read these (authorized learning only — stay in YOUR lab / program scope)
Optional command
jq manual — https://jqlang.github.io/jq/manual/
Sigma testing — https://github.com/SigmaHQ/sigma/wiki/Rule-Creation-Guide Elastic detection testing — https://www.elastic.co/guide/en/security/current/rules-ui.html
═══ INSTALL ═══
Linux (Debian/Ubuntu):
Command — copy this
sudo apt install jq sudo apt install python3
macOS:
Command — copy this
brew install jq brew install python3
Windows:
Command — copy this
choco install jq
Download https://python.org/downloads/
═══ LINUX / macOS ═══
Command — copy this
export PURPLE_LAB=${PURPLE_LAB:-$HOME/cyberlium-lab/t35-purple}
cat > "$PURPLE_LAB/testing/unit-test-plan.md" <<'EOF'
# Detection Unit Test Plan — YOUR lab
## Rule under test
rules/failed-logon-lab.yml (T1110.001 pattern)
## Test cases (FAKE telemetry)
| ID | Input | Expected |
|---|---|---|
| UT-01 | 3x 4625 same src_ip | MATCH |
| UT-02 | single 4625 only | REVIEW (below threshold) |
| UT-03 | 4624 success only | NO MATCH |
## Method
jq select(.event_id==4625) on telemetry/auth.jsonl
NEVER: run credential dump atomics to generate 'real' logs
EOFCommand — copy this
grep -E 'UT-01|4625|NEVER' "$PURPLE_LAB/testing/unit-test-plan.md"
Primary tools to practice this lesson: jq, python3. Reference sites: jq manual (https://jqlang.github.io/jq/manual/); Sigma testing (https://github.com/SigmaHQ/sigma/wiki/Rule-Creation-Guide); Elastic detection testing (https://www.elastic.co/guide/en/security/current/rules-ui.html). Run every command in the box — install first, then the usage lines — only on YOUR lab / program scope.
2. Why unit tests prevent broken deploys
Typo in condition silences rule permanently. Over-broad matcher causes FP on negative fixture. CI gate catches both before lab SIEM deploy. Purple exercises re-run tests after tuning.
Students author lab test specs on notes — production tests live in DaC repos with purple exercise fixtures.
3. Lab boundary
Forbidden: deploying rules with zero test cases. Allowed: unit test rules card — positive and negative fixtures with $PURPLE_LAB fictional logs.
Ship: unit test rules card for YOUR lab rule. Next: Replay Logs.
4. What you ship: unit test rules card for $PURPLE_LAB
Positive and negative fixtures with expectations. $PURPLE_LAB named. chmod 600.
5. What you record before the next lesson
Date. Unit test rules card. $PURPLE_LAB named. File t35-m05-l01-unit-test-rules.txt chmod 600.
6. Wrong vs right: stranger networks vs YOUR purple lab
Worked failure — same MSF word, opposite target. Right never needs a café Wi-Fi or classmate laptop.
Wrong
Deploy rule without any test fixtures. Use live victim logs as positive case without authorization.
Right
Write unit test rules card for YOUR $PURPLE_LAB. Next: Replay Logs.
Mission: author unit tests on YOUR lab rule
1) Define positive and negative fixture purpose. 2) Write test row for each case. 3) Name CI assertion expected. 4) chmod 600.
Stuck? Ask Cyberlium AI Mentor
Negative test is as important as positive — benign noise must not match.
Knowledge Check
APPLY: Detection unit tests primarily:
Multiple choice
Knowledge Check
APPLY: True or False: Negative fixtures verify benign logs do not match the rule.
True or False
Knowledge Check
APPLY: Unit test literacy on Cyberlium uses:
Multiple choice