Source
tests/purrc/app_eventlog_test.cpp
1
// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).2
// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.3
// System-level "application" test: a small event-log pipeline that only passes4
// if datetime + time + os + io + string all cooperate end to end.5
//6
// Unlike the per-module system tests in stdlib_e2e_test.cpp (which exercise one7
// module each), this is a realistic multi-module program:8
//9
// 1. datetime.format() turns FIXED epochs (deterministic under TZ=UTC) into10
// timestamps, which io.format() + string.upper() compose into log lines;11
// 2. io.open()/File.write() persist the lines to a temp file whose path is12
// built and normalized with os.path.join()/os.path.normpath(), then13
// os.path.isfile() confirms the write landed;14
// 3. io.read_file() reads it back, string.splitlines()/len()/string.count()15
// derive a DETERMINISTIC summary (line count, first/last line, error tally);16
// 4. time.perf_counter() across a tiny sleep yields a monotonic PROPERTY check17
// printed as a boolean (raw clock values are never printed);18
// 5. os.remove() cleans up and os.path.exists() confirms the teardown.19
//20
// The 4th arg pins TZ=UTC so datetime.format() is deterministic. The expected21
// stdout was captured byte-for-byte by compiling+running the program under22
// TZ=UTC before being hardcoded here.24
#include "e2e_harness.hpp"27
TEST(SystemApps, EventLog) {28
e2e::expect_e2e("app_eventlog", R"PURR(import io29
import os30
import string31
import datetime32
import time34
# Fixed epochs (seconds) -> deterministic timestamps under TZ=UTC.35
let epochs = [0.0, 3661.0, 90061.0]36
let levels = ["INFO", "WARN", "ERROR"]37
let msgs = ["service start", "cache miss", "disk full"]39
# Build one normalized temp path with os.path.40
let path = os.path.normpath(os.path.join("/tmp", "cheatah_eventlog", "..", "cheatah_eventlog.log"))42
# Format each event into "TS [LEVEL] msg" via datetime + io.format + string.43
let n = len(epochs)44
let f = io.open(path, "w")45
let i = 046
while i < n {47
let ts = datetime.format(epochs[i], "%Y-%m-%d %H:%M:%S")48
let line = io.format("{} [{}] {}", ts, string.upper(levels[i]), msgs[i])49
f.write(line)50
f.write("\n")51
i = i + 152
}53
f.close()55
# os confirms the file the pipeline just produced exists.56
let wrote_ok = os.path.isfile(path)58
# Read it back with io, split into lines with string.59
let blob = io.read_file(path)60
let lines = string.splitlines(blob)61
let count = len(lines)62
let first = lines[0]63
let last = lines[count - 1]65
# time: deterministic monotonic PROPERTY across a tiny sleep (never print raw).66
let t0 = time.perf_counter()67
time.sleep(0.005)68
let t1 = time.perf_counter()69
let monotonic_ok = t1 >= t071
# Deterministic summary.72
io.print("file:", os.path.basename(path))73
io.print("exists:", wrote_ok)74
io.print("lines:", count)75
io.print("first:", first)76
io.print("last:", last)77
io.print("errors:", string.count(blob, "[ERROR]"))78
io.print("monotonic:", monotonic_ok)80
# Clean up the temp file.81
os.remove(path)82
io.print("cleaned:", not os.path.exists(path))83
)PURR",84
"file: cheatah_eventlog.log\n"85
"exists: True\n"86
"lines: 3\n"87
"first: 1970-01-01 00:00:00 [INFO] service start\n"88
"last: 1970-01-02 01:01:01 [ERROR] disk full\n"89
"errors: 1\n"90
"monotonic: True\n"91
"cleaned: True\n",92
"TZ=UTC ");93
}