test(ethos): D-2 pre-fix tests for ETHOS compliance violations

Pre-fix tests documenting emoji in log statements and fmt.Printf
used as logging across server and agent codebases.

Tests added:
- Server emoji: machine_binding.go, agents.go, update handlers (6 tests)
- Server fmt.Printf: queries, handlers, services (6 tests)
- Agent emoji: main.go log paths, migration executor (4 tests)
- Exemptions: display/terminal.go, setup.go (2 tests, always pass)

Current state: 8 FAIL, 8 PASS, 2 ALWAYS-PASS.
All prior tests pass. No regressions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 10:14:01 -04:00
parent 47aa1da604
commit 0da761243b
10 changed files with 553 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package main
// ethos_emoji_test.go — Pre-fix tests for emoji in agent main.go log statements.
// D-2: main.go has emoji in token renewal and install result log paths.
// EXCLUDES: registration CLI output (lines 294-322) and startup banner
// (lines 691-697) which are intentional user-facing output.
import (
"os"
"strings"
"testing"
)
func hasEmojiRune(s string) bool {
for _, r := range s {
if r >= 0x1F300 || (r >= 0x2600 && r <= 0x27BF) {
return true
}
}
return false
}
func TestMainGoHasEmojiInLogStatements(t *testing.T) {
// D-2: main.go has emoji in log statements for token renewal
// and install results. These are NOT user-facing CLI output.
content, err := os.ReadFile("agent/main.go")
if err != nil {
t.Fatalf("failed to read agent/main.go: %v", err)
}
src := string(content)
lines := strings.Split(src, "\n")
// Count emoji in log.Printf lines only (not fmt.Printf CLI output)
emojiLogCount := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if strings.Contains(trimmed, "log.Printf") && hasEmojiRune(trimmed) {
emojiLogCount++
}
if strings.Contains(trimmed, "log.Println") && hasEmojiRune(trimmed) {
emojiLogCount++
}
}
if emojiLogCount == 0 {
t.Error("[ERROR] [agent] [main] D-2 already fixed: no emoji in main.go log statements")
}
t.Logf("[INFO] [agent] [main] D-2 confirmed: %d log.Printf/Println with emoji in main.go", emojiLogCount)
}
func TestMainGoLogStatementsHaveNoEmoji(t *testing.T) {
content, err := os.ReadFile("agent/main.go")
if err != nil {
t.Fatalf("failed to read agent/main.go: %v", err)
}
src := string(content)
lines := strings.Split(src, "\n")
for i, line := range lines {
trimmed := strings.TrimSpace(line)
isLog := strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "log.Println")
if isLog && hasEmojiRune(trimmed) {
t.Errorf("[ERROR] [agent] [main] emoji in log at line %d", i+1)
}
}
}

View File

@@ -0,0 +1,43 @@
package display
// ethos_exempt_test.go — Exemption documentation for terminal display emoji.
// D-2: display/terminal.go emoji is EXEMPT from ETHOS #1.
// This is intentional user-facing terminal UI, not log output.
// Do NOT modify this file in the D-2 fix pass.
import (
"os"
"testing"
)
func TestTerminalDisplayIsExemptFromEthos(t *testing.T) {
// D-2: display/terminal.go emoji is EXEMPT.
// This is intentional user-facing terminal UI.
// ETHOS #1 applies to log statements, not UI rendering.
_, err := os.Stat("terminal.go")
if err != nil {
t.Skip("[INFO] [agent] [display] terminal.go not found")
}
content, err := os.ReadFile("terminal.go")
if err != nil {
t.Fatalf("failed to read terminal.go: %v", err)
}
// Confirm emoji IS present (intentional)
hasEmoji := false
for _, r := range string(content) {
if r >= 0x1F300 || (r >= 0x2600 && r <= 0x27BF) {
hasEmoji = true
break
}
}
if !hasEmoji {
t.Log("[INFO] [agent] [display] terminal.go has no emoji (ok — may have been cleaned)")
} else {
t.Log("[INFO] [agent] [display] terminal.go has emoji (EXEMPT — intentional terminal UI)")
}
t.Log("[INFO] [agent] [display] EXEMPTION: display/terminal.go emoji is intentional UI, not log output")
}

View File

@@ -0,0 +1,61 @@
package migration
// ethos_emoji_test.go — Pre-fix tests for emoji in migration executor output.
// D-2: migration/executor.go uses emoji in progress output.
import (
"os"
"strings"
"testing"
)
func hasEmojiR(s string) bool {
for _, r := range s {
if r >= 0x1F300 || (r >= 0x2600 && r <= 0x27BF) {
return true
}
}
return false
}
func TestMigrationExecutorHasEmojiInOutput(t *testing.T) {
// D-2: migration/executor.go uses emoji in progress output.
content, err := os.ReadFile("executor.go")
if err != nil {
t.Fatalf("failed to read executor.go: %v", err)
}
src := string(content)
lines := strings.Split(src, "\n")
emojiCount := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if (strings.Contains(trimmed, "fmt.Printf") || strings.Contains(trimmed, "fmt.Println")) && hasEmojiR(trimmed) {
emojiCount++
}
}
if emojiCount == 0 {
t.Error("[ERROR] [agent] [migration] D-2 already fixed: no emoji in executor.go")
}
t.Logf("[INFO] [agent] [migration] D-2 confirmed: %d output lines with emoji in executor.go", emojiCount)
}
func TestMigrationExecutorHasNoEmojiInOutput(t *testing.T) {
content, err := os.ReadFile("executor.go")
if err != nil {
t.Fatalf("failed to read executor.go: %v", err)
}
src := string(content)
lines := strings.Split(src, "\n")
for i, line := range lines {
trimmed := strings.TrimSpace(line)
if (strings.Contains(trimmed, "fmt.Printf") || strings.Contains(trimmed, "fmt.Println")) && hasEmojiR(trimmed) {
t.Errorf("[ERROR] [agent] [migration] emoji in output at line %d", i+1)
}
}
}

View File

@@ -0,0 +1,94 @@
package handlers_test
// ethos_emoji_test.go — Pre-fix tests for emoji in handler log statements.
// D-2: agents.go, agent_updates.go, update_handler.go, updates.go have emoji in logs.
import (
"os"
"strings"
"testing"
)
func hasEmojiChar(s string) bool {
for _, r := range s {
if r >= 0x1F300 || (r >= 0x2600 && r <= 0x27BF) {
return true
}
}
return false
}
func countEmojiLogLines(filepath string) (int, error) {
content, err := os.ReadFile(filepath)
if err != nil {
return 0, err
}
count := 0
for _, line := range strings.Split(string(content), "\n") {
trimmed := strings.TrimSpace(line)
if (strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "log.Println")) && hasEmojiChar(trimmed) {
count++
}
}
return count, nil
}
func TestAgentsHandlerHasEmojiInLogs(t *testing.T) {
// D-2: agents.go has ~9 emoji in log statements including
// heartbeat, rapid mode, and status indicators.
count, err := countEmojiLogLines("agents.go")
if err != nil {
t.Fatalf("failed to read agents.go: %v", err)
}
if count == 0 {
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no emoji in agents.go logs")
}
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d log statements with emoji in agents.go", count)
}
func TestAgentsHandlerHasNoEmojiInLogs(t *testing.T) {
count, err := countEmojiLogLines("agents.go")
if err != nil {
t.Fatalf("failed to read agents.go: %v", err)
}
if count > 0 {
t.Errorf("[ERROR] [server] [handlers] %d emoji-containing log statements in agents.go.\n"+
"D-2: replace emoji with ETHOS [TAG] format text.", count)
}
}
func TestUpdateHandlersHaveEmojiInLogs(t *testing.T) {
// D-2: agent_updates.go, update_handler.go, updates.go have emoji in logs.
files := []string{"agent_updates.go", "update_handler.go", "updates.go"}
total := 0
for _, f := range files {
count, err := countEmojiLogLines(f)
if err != nil {
t.Logf("[WARNING] [server] [handlers] could not read %s: %v", f, err)
continue
}
total += count
}
if total == 0 {
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no emoji in update handler logs")
}
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d emoji log lines across update handlers", total)
}
func TestUpdateHandlersHaveNoEmojiInLogs(t *testing.T) {
files := []string{"agent_updates.go", "update_handler.go", "updates.go"}
for _, f := range files {
count, err := countEmojiLogLines(f)
if err != nil {
continue
}
if count > 0 {
t.Errorf("[ERROR] [server] [handlers] %d emoji log lines in %s", count, f)
}
}
}

View File

@@ -0,0 +1,50 @@
package handlers_test
// ethos_logging_test.go — Pre-fix tests for fmt.Printf used as logging in handlers.
// D-2: docker_reports.go and metrics.go use fmt.Printf for warnings.
// EXCLUDES: setup.go (legitimate CLI wizard output).
import (
"os"
"strings"
"testing"
)
func TestHandlerFilesUseFmtPrintfForLogging(t *testing.T) {
// D-2: handlers use fmt.Printf for warning messages.
// EXCLUDES setup.go which is legitimate CLI output.
files := []string{"docker_reports.go", "metrics.go"}
total := 0
for _, f := range files {
content, err := os.ReadFile(f)
if err != nil {
t.Logf("[WARNING] [server] [handlers] could not read %s: %v", f, err)
continue
}
count := strings.Count(string(content), "fmt.Printf")
total += count
}
if total == 0 {
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no fmt.Printf in handler logs")
}
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d fmt.Printf in docker_reports.go + metrics.go", total)
}
func TestHandlerFilesUseStructuredLogging(t *testing.T) {
files := []string{"docker_reports.go", "metrics.go"}
for _, f := range files {
content, err := os.ReadFile(f)
if err != nil {
continue
}
count := strings.Count(string(content), "fmt.Printf")
if count > 0 {
t.Errorf("[ERROR] [server] [handlers] %d fmt.Printf calls in %s.\n"+
"D-2: use log.Printf with [TAG] [server] [handlers] format.", count, f)
}
}
}

View File

@@ -0,0 +1,33 @@
package handlers_test
// ethos_setup_exempt_test.go — Exemption documentation for setup wizard output.
// D-2: setup.go fmt.Printf is EXEMPT from ETHOS #1.
// The setup wizard is user-facing CLI output, not background log statements.
// Do NOT modify setup.go fmt.Printf in D-2 fix pass.
import (
"os"
"strings"
"testing"
)
func TestSetupHandlerIsExemptFromEthos(t *testing.T) {
// D-2: setup.go fmt.Printf is EXEMPT.
// The setup wizard is user-facing CLI output.
// ETHOS #1 applies to background log statements.
content, err := os.ReadFile("setup.go")
if err != nil {
t.Fatalf("failed to read setup.go: %v", err)
}
hasFmtPrint := strings.Contains(string(content), "fmt.Printf") ||
strings.Contains(string(content), "fmt.Println")
if !hasFmtPrint {
t.Log("[INFO] [server] [handlers] setup.go has no fmt.Printf (may have been restructured)")
} else {
t.Log("[INFO] [server] [handlers] setup.go uses fmt.Printf (EXEMPT — CLI wizard output)")
}
t.Log("[INFO] [server] [handlers] EXEMPTION: setup.go fmt.Printf is intentional CLI output")
}

View File

@@ -0,0 +1,62 @@
package middleware_test
// ethos_emoji_test.go — Pre-fix tests for emoji in middleware log statements.
// D-2: machine_binding.go uses emoji in security log messages.
import (
"os"
"strings"
"testing"
)
func hasEmoji(s string) bool {
for _, r := range s {
if r >= 0x1F300 || (r >= 0x2600 && r <= 0x27BF) {
return true
}
}
return false
}
func TestMachineBindingMiddlewareHasEmojiInLogs(t *testing.T) {
// D-2: machine_binding.go uses emoji in security alert and
// validation log messages. ETHOS #1 prohibits emoji in log output.
content, err := os.ReadFile("machine_binding.go")
if err != nil {
t.Fatalf("failed to read machine_binding.go: %v", err)
}
src := string(content)
// Find log lines with emoji
lines := strings.Split(src, "\n")
emojiLogCount := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if (strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "fmt.Printf")) && hasEmoji(trimmed) {
emojiLogCount++
}
}
if emojiLogCount == 0 {
t.Error("[ERROR] [server] [middleware] D-2 already fixed: no emoji in machine_binding.go logs")
}
t.Logf("[INFO] [server] [middleware] D-2 confirmed: %d log statements with emoji in machine_binding.go", emojiLogCount)
}
func TestMachineBindingMiddlewareHasNoEmojiInLogs(t *testing.T) {
content, err := os.ReadFile("machine_binding.go")
if err != nil {
t.Fatalf("failed to read machine_binding.go: %v", err)
}
src := string(content)
lines := strings.Split(src, "\n")
for i, line := range lines {
trimmed := strings.TrimSpace(line)
if (strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "fmt.Printf")) && hasEmoji(trimmed) {
t.Errorf("[ERROR] [server] [middleware] emoji in log at line %d: %s", i+1, trimmed[:80])
}
}
}

View File

@@ -0,0 +1,51 @@
package queries_test
// ethos_logging_test.go — Pre-fix tests for fmt.Printf used as logging.
// D-2: Database query files use fmt.Printf for warnings and cleanup.
import (
"os"
"strings"
"testing"
)
func TestQueriesUseFmtPrintfForLogging(t *testing.T) {
// D-2: Database query files use fmt.Printf for warning and cleanup
// messages. These should use log.Printf with ETHOS format.
files := []string{"docker.go", "metrics.go", "updates.go"}
total := 0
for _, f := range files {
content, err := os.ReadFile(f)
if err != nil {
t.Logf("[WARNING] [server] [database] could not read %s: %v", f, err)
continue
}
count := strings.Count(string(content), "fmt.Printf")
count += strings.Count(string(content), "fmt.Println")
total += count
}
if total == 0 {
t.Error("[ERROR] [server] [database] D-2 already fixed: no fmt.Printf in query files")
}
t.Logf("[INFO] [server] [database] D-2 confirmed: %d fmt.Printf calls across query files", total)
}
func TestQueriesUseStructuredLogging(t *testing.T) {
files := []string{"docker.go", "metrics.go", "updates.go"}
for _, f := range files {
content, err := os.ReadFile(f)
if err != nil {
continue
}
count := strings.Count(string(content), "fmt.Printf")
count += strings.Count(string(content), "fmt.Println")
if count > 0 {
t.Errorf("[ERROR] [server] [database] %d fmt.Printf calls in %s.\n"+
"D-2: use log.Printf with [TAG] [server] [database] format.", count, f)
}
}
}

View File

@@ -0,0 +1,37 @@
package services_test
// ethos_logging_test.go — Pre-fix tests for fmt.Printf in services.
// D-2: security_settings_service.go uses fmt.Printf for audit log warning.
import (
"os"
"strings"
"testing"
)
func TestServicesUseFmtPrintfForLogging(t *testing.T) {
content, err := os.ReadFile("security_settings_service.go")
if err != nil {
t.Fatalf("failed to read security_settings_service.go: %v", err)
}
count := strings.Count(string(content), "fmt.Printf")
if count == 0 {
t.Error("[ERROR] [server] [services] D-2 already fixed: no fmt.Printf in security_settings_service.go")
}
t.Logf("[INFO] [server] [services] D-2 confirmed: %d fmt.Printf calls in security_settings_service.go", count)
}
func TestServicesUseStructuredLogging(t *testing.T) {
content, err := os.ReadFile("security_settings_service.go")
if err != nil {
t.Fatalf("failed to read security_settings_service.go: %v", err)
}
count := strings.Count(string(content), "fmt.Printf")
if count > 0 {
t.Errorf("[ERROR] [server] [services] %d fmt.Printf calls in security_settings_service.go.\n"+
"D-2: use log.Printf with ETHOS format.", count)
}
}

53
docs/D2_PreFix_Tests.md Normal file
View File

@@ -0,0 +1,53 @@
# D-2 Pre-Fix Test Suite
**Date:** 2026-03-29
**Branch:** culurien
**Purpose:** Document ETHOS violations BEFORE fixing them.
---
## Test Files
| File | Package | Type | Targets |
|------|---------|------|---------|
| `server/middleware/ethos_emoji_test.go` | `middleware_test` | Emoji | machine_binding.go |
| `server/handlers/ethos_emoji_test.go` | `handlers_test` | Emoji | agents.go, update handlers |
| `server/handlers/ethos_logging_test.go` | `handlers_test` | fmt.Printf | docker_reports.go, metrics.go |
| `server/handlers/ethos_setup_exempt_test.go` | `handlers_test` | Exemption | setup.go |
| `server/services/ethos_logging_test.go` | `services_test` | fmt.Printf | security_settings_service.go |
| `server/queries/ethos_logging_test.go` | `queries_test` | fmt.Printf | docker.go, metrics.go, updates.go |
| `agent/cmd/ethos_emoji_test.go` | `main` | Emoji | main.go log statements |
| `agent/migration/ethos_emoji_test.go` | `migration` | Emoji | executor.go |
| `agent/display/ethos_exempt_test.go` | `display` | Exemption | terminal.go |
## Exemptions (NOT to be touched in D-2 fix)
- `display/terminal.go` — intentional terminal UI emoji
- `handlers/setup.go` — CLI wizard output (fmt.Printf intentional)
- `cmd/agent/main.go` lines 294-322 — registration CLI output
- `cmd/agent/main.go` lines 691-697 — startup banner
## State-Change Summary
| Test | Type | Current | After Fix |
|------|------|---------|-----------|
| TestMachineBindingMiddlewareHasEmojiInLogs | Emoji | PASS | update |
| TestMachineBindingMiddlewareHasNoEmojiInLogs | Emoji | **FAIL** | PASS |
| TestAgentsHandlerHasEmojiInLogs | Emoji | PASS | update |
| TestAgentsHandlerHasNoEmojiInLogs | Emoji | **FAIL** | PASS |
| TestUpdateHandlersHaveEmojiInLogs | Emoji | PASS | update |
| TestUpdateHandlersHaveNoEmojiInLogs | Emoji | **FAIL** | PASS |
| TestHandlerFilesUseFmtPrintfForLogging | fmt.Printf | PASS | update |
| TestHandlerFilesUseStructuredLogging | fmt.Printf | **FAIL** | PASS |
| TestServicesUseFmtPrintfForLogging | fmt.Printf | PASS | update |
| TestServicesUseStructuredLogging | fmt.Printf | **FAIL** | PASS |
| TestQueriesUseFmtPrintfForLogging | fmt.Printf | PASS | update |
| TestQueriesUseStructuredLogging | fmt.Printf | **FAIL** | PASS |
| TestMainGoHasEmojiInLogStatements | Emoji | PASS | update |
| TestMainGoLogStatementsHaveNoEmoji | Emoji | **FAIL** | PASS |
| TestMigrationExecutorHasEmojiInOutput | Emoji | PASS | update |
| TestMigrationExecutorHasNoEmojiInOutput | Emoji | **FAIL** | PASS |
| TestTerminalDisplayIsExemptFromEthos | Exemption | PASS | PASS |
| TestSetupHandlerIsExemptFromEthos | Exemption | PASS | PASS |
**8 FAIL** (assert post-fix), **8 PASS** (document state), **2 ALWAYS-PASS** (exemptions).