more tests! added BusEvent.Equals
This commit is contained in:
parent
a28393388b
commit
90e8c3f101
|
@ -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
4
db.go
|
@ -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)
|
||||||
|
|
16
db_test.go
16
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) {
|
func TestTelemDb(t *testing.T) {
|
||||||
|
|
||||||
t.Run("test opening database", func(t *testing.T) {
|
t.Run("test opening database", func(t *testing.T) {
|
||||||
|
|
41
http_test.go
41
http_test.go
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue