[DEPRECATED] Go implementation of plcbundle

fix tests

+68 -15
+13 -1
bundle/bundle_test.go
··· 13 13 "tangled.org/atscan.net/plcbundle/internal/types" 14 14 ) 15 15 16 + var ( 17 + bundleInfo = &storage.BundleInfo{ 18 + BundleNumber: 1, 19 + Origin: "test-origin", 20 + ParentHash: "", 21 + Cursor: "", 22 + CreatedBy: "test", 23 + Hostname: "test-host", 24 + } 25 + ) 26 + 16 27 // TestIndex tests index operations 17 28 func TestIndex(t *testing.T) { 29 + 18 30 t.Run("CreateNewIndex", func(t *testing.T) { 19 31 idx := bundleindex.NewIndex("test-origin") 20 32 if idx == nil { ··· 348 360 path := filepath.Join(tmpDir, "test_bundle.jsonl.zst") 349 361 350 362 // Save 351 - uncompHash, compHash, uncompSize, compSize, err := ops.SaveBundle(path, operations, nil) 363 + uncompHash, compHash, uncompSize, compSize, err := ops.SaveBundle(path, operations, bundleInfo) 352 364 if err != nil { 353 365 t.Fatalf("SaveBundle failed: %v", err) 354 366 }
+20 -1
internal/storage/storage.go
··· 140 140 141 141 // SaveBundle saves operations with metadata containing RELATIVE frame offsets 142 142 func (op *Operations) SaveBundle(path string, operations []plcclient.PLCOperation, bundleInfo *BundleInfo) (string, string, int64, int64, error) { 143 + if bundleInfo == nil { 144 + return "", "", 0, 0, fmt.Errorf("bundleInfo cannot be nil") 145 + } 146 + 143 147 // 1. Calculate content 144 148 jsonlData := op.SerializeJSONL(operations) 145 149 contentSize := int64(len(jsonlData)) ··· 263 267 return nil, fmt.Errorf("failed to decompress: %w", err) 264 268 } 265 269 270 + // DEFENSIVE: Validate we got actual data 271 + if len(decompressed) == 0 { 272 + return nil, fmt.Errorf("decompression produced empty result") 273 + } 274 + 266 275 // Parse JSONL 267 - return op.ParseJSONL(decompressed) 276 + operations, err := op.ParseJSONL(decompressed) 277 + if err != nil { 278 + return nil, fmt.Errorf("failed to parse JSONL: %w", err) 279 + } 280 + 281 + // DEFENSIVE: Additional validation 282 + if len(operations) == 0 { 283 + return nil, fmt.Errorf("bundle contains no valid operations") 284 + } 285 + 286 + return operations, nil 268 287 } 269 288 270 289 // ========================================
+23 -12
internal/storage/storage_test.go
··· 26 26 l.t.Log(v...) 27 27 } 28 28 29 + var ( 30 + bundleInfo = &storage.BundleInfo{ 31 + BundleNumber: 1, 32 + Origin: "test-origin", 33 + ParentHash: "", 34 + Cursor: "", 35 + CreatedBy: "test", 36 + Hostname: "test-host", 37 + } 38 + ) 39 + 29 40 // ==================================================================================== 30 41 // COMPRESSION TESTS 31 42 // ==================================================================================== ··· 62 73 path := filepath.Join(tmpDir, tt.name+".jsonl.zst") 63 74 64 75 // Save 65 - _, _, _, _, err := ops.SaveBundle(path, original, nil) 76 + _, _, _, _, err := ops.SaveBundle(path, original, bundleInfo) 66 77 if err != nil { 67 78 t.Fatalf("SaveBundle failed: %v", err) 68 79 } ··· 98 109 operations := makeTestOperations(10000) 99 110 path := filepath.Join(tmpDir, "compression_test.jsonl.zst") 100 111 101 - _, _, uncompSize, compSize, err := ops.SaveBundle(path, operations, nil) 112 + _, _, uncompSize, compSize, err := ops.SaveBundle(path, operations, bundleInfo) 102 113 if err != nil { 103 114 t.Fatalf("SaveBundle failed: %v", err) 104 115 } ··· 119 130 operations := makeTestOperations(100) 120 131 path := filepath.Join(tmpDir, "integrity_test.jsonl.zst") 121 132 122 - contentHash, compHash, _, _, err := ops.SaveBundle(path, operations, nil) 133 + contentHash, compHash, _, _, err := ops.SaveBundle(path, operations, bundleInfo) 123 134 if err != nil { 124 135 t.Fatalf("SaveBundle failed: %v", err) 125 136 } ··· 250 261 // Create test bundle 251 262 operations := makeTestOperations(10000) 252 263 path := filepath.Join(tmpDir, "parallel_test.jsonl.zst") 253 - _, _, _, _, err := ops.SaveBundle(path, operations, nil) 264 + _, _, _, _, err := ops.SaveBundle(path, operations, bundleInfo) 254 265 if err != nil { 255 266 t.Fatalf("SaveBundle failed: %v", err) 256 267 } ··· 286 297 // Critical test - this is heavily used by DID lookups 287 298 operations := makeTestOperations(10000) 288 299 path := filepath.Join(tmpDir, "position_test.jsonl.zst") 289 - _, _, _, _, err := ops.SaveBundle(path, operations, nil) 300 + _, _, _, _, err := ops.SaveBundle(path, operations, bundleInfo) 290 301 if err != nil { 291 302 t.Fatalf("SaveBundle failed: %v", err) 292 303 } ··· 321 332 t.Run("ConcurrentHashVerification", func(t *testing.T) { 322 333 operations := makeTestOperations(1000) 323 334 path := filepath.Join(tmpDir, "verify_test.jsonl.zst") 324 - _, compHash, _, _, err := ops.SaveBundle(path, operations, nil) 335 + _, compHash, _, _, err := ops.SaveBundle(path, operations, bundleInfo) 325 336 if err != nil { 326 337 t.Fatalf("SaveBundle failed: %v", err) 327 338 } ··· 371 382 t.Run("TruncatedFile", func(t *testing.T) { 372 383 operations := makeTestOperations(100) 373 384 path := filepath.Join(tmpDir, "truncated.jsonl.zst") 374 - ops.SaveBundle(path, operations, nil) 385 + ops.SaveBundle(path, operations, bundleInfo) 375 386 376 387 // Read and truncate 377 388 data, _ := os.ReadFile(path) ··· 389 400 390 401 // Manually compress invalid data 391 402 operations := makeTestOperations(10) 392 - ops.SaveBundle(path, operations, nil) // Create valid file first 403 + ops.SaveBundle(path, operations, bundleInfo) // Create valid file first 393 404 394 405 // Now corrupt it with invalid JSON 395 406 // This is hard to test properly since SaveBundle enforces valid data ··· 410 421 t.Run("InvalidPosition", func(t *testing.T) { 411 422 operations := makeTestOperations(100) 412 423 path := filepath.Join(tmpDir, "position_test.jsonl.zst") 413 - ops.SaveBundle(path, operations, nil) 424 + ops.SaveBundle(path, operations, bundleInfo) 414 425 415 426 // Negative position 416 427 _, err := ops.LoadOperationAtPosition(path, -1) ··· 746 757 t.Run("StreamRaw", func(t *testing.T) { 747 758 operations := makeTestOperations(100) 748 759 path := filepath.Join(tmpDir, "stream_raw.jsonl.zst") 749 - _, _, _, _, err := ops.SaveBundle(path, operations, nil) 760 + _, _, _, _, err := ops.SaveBundle(path, operations, bundleInfo) 750 761 if err != nil { 751 762 t.Fatalf("SaveBundle failed: %v", err) 752 763 } ··· 772 783 t.Run("StreamDecompressed", func(t *testing.T) { 773 784 operations := makeTestOperations(100) 774 785 path := filepath.Join(tmpDir, "stream_decomp.jsonl.zst") 775 - ops.SaveBundle(path, operations, nil) 786 + ops.SaveBundle(path, operations, bundleInfo) 776 787 777 788 reader, err := ops.StreamDecompressed(path) 778 789 if err != nil { ··· 808 819 b.Run("SaveBundle", func(b *testing.B) { 809 820 for i := 0; i < b.N; i++ { 810 821 path := filepath.Join(tmpDir, fmt.Sprintf("bench_%d.jsonl.zst", i)) 811 - ops.SaveBundle(path, operations, nil) 822 + ops.SaveBundle(path, operations, bundleInfo) 812 823 } 813 824 }) 814 825
+12 -1
server/server_test.go
··· 34 34 l.t.Log(v...) 35 35 } 36 36 37 + var ( 38 + bundleInfo = &storage.BundleInfo{ 39 + BundleNumber: 1, 40 + Origin: "test-origin", 41 + ParentHash: "", 42 + Cursor: "", 43 + CreatedBy: "test", 44 + Hostname: "test-host", 45 + } 46 + ) 47 + 37 48 // ==================================================================================== 38 49 // HTTP ENDPOINT TESTS 39 50 // ==================================================================================== ··· 1006 1017 path := filepath.Join(tmpDir, fmt.Sprintf("%06d.jsonl.zst", i)) 1007 1018 ops := makeMinimalTestOperations(10000, i*10000) // Unique ops per bundle 1008 1019 1009 - contentHash, compHash, uncompSize, compSize, err := storageOps.SaveBundle(path, ops, nil) 1020 + contentHash, compHash, uncompSize, compSize, err := storageOps.SaveBundle(path, ops, bundleInfo) 1010 1021 if err != nil { 1011 1022 t.Fatalf("failed to save test bundle %d: %v", i, err) 1012 1023 }