| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package exporter
- import (
- "fmt"
- "sync/atomic"
- "testing"
- "time"
- "github.com/opencost/opencost/core/pkg/opencost"
- "github.com/opencost/opencost/core/pkg/util"
- )
- type TObject struct {
- Window opencost.Window
- Message string
- }
- func (tobj *TObject) MarshalBinary() ([]byte, error) {
- ctx := &opencost.EncodingContext{
- Buffer: util.NewBuffer(),
- Table: nil,
- }
- err := tobj.Window.MarshalBinaryWithContext(ctx)
- if err != nil {
- return nil, err
- }
- ctx.Buffer.WriteString(tobj.Message)
- return ctx.Buffer.Bytes(), nil
- }
- func (tobj *TObject) UnmarshalBinary(data []byte) error {
- ctx := &opencost.DecodingContext{
- Buffer: util.NewBufferFromBytes(data),
- Table: nil,
- }
- err := tobj.Window.UnmarshalBinaryWithContext(ctx)
- if err != nil {
- return err
- }
- tobj.Message = ctx.Buffer.ReadString()
- return nil
- }
- func (tobj *TObject) IsEmpty() bool {
- return tobj.Message == ""
- }
- type TObjectSource struct {
- count atomic.Uint64
- }
- func (s *TObjectSource) CanCompute(start, end time.Time) bool {
- return true
- }
- func (s *TObjectSource) Compute(start, end time.Time, resolution time.Duration) (*TObject, error) {
- c := s.count.Add(1)
- return &TObject{
- Window: opencost.NewClosedWindow(start, end),
- Message: fmt.Sprintf("Message #%d", c),
- }, nil
- }
- func (s *TObjectSource) Name() string {
- return "TObjectSource"
- }
- type TObjectComputeExporter struct {
- encoder Encoder[TObject]
- data map[string][]byte
- }
- func NewTObjectComputeExporter() *TObjectComputeExporter {
- return &TObjectComputeExporter{
- encoder: NewBingenEncoder[TObject](),
- data: make(map[string][]byte),
- }
- }
- func (t *TObjectComputeExporter) Export(window opencost.Window, data *TObject) error {
- d, err := data.MarshalBinary()
- if err != nil {
- return err
- }
- t.data[window.String()] = d
- return nil
- }
- func TestTObjectSymmetry(t *testing.T) {
- now := time.Now().UTC().Truncate(time.Hour)
- future := now.Add(time.Hour)
- tobj := &TObject{
- Window: opencost.NewClosedWindow(now, future),
- Message: "Testing 1 2 3",
- }
- data, err := tobj.MarshalBinary()
- if err != nil {
- t.Fatalf("Failed to marshal: %v", err)
- }
- tobj2 := &TObject{}
- err = tobj2.UnmarshalBinary(data)
- if err != nil {
- t.Fatalf("Failed to unmarshal: %v", err)
- }
- if tobj2.Message != tobj.Message && tobj2.Message == "Testing 1 2 3" {
- t.Fatalf("Message mismatch: %s != %s", tobj2.Message, tobj.Message)
- }
- if !tobj2.Window.Start().Equal(*tobj.Window.Start()) || !tobj2.Window.Start().Equal(now) {
- t.Fatalf("Start time mismatch: %s != %s", tobj2.Window.Start(), tobj.Window.Start())
- }
- if !tobj2.Window.End().Equal(*tobj.Window.End()) || !tobj2.Window.End().Equal(future) {
- t.Fatalf("End time mismatch: %s != %s", tobj2.Window.End(), tobj.Window.End())
- }
- }
|