tangled
alpha
login
or
join now
atscan.net
/
plcbundle-go
1
fork
atom
[DEPRECATED] Go implementation of plcbundle
1
fork
atom
overview
issues
pulls
pipelines
fix tests
tree.fail
4 months ago
9c0c9fca
f4582e9f
+68
-15
4 changed files
expand all
collapse all
unified
split
bundle
bundle_test.go
internal
storage
storage.go
storage_test.go
server
server_test.go
+13
-1
bundle/bundle_test.go
···
13
13
"tangled.org/atscan.net/plcbundle/internal/types"
14
14
)
15
15
16
16
+
var (
17
17
+
bundleInfo = &storage.BundleInfo{
18
18
+
BundleNumber: 1,
19
19
+
Origin: "test-origin",
20
20
+
ParentHash: "",
21
21
+
Cursor: "",
22
22
+
CreatedBy: "test",
23
23
+
Hostname: "test-host",
24
24
+
}
25
25
+
)
26
26
+
16
27
// TestIndex tests index operations
17
28
func TestIndex(t *testing.T) {
29
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
351
-
uncompHash, compHash, uncompSize, compSize, err := ops.SaveBundle(path, operations, nil)
363
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
143
+
if bundleInfo == nil {
144
144
+
return "", "", 0, 0, fmt.Errorf("bundleInfo cannot be nil")
145
145
+
}
146
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
270
+
// DEFENSIVE: Validate we got actual data
271
271
+
if len(decompressed) == 0 {
272
272
+
return nil, fmt.Errorf("decompression produced empty result")
273
273
+
}
274
274
+
266
275
// Parse JSONL
267
267
-
return op.ParseJSONL(decompressed)
276
276
+
operations, err := op.ParseJSONL(decompressed)
277
277
+
if err != nil {
278
278
+
return nil, fmt.Errorf("failed to parse JSONL: %w", err)
279
279
+
}
280
280
+
281
281
+
// DEFENSIVE: Additional validation
282
282
+
if len(operations) == 0 {
283
283
+
return nil, fmt.Errorf("bundle contains no valid operations")
284
284
+
}
285
285
+
286
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
29
+
var (
30
30
+
bundleInfo = &storage.BundleInfo{
31
31
+
BundleNumber: 1,
32
32
+
Origin: "test-origin",
33
33
+
ParentHash: "",
34
34
+
Cursor: "",
35
35
+
CreatedBy: "test",
36
36
+
Hostname: "test-host",
37
37
+
}
38
38
+
)
39
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
65
-
_, _, _, _, err := ops.SaveBundle(path, original, nil)
76
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
101
-
_, _, uncompSize, compSize, err := ops.SaveBundle(path, operations, nil)
112
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
122
-
contentHash, compHash, _, _, err := ops.SaveBundle(path, operations, nil)
133
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
253
-
_, _, _, _, err := ops.SaveBundle(path, operations, nil)
264
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
289
-
_, _, _, _, err := ops.SaveBundle(path, operations, nil)
300
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
324
-
_, compHash, _, _, err := ops.SaveBundle(path, operations, nil)
335
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
374
-
ops.SaveBundle(path, operations, nil)
385
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
392
-
ops.SaveBundle(path, operations, nil) // Create valid file first
403
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
413
-
ops.SaveBundle(path, operations, nil)
424
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
749
-
_, _, _, _, err := ops.SaveBundle(path, operations, nil)
760
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
775
-
ops.SaveBundle(path, operations, nil)
786
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
811
-
ops.SaveBundle(path, operations, nil)
822
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
37
+
var (
38
38
+
bundleInfo = &storage.BundleInfo{
39
39
+
BundleNumber: 1,
40
40
+
Origin: "test-origin",
41
41
+
ParentHash: "",
42
42
+
Cursor: "",
43
43
+
CreatedBy: "test",
44
44
+
Hostname: "test-host",
45
45
+
}
46
46
+
)
47
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
1009
-
contentHash, compHash, uncompSize, compSize, err := storageOps.SaveBundle(path, ops, nil)
1020
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
}