From 90e8c3f101fdbc13500b8bad8a581e956c4d0d0b Mon Sep 17 00:00:00 2001 From: saji Date: Thu, 7 Mar 2024 23:50:13 -0600 Subject: [PATCH] more tests! added BusEvent.Equals --- broker_test.go | 8 ++------ db.go | 4 ++-- db_test.go | 16 ++++++++++++++++ http_test.go | 41 ++++++++++++++++++++++++++++++++++++++++- skylab/skylab.go | 26 +++++++++++++++++++++++--- 5 files changed, 83 insertions(+), 12 deletions(-) diff --git a/broker_test.go b/broker_test.go index 2df8b66..ff2bf35 100644 --- a/broker_test.go +++ b/broker_test.go @@ -3,7 +3,6 @@ package gotelem import ( "log/slog" "os" - "reflect" "sync" "testing" "time" @@ -45,11 +44,8 @@ func TestBroker(t *testing.T) { var recvEvent skylab.BusEvent select { case recvEvent = <-sub: - if !reflect.DeepEqual(recvEvent.Data, testEvent.Data) { - t.Fatalf("mismatched data, want %v got %v", testEvent.Data, recvEvent.Data) - } - if !testEvent.Timestamp.Equal(recvEvent.Timestamp) { - t.Fatalf("mismatched timestamp, want %v got %v", testEvent.Timestamp, recvEvent.Timestamp) + if !testEvent.Equals(&recvEvent) { + t.Fatalf("events not equal, want %v got %v", testEvent, recvEvent) } case <-time.After(1 * time.Second): t.Fatalf("timeout waiting for packet") diff --git a/db.go b/db.go index 3329d10..f774f43 100644 --- a/db.go +++ b/db.go @@ -195,7 +195,7 @@ func (tdb *TelemDb) GetPackets(ctx context.Context, filter BusEventFilter, lim * sb.WriteString(strings.Join(whereFrags, " AND ")) } - sb.WriteString(" ORDER BY ts DESC") + sb.WriteString(" ORDER BY ts ASC") // Augment our data further if there's i.e a limit modifier. // TODO: factor this out maybe? @@ -278,7 +278,7 @@ func (tdb *TelemDb) GetValues(ctx context.Context, filter BusEventFilter, // join qstrings with AND sb.WriteString(strings.Join(whereFrags, " AND ")) - sb.WriteString(" ORDER BY ts DESC") + sb.WriteString(" ORDER BY ts ASC") if lim != nil { lim.ModifyStatement(&sb) diff --git a/db_test.go b/db_test.go index 0e5f820..d430df1 100644 --- a/db_test.go +++ b/db_test.go @@ -89,6 +89,22 @@ func SeedMockDatabase(tdb *TelemDb) { } } +func GetSeedEvents() []skylab.BusEvent { + evs := make([]skylab.BusEvent, 0) + scanner := bufio.NewScanner(strings.NewReader(exampleData)) + + for scanner.Scan() { + str := scanner.Text() + + bev, err := logparsers.ParsersMap["telem"](str) + if err != nil { + panic(err) + } + evs = append(evs, bev) + } + return evs +} + func TestTelemDb(t *testing.T) { t.Run("test opening database", func(t *testing.T) { diff --git a/http_test.go b/http_test.go index ee96512..12f2d77 100644 --- a/http_test.go +++ b/http_test.go @@ -1,6 +1,7 @@ package gotelem import ( + "encoding/json" "fmt" "net/http" "net/http/httptest" @@ -8,6 +9,8 @@ import ( "reflect" "testing" "time" + + "github.com/kschamplin/gotelem/skylab" ) func Test_extractBusEventFilter(t *testing.T) { @@ -146,17 +149,34 @@ func Test_extractLimitModifier(t *testing.T) { func Test_ApiV1GetPackets(t *testing.T) { tdb := MakeMockDatabase(t.Name()) SeedMockDatabase(tdb) + evs := GetSeedEvents() handler := apiV1GetPackets(tdb) tests := []struct{ name string req *http.Request statusCode int + expectedResults []skylab.BusEvent }{ { - name: "stationary test", + name: "get all packets test", req: httptest.NewRequest(http.MethodGet, "http://localhost/", nil), statusCode: http.StatusOK, + expectedResults: evs, + }, + { + name: "filter name test", + req: httptest.NewRequest(http.MethodGet, "http://localhost/?name=bms_module", nil), + statusCode: http.StatusOK, + expectedResults: func() []skylab.BusEvent { + filtered := make([]skylab.BusEvent, 0) + for _, pkt := range evs { + if pkt.Name == "bms_module" { + filtered = append(filtered, pkt) + } + } + return filtered + }(), }, } @@ -172,6 +192,25 @@ func Test_ApiV1GetPackets(t *testing.T) { t.Errorf("incorrect status code: expected %d got %d", tt.statusCode, resp.StatusCode) } + decoder := json.NewDecoder(resp.Body) + var resultEvents []skylab.BusEvent + err := decoder.Decode(&resultEvents) + if err != nil { + t.Fatalf("could not parse JSON response: %v", err) + } + + if len(resultEvents) != len(tt.expectedResults) { + t.Fatalf("response length did not match, want %d got %d", len(tt.expectedResults), len(resultEvents)) + } + + for idx := range tt.expectedResults { + expected := tt.expectedResults[idx] + actual := resultEvents[idx] + if !expected.Equals(&actual) { + t.Errorf("packet did not match, want %v got %v", expected, actual) + } + } + }) } } diff --git a/skylab/skylab.go b/skylab/skylab.go index 7bd711a..ba7051e 100644 --- a/skylab/skylab.go +++ b/skylab/skylab.go @@ -3,6 +3,7 @@ package skylab import ( + "bytes" "encoding/binary" "encoding/json" "fmt" @@ -94,9 +95,9 @@ type RawJsonEvent struct { // BusEvent is a timestamped Skylab packet - it contains type BusEvent struct { - Timestamp time.Time `json:"ts"` - Name string `json:"id"` - Data Packet `json:"data"` + Timestamp time.Time + Name string + Data Packet } func (e BusEvent) MarshalJSON() (b []byte, err error) { @@ -116,6 +117,9 @@ func (e BusEvent) MarshalJSON() (b []byte, err error) { } +// UnmarshalJSON implements JSON unmarshalling. Note that this +// uses RawJSON events, which are formatted differently. +// also it uses int64 milliseconds instead of times. func (e *BusEvent) UnmarshalJSON(b []byte) error { j := &RawJsonEvent{} @@ -132,6 +136,22 @@ func (e *BusEvent) UnmarshalJSON(b []byte) error { return err } +// Equals compares two bus events deeply. +func (e *BusEvent) Equals(other *BusEvent) bool { + if e.Name != other.Name { + return false + } + if !e.Timestamp.Equal(other.Timestamp) { + return false + } + pkt1, _ := e.Data.MarshalPacket() + pkt2, _ := e.Data.MarshalPacket() + if !bytes.Equal(pkt1, pkt2) { + return false + } + return true +} + // we need to be able to parse the JSON as well. this is done using the // generator since we can use the switch/case thing since it's the fastest