Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 46 additions & 7 deletions commands/metrics/cbor_gen.maps.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

129 changes: 0 additions & 129 deletions commands/metrics/codec.go

This file was deleted.

82 changes: 14 additions & 68 deletions commands/metrics/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"testing"

"github.com/fil-forge/libforge/commands/metrics"
"github.com/fil-forge/ucantone/did"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -46,97 +45,44 @@ func TestSampleArgumentsRoundTrip(t *testing.T) {
require.Equal(t, `{"from":1700000000,"to":1700003600,"window":3600}`, roundTrip(t, in))
}

// provider is a fixed DID so the expected DAG-JSON below is stable.
var provider = did.MustParse("did:web:provider.example")

func TestSampleOKRoundTrip(t *testing.T) {
in := &metrics.SampleOK{
From: 1700000000,
To: 1700007200,
Window: 3600,
Samples: metrics.SampleSet{Entries: map[did.DID][]metrics.SampleItem{
provider: {
{Timestamp: 1700003600, BytesStored: 1024, BytesIngested: 1024},
{Timestamp: 1700007200, BytesStored: 512, BytesIngested: 0},
},
}},
Samples: []metrics.SampleItem{
{Timestamp: 1700003600, BytesStored: 1024, BytesIngested: 1024},
{Timestamp: 1700007200, BytesStored: 512, BytesIngested: 0},
},
}
// SampleItem is tuple encoded: [timestamp, bytesStored, bytesIngested].
require.Equal(t,
`{"from":1700000000,"samples":{"did:web:provider.example":[`+
`{"from":1700000000,"samples":[`+
`[1700003600,1024,1024],`+
`[1700007200,512,0]`+
`]},"to":1700007200,"window":3600}`,
roundTrip(t, in))
}

// A space provisioned with several providers carries a series each, on one
// shared bucket grid. The keys sort, so the encoding is deterministic.
func TestSampleOKSeveralProvidersRoundTrip(t *testing.T) {
a := did.MustParse("did:web:a.example")
b := did.MustParse("did:web:b.example")
in := &metrics.SampleOK{
From: 1700000000,
To: 1700003600,
Window: 3600,
Samples: metrics.SampleSet{Entries: map[did.DID][]metrics.SampleItem{
b: {{Timestamp: 1700003600, BytesStored: 2, BytesIngested: 2}},
a: {{Timestamp: 1700003600, BytesStored: 1, BytesIngested: 1}},
}},
}
require.Equal(t,
`{"from":1700000000,"samples":{`+
`"did:web:a.example":[[1700003600,1,1]],`+
`"did:web:b.example":[[1700003600,2,2]]`+
`},"to":1700003600,"window":3600}`,
`],"to":1700007200,"window":3600}`,
roundTrip(t, in))
}

// A range entirely in the future carries no samples. An absent set and an
// empty one are the same thing on the wire, so these assert the encoding and
// A range entirely in the future carries no samples. An absent series and an
// empty one are the same thing on the wire, so this asserts the encoding and
// the decoded content rather than round-trip identity.
func TestSampleOKEmptySetRoundTrip(t *testing.T) {
in := &metrics.SampleOK{From: 1700000000, To: 1700000000, Window: 3600}

var jb bytes.Buffer
require.NoError(t, in.MarshalDagJSON(&jb))
require.Equal(t, `{"from":1700000000,"samples":{},"to":1700000000,"window":3600}`, jb.String())

var fromJSON metrics.SampleOK
require.NoError(t, fromJSON.UnmarshalDagJSON(bytes.NewReader(jb.Bytes())))
require.Empty(t, fromJSON.Samples.Entries)

var cb bytes.Buffer
require.NoError(t, in.MarshalCBOR(&cb))
var fromCBOR metrics.SampleOK
require.NoError(t, fromCBOR.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Empty(t, fromCBOR.Samples.Entries)
}

// A provider present with nothing to report keeps its key and an empty series.
func TestSampleOKEmptySeriesRoundTrip(t *testing.T) {
in := &metrics.SampleOK{
From: 1700000000, To: 1700000000, Window: 3600,
Samples: metrics.SampleSet{Entries: map[did.DID][]metrics.SampleItem{provider: {}}},
}
in := &metrics.SampleOK{From: 1700000000, To: 1700000000, Window: 3600}

var jb bytes.Buffer
require.NoError(t, in.MarshalDagJSON(&jb))
require.Equal(t,
`{"from":1700000000,"samples":{"did:web:provider.example":[]},"to":1700000000,"window":3600}`,
jb.String())
require.Equal(t, `{"from":1700000000,"samples":[],"to":1700000000,"window":3600}`, jb.String())

var fromJSON metrics.SampleOK
require.NoError(t, fromJSON.UnmarshalDagJSON(bytes.NewReader(jb.Bytes())))
require.Len(t, fromJSON.Samples.Entries, 1)
require.Empty(t, fromJSON.Samples.Entries[provider])
require.Empty(t, fromJSON.Samples)

var cb bytes.Buffer
require.NoError(t, in.MarshalCBOR(&cb))
var fromCBOR metrics.SampleOK
require.NoError(t, fromCBOR.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Len(t, fromCBOR.Samples.Entries, 1)
require.Empty(t, fromCBOR.Samples.Entries[provider])
require.Empty(t, fromCBOR.Samples)
}

// 768 samples is a 32 day range at hourly granularity, the largest series
Expand All @@ -156,14 +102,14 @@ func TestSampleOKLargeSeriesRoundTrip(t *testing.T) {
BytesIngested: 1 << 20,
})
}
in.Samples = metrics.SampleSet{Entries: map[did.DID][]metrics.SampleItem{provider: samples}}
in.Samples = samples
in.To = in.From + count*hour

var cb bytes.Buffer
require.NoError(t, in.MarshalCBOR(&cb))
var out metrics.SampleOK
require.NoError(t, out.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Len(t, out.Samples.Entries[provider], count)
require.Len(t, out.Samples, count)
require.Equal(t, *in, out)
t.Logf("%d samples encode to %d bytes of CBOR", count, cb.Len())
}
2 changes: 0 additions & 2 deletions commands/metrics/gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ func tag(path string) {
}

func main() {
// SampleSet has a hand-written codec (see codec.go) because cbor-gen /
// dag-json-gen do not support DID-keyed maps.
mapModels := []any{
metrics.SampleArguments{},
metrics.SampleOK{},
Expand Down
Loading
Loading