Skip to content

Commit db05ad4

Browse files
authored
test: improve storage package coverage to 88.5% (#77)
Add tests for previously uncovered functions in the storage package: - json_test.go: Add TestJSONEngineGetManifestReader - protobuf_test.go: Add TestProtobufEngineGetManifestReader and TestProtobufEngineGetManifestReaderMissingFile - flatbuffers_test.go: Add comprehensive tests for: - GetManifestReader (success and missing file cases) - Convert (end-to-end JSON to FlatBuffers conversion) - pbEntityTypeToString and pbSideToString helper functions - pbManifestToStorageManifest conversion function Storage package coverage increased from 62.0% to 88.5%. Overall coverage increased from 36.9% to 43.8%.
1 parent a89b619 commit db05ad4

File tree

3 files changed

+333
-0
lines changed

3 files changed

+333
-0
lines changed

internal/storage/flatbuffers_test.go

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010

1111
fb "github.com/OCAP2/web/pkg/schemas/flatbuffers/generated"
12+
pb "github.com/OCAP2/web/pkg/schemas/protobuf"
1213
flatbuffers "github.com/google/flatbuffers/go"
1314
"github.com/stretchr/testify/assert"
1415
"github.com/stretchr/testify/require"
@@ -371,3 +372,291 @@ func TestFlatBuffersTypeConversions(t *testing.T) {
371372
assert.Equal(t, fb.SideGlobal, stringToFBSide("GLOBAL"))
372373
assert.Equal(t, fb.SideUnknown, stringToFBSide("invalid"))
373374
}
375+
376+
func TestFlatBuffersEngineGetManifestReader(t *testing.T) {
377+
dir := t.TempDir()
378+
missionDir := filepath.Join(dir, "test_mission")
379+
require.NoError(t, os.MkdirAll(missionDir, 0755))
380+
381+
// Create test manifest data
382+
testData := []byte("test flatbuffers manifest data")
383+
require.NoError(t, os.WriteFile(filepath.Join(missionDir, "manifest.fb"), testData, 0644))
384+
385+
engine := NewFlatBuffersEngine(dir)
386+
reader, err := engine.GetManifestReader(context.Background(), "test_mission")
387+
require.NoError(t, err)
388+
defer reader.Close()
389+
390+
data, err := io.ReadAll(reader)
391+
require.NoError(t, err)
392+
assert.Equal(t, testData, data)
393+
}
394+
395+
func TestFlatBuffersEngineGetManifestReaderMissingFile(t *testing.T) {
396+
dir := t.TempDir()
397+
engine := NewFlatBuffersEngine(dir)
398+
399+
_, err := engine.GetManifestReader(context.Background(), "nonexistent")
400+
require.Error(t, err)
401+
}
402+
403+
func TestFlatBuffersEngineConvert(t *testing.T) {
404+
dir := t.TempDir()
405+
inputPath := filepath.Join(dir, "test.json")
406+
outputPath := filepath.Join(dir, "output")
407+
408+
// Create test JSON data
409+
testJSON := `{
410+
"worldName": "altis",
411+
"missionName": "FlatBuffers Convert Test",
412+
"endFrame": 10,
413+
"captureDelay": 1,
414+
"entities": [
415+
{
416+
"id": 0,
417+
"type": "unit",
418+
"name": "Player1",
419+
"side": "WEST",
420+
"group": "Alpha",
421+
"role": "Rifleman",
422+
"startFrameNum": 0,
423+
"isPlayer": 1,
424+
"positions": [
425+
[[100, 200], 45, 1, 0, "Player1", 1],
426+
[[101, 201], 46, 1, 0, "Player1", 1],
427+
[[102, 202], 47, 1, 0, "Player1", 1],
428+
[[103, 203], 48, 1, 0, "Player1", 1],
429+
[[104, 204], 49, 1, 0, "Player1", 1],
430+
[[105, 205], 50, 1, 0, "Player1", 1],
431+
[[106, 206], 51, 1, 0, "Player1", 1],
432+
[[107, 207], 52, 1, 0, "Player1", 1],
433+
[[108, 208], 53, 1, 0, "Player1", 1],
434+
[[109, 209], 54, 0, 0, "Player1", 1]
435+
]
436+
},
437+
{
438+
"id": 1,
439+
"type": "vehicle",
440+
"name": "Truck",
441+
"class": "B_Truck_01",
442+
"startFrameNum": 0,
443+
"positions": [
444+
[[500, 600], 180, 1, []],
445+
[[501, 601], 181, 1, []],
446+
[[502, 602], 182, 1, []],
447+
[[503, 603], 183, 1, []],
448+
[[504, 604], 184, 1, []],
449+
[[505, 605], 185, 1, []],
450+
[[506, 606], 186, 1, []],
451+
[[507, 607], 187, 1, []],
452+
[[508, 608], 188, 1, []],
453+
[[509, 609], 189, 1, []]
454+
]
455+
}
456+
],
457+
"events": [
458+
[9, "killed", 0, 0, "arifle_MX"]
459+
],
460+
"Markers": [],
461+
"times": []
462+
}`
463+
464+
require.NoError(t, os.WriteFile(inputPath, []byte(testJSON), 0644))
465+
466+
engine := NewFlatBuffersEngine(dir)
467+
ctx := context.Background()
468+
469+
err := engine.Convert(ctx, inputPath, outputPath)
470+
require.NoError(t, err)
471+
472+
// Verify manifest was created
473+
manifestPath := filepath.Join(outputPath, "manifest.fb")
474+
_, err = os.Stat(manifestPath)
475+
require.NoError(t, err)
476+
477+
// Verify we can read the manifest
478+
newEngine := NewFlatBuffersEngine(filepath.Dir(outputPath))
479+
manifest, err := newEngine.GetManifest(ctx, "output")
480+
require.NoError(t, err)
481+
482+
assert.Equal(t, "altis", manifest.WorldName)
483+
assert.Equal(t, "FlatBuffers Convert Test", manifest.MissionName)
484+
assert.Equal(t, uint32(10), manifest.FrameCount)
485+
assert.Len(t, manifest.Entities, 2)
486+
487+
// Verify first entity
488+
assert.Equal(t, "unit", manifest.Entities[0].Type)
489+
assert.Equal(t, "Player1", manifest.Entities[0].Name)
490+
assert.Equal(t, "WEST", manifest.Entities[0].Side)
491+
assert.True(t, manifest.Entities[0].IsPlayer)
492+
493+
// Verify vehicle
494+
assert.Equal(t, "vehicle", manifest.Entities[1].Type)
495+
assert.Equal(t, "Truck", manifest.Entities[1].Name)
496+
assert.Equal(t, "B_Truck_01", manifest.Entities[1].VehicleClass)
497+
498+
// Verify chunks were created
499+
chunksDir := filepath.Join(outputPath, "chunks")
500+
_, err = os.Stat(filepath.Join(chunksDir, "0000.fb"))
501+
require.NoError(t, err)
502+
503+
// Read and verify chunk
504+
chunk, err := newEngine.GetChunk(ctx, "output", 0)
505+
require.NoError(t, err)
506+
assert.Greater(t, len(chunk.Frames), 0)
507+
}
508+
509+
func TestFlatBuffersEngineConvertMissingFile(t *testing.T) {
510+
dir := t.TempDir()
511+
engine := NewFlatBuffersEngine(dir)
512+
513+
err := engine.Convert(context.Background(), "nonexistent.json", "output")
514+
require.Error(t, err)
515+
assert.Contains(t, err.Error(), "load JSON")
516+
}
517+
518+
func TestPbEntityTypeToString(t *testing.T) {
519+
tests := []struct {
520+
input pb.EntityType
521+
expected string
522+
}{
523+
{pb.EntityType_ENTITY_TYPE_UNIT, "unit"},
524+
{pb.EntityType_ENTITY_TYPE_VEHICLE, "vehicle"},
525+
{pb.EntityType_ENTITY_TYPE_UNKNOWN, "unknown"},
526+
}
527+
528+
for _, tt := range tests {
529+
t.Run(tt.expected, func(t *testing.T) {
530+
result := pbEntityTypeToString(tt.input)
531+
assert.Equal(t, tt.expected, result)
532+
})
533+
}
534+
}
535+
536+
func TestPbSideToString(t *testing.T) {
537+
tests := []struct {
538+
input pb.Side
539+
expected string
540+
}{
541+
{pb.Side_SIDE_WEST, "WEST"},
542+
{pb.Side_SIDE_EAST, "EAST"},
543+
{pb.Side_SIDE_GUER, "GUER"},
544+
{pb.Side_SIDE_CIV, "CIV"},
545+
{pb.Side_SIDE_GLOBAL, "GLOBAL"},
546+
{pb.Side_SIDE_UNKNOWN, "UNKNOWN"},
547+
}
548+
549+
for _, tt := range tests {
550+
t.Run(tt.expected, func(t *testing.T) {
551+
result := pbSideToString(tt.input)
552+
assert.Equal(t, tt.expected, result)
553+
})
554+
}
555+
}
556+
557+
func TestPbManifestToStorageManifest(t *testing.T) {
558+
pbManifest := &pb.Manifest{
559+
Version: 2,
560+
WorldName: "stratis",
561+
MissionName: "Conversion Test",
562+
FrameCount: 500,
563+
ChunkSize: 100,
564+
CaptureDelayMs: 1000,
565+
ChunkCount: 5,
566+
Entities: []*pb.EntityDef{
567+
{
568+
Id: 1,
569+
Type: pb.EntityType_ENTITY_TYPE_UNIT,
570+
Name: "Squad Leader",
571+
Side: pb.Side_SIDE_GUER,
572+
GroupName: "Bravo",
573+
Role: "Leader",
574+
StartFrame: 0,
575+
EndFrame: 450,
576+
IsPlayer: true,
577+
VehicleClass: "",
578+
},
579+
{
580+
Id: 2,
581+
Type: pb.EntityType_ENTITY_TYPE_VEHICLE,
582+
Name: "Transport",
583+
Side: pb.Side_SIDE_WEST,
584+
GroupName: "",
585+
Role: "",
586+
StartFrame: 10,
587+
EndFrame: 400,
588+
IsPlayer: false,
589+
VehicleClass: "B_Heli_Transport",
590+
},
591+
},
592+
Events: []*pb.Event{
593+
{
594+
FrameNum: 100,
595+
Type: "hit",
596+
SourceId: 1,
597+
TargetId: 2,
598+
Message: "",
599+
Distance: 50.5,
600+
Weapon: "arifle_MX",
601+
},
602+
},
603+
}
604+
605+
manifest := pbManifestToStorageManifest(pbManifest)
606+
607+
// Verify basic fields
608+
assert.Equal(t, uint32(2), manifest.Version)
609+
assert.Equal(t, "stratis", manifest.WorldName)
610+
assert.Equal(t, "Conversion Test", manifest.MissionName)
611+
assert.Equal(t, uint32(500), manifest.FrameCount)
612+
assert.Equal(t, uint32(100), manifest.ChunkSize)
613+
assert.Equal(t, uint32(1000), manifest.CaptureDelayMs)
614+
assert.Equal(t, uint32(5), manifest.ChunkCount)
615+
616+
// Verify entities
617+
require.Len(t, manifest.Entities, 2)
618+
619+
ent0 := manifest.Entities[0]
620+
assert.Equal(t, uint32(1), ent0.ID)
621+
assert.Equal(t, "unit", ent0.Type)
622+
assert.Equal(t, "Squad Leader", ent0.Name)
623+
assert.Equal(t, "GUER", ent0.Side)
624+
assert.Equal(t, "Bravo", ent0.Group)
625+
assert.Equal(t, "Leader", ent0.Role)
626+
assert.Equal(t, uint32(0), ent0.StartFrame)
627+
assert.Equal(t, uint32(450), ent0.EndFrame)
628+
assert.True(t, ent0.IsPlayer)
629+
assert.Empty(t, ent0.VehicleClass)
630+
631+
ent1 := manifest.Entities[1]
632+
assert.Equal(t, uint32(2), ent1.ID)
633+
assert.Equal(t, "vehicle", ent1.Type)
634+
assert.Equal(t, "Transport", ent1.Name)
635+
assert.Equal(t, "WEST", ent1.Side)
636+
assert.Equal(t, "B_Heli_Transport", ent1.VehicleClass)
637+
assert.False(t, ent1.IsPlayer)
638+
639+
// Verify events
640+
require.Len(t, manifest.Events, 1)
641+
evt := manifest.Events[0]
642+
assert.Equal(t, uint32(100), evt.FrameNum)
643+
assert.Equal(t, "hit", evt.Type)
644+
assert.Equal(t, uint32(1), evt.SourceID)
645+
assert.Equal(t, uint32(2), evt.TargetID)
646+
assert.Equal(t, float32(50.5), evt.Distance)
647+
assert.Equal(t, "arifle_MX", evt.Weapon)
648+
}
649+
650+
func TestPbManifestToStorageManifestEmpty(t *testing.T) {
651+
pbManifest := &pb.Manifest{
652+
Version: 1,
653+
WorldName: "empty",
654+
MissionName: "Empty Test",
655+
}
656+
657+
manifest := pbManifestToStorageManifest(pbManifest)
658+
659+
assert.Equal(t, "empty", manifest.WorldName)
660+
assert.Empty(t, manifest.Entities)
661+
assert.Empty(t, manifest.Events)
662+
}

internal/storage/json_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ func TestJSONEngineEmptyEntities(t *testing.T) {
157157
assert.Empty(t, manifest.Entities)
158158
}
159159

160+
func TestJSONEngineGetManifestReader(t *testing.T) {
161+
engine := NewJSONEngine(t.TempDir())
162+
ctx := context.Background()
163+
164+
// JSON engine does not support raw manifest streaming
165+
reader, err := engine.GetManifestReader(ctx, "test")
166+
assert.Nil(t, reader)
167+
assert.Error(t, err)
168+
assert.Contains(t, err.Error(), "does not support")
169+
}
170+
160171
func TestHelperFunctions(t *testing.T) {
161172
m := map[string]interface{}{
162173
"stringVal": "hello",

internal/storage/protobuf_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,39 @@ func TestProtobufEngineGetChunkReaderMissingFile(t *testing.T) {
237237
require.Error(t, err)
238238
}
239239

240+
func TestProtobufEngineGetManifestReader(t *testing.T) {
241+
dir := t.TempDir()
242+
missionDir := filepath.Join(dir, "test_mission")
243+
require.NoError(t, os.MkdirAll(missionDir, 0755))
244+
245+
// Create test manifest
246+
pbManifest := &pb.Manifest{
247+
Version: 1,
248+
WorldName: "altis",
249+
MissionName: "Reader Test",
250+
}
251+
data, err := proto.Marshal(pbManifest)
252+
require.NoError(t, err)
253+
require.NoError(t, os.WriteFile(filepath.Join(missionDir, "manifest.pb"), data, 0644))
254+
255+
engine := NewProtobufEngine(dir)
256+
reader, err := engine.GetManifestReader(context.Background(), "test_mission")
257+
require.NoError(t, err)
258+
defer reader.Close()
259+
260+
readData, err := io.ReadAll(reader)
261+
require.NoError(t, err)
262+
assert.Equal(t, data, readData)
263+
}
264+
265+
func TestProtobufEngineGetManifestReaderMissingFile(t *testing.T) {
266+
dir := t.TempDir()
267+
engine := NewProtobufEngine(dir)
268+
269+
_, err := engine.GetManifestReader(context.Background(), "nonexistent")
270+
require.Error(t, err)
271+
}
272+
240273
func TestProtobufEngineConvert(t *testing.T) {
241274
dir := t.TempDir()
242275
engine := NewProtobufEngine(dir)

0 commit comments

Comments
 (0)