~kris/9p

llm9p

ref: 42c2e6958db4e870f21ce0b60b7522975cd8757f llm9p/internal/llmfs/compact_test.go -rw-r--r-- 4.1 KiB
42c2e695 — pdfinn fix: extract tool args and fix tool result history for OpenAI path 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package llmfs

import (
	"fmt"
	"io"
	"strings"
	"testing"
)

func TestCompactFile_Read_Initial(t *testing.T) {
	mock := NewMockBackend()
	compact := NewCompactFile(mock)

	// Initial read should return "ready"
	buf := make([]byte, 100)
	n, err := compact.Read(buf, 0)
	if err != nil {
		t.Fatalf("Read() error: %v", err)
	}

	content := string(buf[:n])
	expected := "ready\n"
	if content != expected {
		t.Errorf("Read() = %q, want %q", content, expected)
	}
}

func TestCompactFile_Write_TriggerCompaction(t *testing.T) {
	mock := NewMockBackend()
	mock.totalTokens = 160000
	mock.contextLimit = 200000

	compact := NewCompactFile(mock)

	// Write to trigger compaction
	n, err := compact.Write([]byte("1"), 0)
	if err != nil {
		t.Fatalf("Write() error: %v", err)
	}
	if n != 1 {
		t.Errorf("Write() n = %d, want 1", n)
	}

	// Verify compaction was called
	if !mock.compactCalled {
		t.Error("Compact() was not called on backend")
	}

	// Read should show "ok: tokens/limit"
	buf := make([]byte, 100)
	readN, _ := compact.Read(buf, 0)
	content := string(buf[:readN])

	if !strings.HasPrefix(content, "ok:") {
		t.Errorf("Read() after compaction = %q, want prefix 'ok:'", content)
	}
}

func TestCompactFile_Write_EmptyNoOp(t *testing.T) {
	mock := NewMockBackend()
	compact := NewCompactFile(mock)

	// Empty write should be no-op
	n, err := compact.Write([]byte(""), 0)
	if err != nil {
		t.Fatalf("Write() error: %v", err)
	}
	if n != 0 {
		t.Errorf("Write('') n = %d, want 0", n)
	}

	// Compaction should not be triggered
	if mock.compactCalled {
		t.Error("Compact() should not be called for empty write")
	}
}

func TestCompactFile_Write_WhitespaceNoOp(t *testing.T) {
	mock := NewMockBackend()
	compact := NewCompactFile(mock)

	// Whitespace-only write should be no-op
	_, err := compact.Write([]byte("   \n\t  "), 0)
	if err != nil {
		t.Fatalf("Write() error: %v", err)
	}

	// Compaction should not be triggered
	if mock.compactCalled {
		t.Error("Compact() should not be called for whitespace-only write")
	}
}

func TestCompactFile_Write_Error(t *testing.T) {
	mock := NewMockBackend()
	mock.compactError = fmt.Errorf("compaction failed")

	compact := NewCompactFile(mock)

	// Write should still succeed (error is stored for read)
	n, err := compact.Write([]byte("1"), 0)
	if err != nil {
		t.Fatalf("Write() error: %v", err)
	}
	if n != 1 {
		t.Errorf("Write() n = %d, want 1", n)
	}

	// Read should show error
	buf := make([]byte, 100)
	readN, _ := compact.Read(buf, 0)
	content := string(buf[:readN])

	if !strings.HasPrefix(content, "error:") {
		t.Errorf("Read() after error = %q, want prefix 'error:'", content)
	}
	if !strings.Contains(content, "compaction failed") {
		t.Errorf("Read() should contain error message, got %q", content)
	}
}

func TestCompactFile_Read_EOF(t *testing.T) {
	mock := NewMockBackend()
	compact := NewCompactFile(mock)

	// Read past end
	buf := make([]byte, 100)
	n, err := compact.Read(buf, 1000)
	if err != io.EOF {
		t.Errorf("Read(offset=1000) error = %v, want io.EOF", err)
	}
	if n != 0 {
		t.Errorf("Read(offset=1000) n = %d, want 0", n)
	}
}

func TestCompactFile_Stat(t *testing.T) {
	mock := NewMockBackend()
	compact := NewCompactFile(mock)

	stat := compact.Stat()

	// Initial content is "ready\n" = 6 chars
	expected := uint64(6)
	if stat.Length != expected {
		t.Errorf("Stat().Length = %d, want %d", stat.Length, expected)
	}
}

func TestCompactFile_MultipleCompactions(t *testing.T) {
	mock := NewMockBackend()
	mock.totalTokens = 180000
	mock.contextLimit = 200000

	compact := NewCompactFile(mock)

	// First compaction
	compact.Write([]byte("1"), 0)
	if !mock.compactCalled {
		t.Error("First compaction not called")
	}

	// Reset flag
	mock.compactCalled = false
	mock.totalTokens = 100000

	// Second compaction
	compact.Write([]byte("1"), 0)
	if !mock.compactCalled {
		t.Error("Second compaction not called")
	}

	// Check result reflects new token count
	buf := make([]byte, 100)
	readN, _ := compact.Read(buf, 0)
	content := string(buf[:readN])

	if !strings.Contains(content, "25000") { // 100000 / 4 from mock
		t.Errorf("Read() = %q, should contain reduced token count", content)
	}
}