more tests! added BusEvent.Equals
Some checks failed
Go / build (1.21) (push) Failing after 1m6s
Go / build (1.22) (push) Failing after 1m5s

This commit is contained in:
saji 2024-03-07 23:50:13 -06:00
parent a28393388b
commit 90e8c3f101
5 changed files with 83 additions and 12 deletions

View file

@ -3,7 +3,6 @@ package gotelem
import ( import (
"log/slog" "log/slog"
"os" "os"
"reflect"
"sync" "sync"
"testing" "testing"
"time" "time"
@ -45,11 +44,8 @@ func TestBroker(t *testing.T) {
var recvEvent skylab.BusEvent var recvEvent skylab.BusEvent
select { select {
case recvEvent = <-sub: case recvEvent = <-sub:
if !reflect.DeepEqual(recvEvent.Data, testEvent.Data) { if !testEvent.Equals(&recvEvent) {
t.Fatalf("mismatched data, want %v got %v", testEvent.Data, recvEvent.Data) t.Fatalf("events not equal, want %v got %v", testEvent, recvEvent)
}
if !testEvent.Timestamp.Equal(recvEvent.Timestamp) {
t.Fatalf("mismatched timestamp, want %v got %v", testEvent.Timestamp, recvEvent.Timestamp)
} }
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
t.Fatalf("timeout waiting for packet") t.Fatalf("timeout waiting for packet")

4
db.go
View file

@ -195,7 +195,7 @@ func (tdb *TelemDb) GetPackets(ctx context.Context, filter BusEventFilter, lim *
sb.WriteString(strings.Join(whereFrags, " AND ")) 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. // Augment our data further if there's i.e a limit modifier.
// TODO: factor this out maybe? // TODO: factor this out maybe?
@ -278,7 +278,7 @@ func (tdb *TelemDb) GetValues(ctx context.Context, filter BusEventFilter,
// join qstrings with AND // join qstrings with AND
sb.WriteString(strings.Join(whereFrags, " AND ")) sb.WriteString(strings.Join(whereFrags, " AND "))
sb.WriteString(" ORDER BY ts DESC") sb.WriteString(" ORDER BY ts ASC")
if lim != nil { if lim != nil {
lim.ModifyStatement(&sb) lim.ModifyStatement(&sb)

View file

@ -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) { func TestTelemDb(t *testing.T) {
t.Run("test opening database", func(t *testing.T) { t.Run("test opening database", func(t *testing.T) {

View file

@ -1,6 +1,7 @@
package gotelem package gotelem
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -8,6 +9,8 @@ import (
"reflect" "reflect"
"testing" "testing"
"time" "time"
"github.com/kschamplin/gotelem/skylab"
) )
func Test_extractBusEventFilter(t *testing.T) { func Test_extractBusEventFilter(t *testing.T) {
@ -146,17 +149,34 @@ func Test_extractLimitModifier(t *testing.T) {
func Test_ApiV1GetPackets(t *testing.T) { func Test_ApiV1GetPackets(t *testing.T) {
tdb := MakeMockDatabase(t.Name()) tdb := MakeMockDatabase(t.Name())
SeedMockDatabase(tdb) SeedMockDatabase(tdb)
evs := GetSeedEvents()
handler := apiV1GetPackets(tdb) handler := apiV1GetPackets(tdb)
tests := []struct{ tests := []struct{
name string name string
req *http.Request req *http.Request
statusCode int statusCode int
expectedResults []skylab.BusEvent
}{ }{
{ {
name: "stationary test", name: "get all packets test",
req: httptest.NewRequest(http.MethodGet, "http://localhost/", nil), req: httptest.NewRequest(http.MethodGet, "http://localhost/", nil),
statusCode: http.StatusOK, 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) 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)
}
}
}) })
} }
} }

View file

@ -3,6 +3,7 @@
package skylab package skylab
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -94,9 +95,9 @@ type RawJsonEvent struct {
// BusEvent is a timestamped Skylab packet - it contains // BusEvent is a timestamped Skylab packet - it contains
type BusEvent struct { type BusEvent struct {
Timestamp time.Time `json:"ts"` Timestamp time.Time
Name string `json:"id"` Name string
Data Packet `json:"data"` Data Packet
} }
func (e BusEvent) MarshalJSON() (b []byte, err error) { 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 { func (e *BusEvent) UnmarshalJSON(b []byte) error {
j := &RawJsonEvent{} j := &RawJsonEvent{}
@ -132,6 +136,22 @@ func (e *BusEvent) UnmarshalJSON(b []byte) error {
return err 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 // 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 // generator since we can use the switch/case thing since it's the fastest