f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
268 lines
8.5 KiB
Go
268 lines
8.5 KiB
Go
package sync
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.kenn.io/agentsview/internal/parser"
|
|
"go.kenn.io/agentsview/internal/testjsonl"
|
|
)
|
|
|
|
const (
|
|
codexSyncBenchmarkUUID = "019eb791-cf7d-75c1-8439-9ed74c122b01"
|
|
codexSyncBenchmarkPriorTurns = 1500
|
|
codexSyncBenchmarkTailUser = "Tail request: measure the remaining source reads."
|
|
codexSyncBenchmarkTailAgent = "Tail response: the appended records were parsed."
|
|
)
|
|
|
|
var (
|
|
codexSyncBenchmarkOutcomeSink parser.IncrementalOutcome
|
|
codexSyncBenchmarkHashSink string
|
|
)
|
|
|
|
// BenchmarkCodexIncrementalSyncReads measures the source-reading pipeline that
|
|
// remains around a warm cursor append: Fingerprint hashes the full source and
|
|
// ComputeFileHashPrefix hashes through the proposed committed offset.
|
|
func BenchmarkCodexIncrementalSyncReads(b *testing.B) {
|
|
b.StopTimer()
|
|
ctx := context.Background()
|
|
root, path, prefix, tail, startOrdinal := writeCodexSyncBenchmarkTranscript(b)
|
|
cfg := parser.ProviderConfig{
|
|
Roots: []string{root},
|
|
Machine: "benchmark-host",
|
|
}
|
|
provider, ok := parser.NewProvider(parser.AgentCodex, cfg)
|
|
require.True(b, ok)
|
|
source, found, err := provider.FindSource(ctx, parser.FindSourceRequest{
|
|
FullSessionID: "codex:" + codexSyncBenchmarkUUID,
|
|
})
|
|
require.NoError(b, err)
|
|
require.True(b, found)
|
|
|
|
prefixFingerprint, err := provider.Fingerprint(ctx, source)
|
|
require.NoError(b, err)
|
|
assert.Equal(b, int64(len(prefix)), prefixFingerprint.Size)
|
|
full, err := provider.Parse(ctx, parser.ParseRequest{
|
|
Source: source,
|
|
Fingerprint: prefixFingerprint,
|
|
})
|
|
require.NoError(b, err)
|
|
require.Len(b, full.Results, 1)
|
|
assert.Len(b, full.Results[0].Result.Messages, startOrdinal)
|
|
|
|
// Keep the timed provider untouched after its prefix-only full parse. A
|
|
// separately seeded provider handles output validation after the append.
|
|
validationProvider, ok := parser.NewProvider(parser.AgentCodex, cfg)
|
|
require.True(b, ok)
|
|
_, err = validationProvider.Parse(ctx, parser.ParseRequest{
|
|
Source: source,
|
|
Fingerprint: prefixFingerprint,
|
|
})
|
|
require.NoError(b, err)
|
|
|
|
appendCodexSyncBenchmarkTail(b, path, tail)
|
|
req := parser.IncrementalRequest{
|
|
Source: source,
|
|
SessionID: "codex:" + codexSyncBenchmarkUUID,
|
|
Offset: int64(len(prefix)),
|
|
StartOrdinal: startOrdinal,
|
|
}
|
|
|
|
currentFingerprint, outcome, status, committedHash, err :=
|
|
runCodexIncrementalSyncReads(ctx, validationProvider, source, path, req)
|
|
require.NoError(b, err)
|
|
requireCodexSyncBenchmarkOutcome(
|
|
b, outcome, status, startOrdinal, int64(len(tail)),
|
|
)
|
|
require.Equal(b, int64(len(prefix)+len(tail)), currentFingerprint.Size)
|
|
require.Equal(b, currentFingerprint.Size, req.Offset+outcome.ConsumedBytes)
|
|
require.NotEmpty(b, currentFingerprint.Hash)
|
|
require.Len(b, committedHash, 64)
|
|
require.Equal(b, currentFingerprint.Hash, committedHash)
|
|
|
|
// Two full-length linear reads dominate this pipeline: the provider source
|
|
// fingerprint and the engine's committed-prefix hash. The warm tail parse is
|
|
// intentionally left in the same measurement between them.
|
|
b.SetBytes(2 * int64(len(prefix)+len(tail)))
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
b.StartTimer()
|
|
for b.Loop() {
|
|
fingerprint, outcome, status, hash, err := runCodexIncrementalSyncReads(
|
|
ctx, provider, source, path, req,
|
|
)
|
|
if err != nil || !codexSyncBenchmarkOutcomeValid(
|
|
outcome, status, startOrdinal, int64(len(tail)),
|
|
) || fingerprint.Size != int64(len(prefix)+len(tail)) ||
|
|
fingerprint.Hash == "" || len(hash) != 64 || fingerprint.Hash != hash {
|
|
b.StopTimer()
|
|
require.NoError(b, err)
|
|
requireCodexSyncBenchmarkOutcome(
|
|
b, outcome, status, startOrdinal, int64(len(tail)),
|
|
)
|
|
assert.Equal(b, int64(len(prefix)+len(tail)), fingerprint.Size)
|
|
require.NotEmpty(b, fingerprint.Hash)
|
|
assert.Len(b, hash, 64)
|
|
assert.Equal(b, fingerprint.Hash, hash)
|
|
b.StartTimer()
|
|
}
|
|
codexSyncBenchmarkOutcomeSink = outcome
|
|
codexSyncBenchmarkHashSink = hash
|
|
}
|
|
}
|
|
|
|
func runCodexIncrementalSyncReads(
|
|
ctx context.Context,
|
|
provider parser.Provider,
|
|
source parser.SourceRef,
|
|
path string,
|
|
req parser.IncrementalRequest,
|
|
) (
|
|
parser.SourceFingerprint,
|
|
parser.IncrementalOutcome,
|
|
parser.IncrementalStatus,
|
|
string,
|
|
error,
|
|
) {
|
|
// Fingerprint retains the existing full-source content hash.
|
|
fingerprint, err := provider.Fingerprint(ctx, source)
|
|
if err != nil {
|
|
return parser.SourceFingerprint{}, parser.IncrementalOutcome{},
|
|
parser.IncrementalUnsupported, "", err
|
|
}
|
|
req.Fingerprint = fingerprint
|
|
outcome, status, err := provider.ParseIncremental(ctx, req)
|
|
if err != nil {
|
|
return fingerprint, outcome, status, "", err
|
|
}
|
|
// This is the engine's second remaining linear read, through the offset
|
|
// that would be committed after the incremental database write succeeds.
|
|
committedHash, err := ComputeFileHashPrefix(
|
|
path, req.Offset+outcome.ConsumedBytes,
|
|
)
|
|
return fingerprint, outcome, status, committedHash, err
|
|
}
|
|
|
|
func writeCodexSyncBenchmarkTranscript(
|
|
b *testing.B,
|
|
) (root, path, prefix, tail string, startOrdinal int) {
|
|
b.Helper()
|
|
root = filepath.Join(b.TempDir(), "sessions")
|
|
path = filepath.Join(
|
|
root,
|
|
"2026",
|
|
"07",
|
|
"10",
|
|
"rollout-2026-07-10T07-12-15-"+codexSyncBenchmarkUUID+".jsonl",
|
|
)
|
|
require.NoError(b, os.MkdirAll(filepath.Dir(path), 0o755))
|
|
|
|
fixture := testjsonl.NewSessionBuilder().
|
|
AddCodexMeta(
|
|
"2026-07-10T07:00:00Z",
|
|
codexSyncBenchmarkUUID,
|
|
"/workspace/project-a",
|
|
"codex_cli_rs",
|
|
).
|
|
AddRaw(testjsonl.CodexTurnContextJSON(
|
|
"gpt-5.4", "2026-07-10T07:00:01Z",
|
|
)).
|
|
AddCodexMessage(
|
|
"2026-07-10T07:00:02Z",
|
|
"user",
|
|
"Initial request: inspect the project and make a careful change.",
|
|
).
|
|
AddCodexMessage(
|
|
"2026-07-10T07:00:03Z",
|
|
"assistant",
|
|
"Initial response: I will inspect the relevant code and tests.",
|
|
)
|
|
contextPayload := strings.Repeat(
|
|
"Retain concrete code, test, and validation context. ", 8,
|
|
)
|
|
for i := range codexSyncBenchmarkPriorTurns {
|
|
turn := strconv.Itoa(i)
|
|
fixture.AddCodexMessage(
|
|
"2026-07-10T07:01:00Z",
|
|
"user",
|
|
"Prior turn "+turn+" request: continue the implementation. "+
|
|
contextPayload,
|
|
)
|
|
fixture.AddCodexMessage(
|
|
"2026-07-10T07:01:01Z",
|
|
"assistant",
|
|
"Prior turn "+turn+" response: applied the next bounded change. "+
|
|
contextPayload,
|
|
)
|
|
}
|
|
prefix = fixture.String()
|
|
startOrdinal = 2 + 2*codexSyncBenchmarkPriorTurns
|
|
tail = testjsonl.JoinJSONL(
|
|
testjsonl.CodexMsgJSON(
|
|
"user", codexSyncBenchmarkTailUser, "2026-07-10T07:12:15Z",
|
|
),
|
|
testjsonl.CodexMsgJSON(
|
|
"assistant", codexSyncBenchmarkTailAgent, "2026-07-10T07:12:16Z",
|
|
),
|
|
)
|
|
require.NoError(b, os.WriteFile(path, []byte(prefix), 0o644))
|
|
return root, path, prefix, tail, startOrdinal
|
|
}
|
|
|
|
func appendCodexSyncBenchmarkTail(b *testing.B, path, tail string) {
|
|
b.Helper()
|
|
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0o644)
|
|
require.NoError(b, err)
|
|
_, err = f.WriteString(tail)
|
|
require.NoError(b, err)
|
|
require.NoError(b, f.Close())
|
|
}
|
|
|
|
func requireCodexSyncBenchmarkOutcome(
|
|
b *testing.B,
|
|
outcome parser.IncrementalOutcome,
|
|
status parser.IncrementalStatus,
|
|
startOrdinal int,
|
|
tailBytes int64,
|
|
) {
|
|
b.Helper()
|
|
require.Equal(b, parser.IncrementalApplied, status)
|
|
require.Len(b, outcome.Messages, 2)
|
|
assert.Equal(b, "codex:"+codexSyncBenchmarkUUID, outcome.SessionID)
|
|
assert.Equal(b, 2, outcome.MessageCount)
|
|
assert.Equal(b, 1, outcome.UserMessageCount)
|
|
assert.Equal(b, tailBytes, outcome.ConsumedBytes)
|
|
assert.Equal(b, parser.RoleUser, outcome.Messages[0].Role)
|
|
assert.Equal(b, codexSyncBenchmarkTailUser, outcome.Messages[0].Content)
|
|
assert.Equal(b, startOrdinal, outcome.Messages[0].Ordinal)
|
|
assert.Equal(b, parser.RoleAssistant, outcome.Messages[1].Role)
|
|
assert.Equal(b, codexSyncBenchmarkTailAgent, outcome.Messages[1].Content)
|
|
assert.Equal(b, startOrdinal+1, outcome.Messages[1].Ordinal)
|
|
}
|
|
|
|
func codexSyncBenchmarkOutcomeValid(
|
|
outcome parser.IncrementalOutcome,
|
|
status parser.IncrementalStatus,
|
|
startOrdinal int,
|
|
tailBytes int64,
|
|
) bool {
|
|
return status == parser.IncrementalApplied &&
|
|
outcome.SessionID == "codex:"+codexSyncBenchmarkUUID &&
|
|
outcome.MessageCount == 2 &&
|
|
outcome.UserMessageCount == 1 &&
|
|
outcome.ConsumedBytes == tailBytes &&
|
|
len(outcome.Messages) == 2 &&
|
|
outcome.Messages[0].Role == parser.RoleUser &&
|
|
outcome.Messages[0].Content == codexSyncBenchmarkTailUser &&
|
|
outcome.Messages[0].Ordinal == startOrdinal &&
|
|
outcome.Messages[1].Role == parser.RoleAssistant &&
|
|
outcome.Messages[1].Content == codexSyncBenchmarkTailAgent &&
|
|
outcome.Messages[1].Ordinal == startOrdinal+1
|
|
}
|