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
8 changes: 7 additions & 1 deletion pkg/telemetry/streamer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ type streamingClient struct {

// referenceTime is the reference point provided in the ACMI data.
referenceTime time.Time
// referenceTimeSet tracks whether a ReferenceTime property has been received. It must not be
// replaced by referenceTime.IsZero() because 0001-01-01T00:00:00Z is a valid reference time
// used by some ACMI recorders (e.g. DCS2ACMI) and is also Go's zero time.Time value.
referenceTimeSet bool
// referencePoint is the reference point provided in the ACMI data.
referencePoint orb.Point
// cursorTime is the current frame time, computed by adding the current time frame to the reference time.
Expand Down Expand Up @@ -333,7 +337,7 @@ func (c *streamingClient) handleTimeFrame(line string) error {
if err != nil {
return fmt.Errorf("error parsing time frame: %w", err)
}
if c.referenceTime.IsZero() {
if !c.referenceTimeSet {
return errors.New("time frame received before reference time")
}
c.cursorTime = c.referenceTime.Add(offset)
Expand All @@ -353,6 +357,7 @@ func (c *streamingClient) updateGlobalObject(update *objects.Update) error {
return fmt.Errorf("error parsing reference time: %w", err)
}
c.referenceTime = referenceTime
c.referenceTimeSet = true
if c.cursorTime.IsZero() {
c.cursorTime = c.referenceTime
}
Expand Down Expand Up @@ -450,6 +455,7 @@ func (c *streamingClient) reset() {
defer c.lock.Unlock()

c.referenceTime = time.Time{}
c.referenceTimeSet = false
c.referencePoint = orb.Point{}
c.cursorTime = time.Time{}
c.state = map[uint64]*objects.Object{}
Expand Down
31 changes: 31 additions & 0 deletions pkg/telemetry/streamer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,41 @@ import (
"testing"
"time"

"github.com/dharmab/goacmi/v2/parsing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// TestHandleLineAcceptsZeroReferenceTime verifies that a zero-valued
// ReferenceTime (0001-01-01T00:00:00Z) is accepted and does not cause
// subsequent time frames to be rejected. This is regression test for
// a case that sometimes happens on Lima Kilo.
func TestHandleLineAcceptsZeroReferenceTime(t *testing.T) {
t.Parallel()

const timeFrame = "#62754967308.46" // Observed value from eu.limakilo.net sometimes
lines := []string{
"FileType=text/acmi/tacview",
"FileVersion=2.2",
"0,ReferenceTime=0001-01-01T00:00:00Z",
"0,ReferenceLongitude=30",
"0,ReferenceLatitude=30",
timeFrame,
}

client := newStreamingClient(time.Second)
reader := bufio.NewReader(strings.NewReader(strings.Join(lines, "\n") + "\n"))
for range lines {
line, err := readACMILine(reader)
require.NoError(t, err)
require.NoError(t, client.handleLine(line))
}

offset, err := parsing.ParseTimeFrame(timeFrame)
require.NoError(t, err)
assert.Equal(t, time.Time{}.Add(offset), client.Time())
}

func TestReadACMILineContinuationPreservesNextRecord(t *testing.T) {
t.Parallel()

Expand Down
Loading