This repository has been archived on 2026-03-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
labmcp/internal/database/benchmark_test.go
Torjus Håkestad ea11dd5e14 fix: add nolint:errcheck comments for intentionally unchecked errors
Add //nolint:errcheck comments to intentionally unchecked error returns:

- defer X.Close() calls: errors from closing read-only resources, rows
  after iteration, files, response bodies, and gzip readers are not
  actionable and don't affect correctness

- defer tx.Rollback(): standard Go pattern where rollback after
  successful commit returns an error, which is expected behavior

- defer stmt.Close(): statements are closed with their transactions

- Cleanup operations: DeleteRevision on failure and os.RemoveAll for
  temp directories are best-effort cleanup

- HTTP response encoding: if JSON encoding fails at response time,
  there's nothing useful we can do

- Test/benchmark code: unchecked errors in test setup/cleanup where
  failures will surface through test assertions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:51:20 +01:00

247 lines
6.2 KiB
Go

package database
import (
"context"
"fmt"
"testing"
"time"
)
func BenchmarkCreateOptions(b *testing.B) {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
defer store.Close() //nolint:errcheck // benchmark cleanup
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
rev := &Revision{GitHash: "bench123", ChannelName: "bench"}
if err := store.CreateRevision(ctx, rev); err != nil {
b.Fatalf("Failed to create revision: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
opt := &Option{
RevisionID: rev.ID,
Name: fmt.Sprintf("services.test%d.enable", i),
ParentPath: fmt.Sprintf("services.test%d", i),
Type: "boolean",
DefaultValue: "false",
Description: "Test option",
}
if err := store.CreateOption(ctx, opt); err != nil {
b.Fatalf("Failed to create option: %v", err)
}
}
}
func BenchmarkCreateOptionsBatch(b *testing.B) {
benchmarkBatch(b, 100)
}
func BenchmarkCreateOptionsBatch1000(b *testing.B) {
benchmarkBatch(b, 1000)
}
func benchmarkBatch(b *testing.B, batchSize int) {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
defer store.Close() //nolint:errcheck // benchmark cleanup
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
rev := &Revision{GitHash: "batchbench", ChannelName: "bench"}
if err := store.CreateRevision(ctx, rev); err != nil {
b.Fatalf("Failed to create revision: %v", err)
}
opts := make([]*Option, batchSize)
for i := 0; i < batchSize; i++ {
opts[i] = &Option{
RevisionID: rev.ID,
Name: fmt.Sprintf("services.batch%d.enable", i),
ParentPath: fmt.Sprintf("services.batch%d", i),
Type: "boolean",
DefaultValue: "false",
Description: "Batch test option",
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
// Reset IDs for next iteration
for _, opt := range opts {
opt.ID = 0
}
if err := store.CreateOptionsBatch(ctx, opts); err != nil {
b.Fatalf("Failed to create batch: %v", err)
}
// Clean up for next iteration
_ = store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // benchmark cleanup
rev = &Revision{GitHash: fmt.Sprintf("batchbench%d", i), ChannelName: "bench"}
_ = store.CreateRevision(ctx, rev) //nolint:errcheck // benchmark setup
for _, opt := range opts {
opt.RevisionID = rev.ID
}
}
}
func BenchmarkSearchOptions(b *testing.B) {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
defer store.Close() //nolint:errcheck // benchmark cleanup
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
rev := &Revision{GitHash: "searchbench", ChannelName: "bench"}
if err := store.CreateRevision(ctx, rev); err != nil {
b.Fatalf("Failed to create revision: %v", err)
}
// Create 1000 options to search through
opts := make([]*Option, 1000)
for i := 0; i < 1000; i++ {
opts[i] = &Option{
RevisionID: rev.ID,
Name: fmt.Sprintf("services.service%d.enable", i),
ParentPath: fmt.Sprintf("services.service%d", i),
Type: "boolean",
DefaultValue: "false",
Description: fmt.Sprintf("Enable service %d for testing purposes", i),
}
}
if err := store.CreateOptionsBatch(ctx, opts); err != nil {
b.Fatalf("Failed to create options: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := store.SearchOptions(ctx, rev.ID, "enable service", SearchFilters{Limit: 50})
if err != nil {
b.Fatalf("Search failed: %v", err)
}
}
}
func BenchmarkGetChildren(b *testing.B) {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
defer store.Close() //nolint:errcheck // benchmark cleanup
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
rev := &Revision{GitHash: "childrenbench", ChannelName: "bench"}
if err := store.CreateRevision(ctx, rev); err != nil {
b.Fatalf("Failed to create revision: %v", err)
}
// Create parent and 100 children
opts := make([]*Option, 101)
opts[0] = &Option{
RevisionID: rev.ID,
Name: "services",
ParentPath: "",
Type: "attrsOf",
}
for i := 1; i <= 100; i++ {
opts[i] = &Option{
RevisionID: rev.ID,
Name: fmt.Sprintf("services.service%d", i),
ParentPath: "services",
Type: "submodule",
}
}
if err := store.CreateOptionsBatch(ctx, opts); err != nil {
b.Fatalf("Failed to create options: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := store.GetChildren(ctx, rev.ID, "services")
if err != nil {
b.Fatalf("GetChildren failed: %v", err)
}
}
}
func BenchmarkSchemaInitialize(b *testing.B) {
for i := 0; i < b.N; i++ {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
store.Close() //nolint:errcheck // benchmark cleanup
}
}
// BenchmarkRevisionCRUD benchmarks the full CRUD cycle for revisions.
func BenchmarkRevisionCRUD(b *testing.B) {
store, err := NewSQLiteStore(":memory:")
if err != nil {
b.Fatalf("Failed to create store: %v", err)
}
defer store.Close() //nolint:errcheck // benchmark cleanup
ctx := context.Background()
if err := store.Initialize(ctx); err != nil {
b.Fatalf("Failed to initialize: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
rev := &Revision{
GitHash: fmt.Sprintf("crud%d", i),
ChannelName: "test",
CommitDate: time.Now(),
}
// Create
if err := store.CreateRevision(ctx, rev); err != nil {
b.Fatalf("Create failed: %v", err)
}
// Read
_, err := store.GetRevision(ctx, rev.GitHash)
if err != nil {
b.Fatalf("Get failed: %v", err)
}
// Update
if err := store.UpdateRevisionOptionCount(ctx, rev.ID, 100); err != nil {
b.Fatalf("Update failed: %v", err)
}
// Delete
if err := store.DeleteRevision(ctx, rev.ID); err != nil {
b.Fatalf("Delete failed: %v", err)
}
}
}