snowflake/common/messages/messages_test.go
Cecylia Bocovich 270eb21803 Encode client-broker messages as json in HTTP body
Send the client poll request and response in a json-encoded format in
the HTTP request body rather than sending the data in HTTP headers. This
will pave the way for using domain-fronting alternatives for the
Snowflake rendezvous.
2021-06-02 09:52:42 -04:00

370 lines
8 KiB
Go

package messages
import (
"bytes"
"encoding/json"
"fmt"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDecodeProxyPollRequest(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
sid string
proxyType string
natType string
data string
err error
}{
{
//Version 1.0 proxy message
"ymbcCMto7KHNGYlp",
"",
"unknown",
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`,
nil,
},
{
//Version 1.1 proxy message
"ymbcCMto7KHNGYlp",
"standalone",
"unknown",
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.1","Type":"standalone"}`,
nil,
},
{
//Version 1.2 proxy message
"ymbcCMto7KHNGYlp",
"standalone",
"restricted",
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted"}`,
nil,
},
{
//Version 0.X proxy message:
"",
"",
"",
"",
&json.SyntaxError{},
},
{
"",
"",
"",
`{"Sid":"ymbcCMto7KHNGYlp"}`,
fmt.Errorf(""),
},
{
"",
"",
"",
"{}",
fmt.Errorf(""),
},
{
"",
"",
"",
`{"Version":"1.0"}`,
fmt.Errorf(""),
},
{
"",
"",
"",
`{"Version":"2.0"}`,
fmt.Errorf(""),
},
} {
sid, proxyType, natType, err := DecodePollRequest([]byte(test.data))
So(sid, ShouldResemble, test.sid)
So(proxyType, ShouldResemble, test.proxyType)
So(natType, ShouldResemble, test.natType)
So(err, ShouldHaveSameTypeAs, test.err)
}
})
}
func TestEncodeProxyPollRequests(t *testing.T) {
Convey("Context", t, func() {
b, err := EncodePollRequest("ymbcCMto7KHNGYlp", "standalone", "unknown")
So(err, ShouldEqual, nil)
sid, proxyType, natType, err := DecodePollRequest(b)
So(sid, ShouldEqual, "ymbcCMto7KHNGYlp")
So(proxyType, ShouldEqual, "standalone")
So(natType, ShouldEqual, "unknown")
So(err, ShouldEqual, nil)
})
}
func TestDecodeProxyPollResponse(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
offer string
data string
err error
}{
{
"fake offer",
`{"Status":"client match","Offer":"fake offer","NAT":"unknown"}`,
nil,
},
{
"",
`{"Status":"no match"}`,
nil,
},
{
"",
`{"Status":"client match"}`,
fmt.Errorf("no supplied offer"),
},
{
"",
`{"Test":"test"}`,
fmt.Errorf(""),
},
} {
offer, _, err := DecodePollResponse([]byte(test.data))
So(err, ShouldHaveSameTypeAs, test.err)
So(offer, ShouldResemble, test.offer)
}
})
}
func TestEncodeProxyPollResponse(t *testing.T) {
Convey("Context", t, func() {
b, err := EncodePollResponse("fake offer", true, "restricted")
So(err, ShouldEqual, nil)
offer, natType, err := DecodePollResponse(b)
So(offer, ShouldEqual, "fake offer")
So(natType, ShouldEqual, "restricted")
So(err, ShouldEqual, nil)
b, err = EncodePollResponse("", false, "unknown")
So(err, ShouldEqual, nil)
offer, natType, err = DecodePollResponse(b)
So(offer, ShouldEqual, "")
So(natType, ShouldEqual, "unknown")
So(err, ShouldEqual, nil)
})
}
func TestDecodeProxyAnswerRequest(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
answer string
sid string
data string
err error
}{
{
"test",
"test",
`{"Version":"1.0","Sid":"test","Answer":"test"}`,
nil,
},
{
"",
"",
`{"type":"offer","sdp":"v=0\r\no=- 4358805017720277108 2 IN IP4 [scrubbed]\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 56688 DTLS/SCTP 5000\r\nc=IN IP4 [scrubbed]\r\na=candidate:3769337065 1 udp 2122260223 [scrubbed] 56688 typ host generation 0 network-id 1 network-cost 50\r\na=candidate:2921887769 1 tcp 1518280447 [scrubbed] 35441 typ host tcptype passive generation 0 network-id 1 network-cost 50\r\na=ice-ufrag:aMAZ\r\na=ice-pwd:jcHb08Jjgrazp2dzjdrvPPvV\r\na=ice-options:trickle\r\na=fingerprint:sha-256 C8:88:EE:B9:E7:02:2E:21:37:ED:7A:D1:EB:2B:A3:15:A2:3B:5B:1C:3D:D4:D5:1F:06:CF:52:40:03:F8:DD:66\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n"}`,
fmt.Errorf(""),
},
{
"",
"",
`{"Version":"1.0","Answer":"test"}`,
fmt.Errorf(""),
},
{
"",
"",
`{"Version":"1.0","Sid":"test"}`,
fmt.Errorf(""),
},
} {
answer, sid, err := DecodeAnswerRequest([]byte(test.data))
So(answer, ShouldResemble, test.answer)
So(sid, ShouldResemble, test.sid)
So(err, ShouldHaveSameTypeAs, test.err)
}
})
}
func TestEncodeProxyAnswerRequest(t *testing.T) {
Convey("Context", t, func() {
b, err := EncodeAnswerRequest("test answer", "test sid")
So(err, ShouldEqual, nil)
answer, sid, err := DecodeAnswerRequest(b)
So(answer, ShouldEqual, "test answer")
So(sid, ShouldEqual, "test sid")
So(err, ShouldEqual, nil)
})
}
func TestDecodeProxyAnswerResponse(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
success bool
data string
err error
}{
{
true,
`{"Status":"success"}`,
nil,
},
{
false,
`{"Status":"client gone"}`,
nil,
},
{
false,
`{"Test":"test"}`,
fmt.Errorf(""),
},
} {
success, err := DecodeAnswerResponse([]byte(test.data))
So(success, ShouldResemble, test.success)
So(err, ShouldHaveSameTypeAs, test.err)
}
})
}
func TestEncodeProxyAnswerResponse(t *testing.T) {
Convey("Context", t, func() {
b, err := EncodeAnswerResponse(true)
So(err, ShouldEqual, nil)
success, err := DecodeAnswerResponse(b)
So(success, ShouldEqual, true)
So(err, ShouldEqual, nil)
b, err = EncodeAnswerResponse(false)
So(err, ShouldEqual, nil)
success, err = DecodeAnswerResponse(b)
So(success, ShouldEqual, false)
So(err, ShouldEqual, nil)
})
}
func TestDecodeClientPollRequest(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
natType string
offer string
data string
err error
}{
{
//version 1.0 client message
"unknown",
"fake",
`{"nat":"unknown","offer":"fake"}`,
nil,
},
{
//version 1.0 client message
"unknown",
"fake",
`{"offer":"fake"}`,
nil,
},
{
//unknown version
"",
"",
`{"version":"2.0"}`,
fmt.Errorf(""),
},
{
//no offer
"",
"",
`{"nat":"unknown"}`,
fmt.Errorf(""),
},
} {
req, err := DecodeClientPollRequest([]byte(test.data))
if test.err == nil {
So(req.NAT, ShouldResemble, test.natType)
So(req.Offer, ShouldResemble, test.offer)
}
So(err, ShouldHaveSameTypeAs, test.err)
}
})
}
func TestEncodeClientPollRequests(t *testing.T) {
Convey("Context", t, func() {
req1 := &ClientPollRequest{
NAT: "unknown",
Offer: "fake",
}
b, err := req1.EncodePollRequest()
So(err, ShouldEqual, nil)
fmt.Println(string(b))
parts := bytes.SplitN(b, []byte("\n"), 2)
So(string(parts[0]), ShouldEqual, "1.0")
b = parts[1]
req2, err := DecodeClientPollRequest(b)
So(err, ShouldEqual, nil)
So(req2, ShouldResemble, req1)
})
}
func TestDecodeClientPollResponse(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
answer string
msg string
data string
}{
{
"fake answer",
"",
`{"answer":"fake answer"}`,
},
{
"",
"no snowflakes",
`{"error":"no snowflakes"}`,
},
} {
resp, err := DecodeClientPollResponse([]byte(test.data))
So(err, ShouldBeNil)
So(resp.Answer, ShouldResemble, test.answer)
So(resp.Error, ShouldResemble, test.msg)
}
})
}
func TestEncodeClientPollResponse(t *testing.T) {
Convey("Context", t, func() {
resp1 := &ClientPollResponse{
Answer: "fake answer",
}
b, err := resp1.EncodePollResponse()
So(err, ShouldEqual, nil)
resp2, err := DecodeClientPollResponse(b)
So(err, ShouldEqual, nil)
So(resp1, ShouldResemble, resp2)
resp1 = &ClientPollResponse{
Error: "failed",
}
b, err = resp1.EncodePollResponse()
So(err, ShouldEqual, nil)
resp2, err = DecodeClientPollResponse(b)
So(err, ShouldEqual, nil)
So(resp1, ShouldResemble, resp2)
})
}