diff --git a/inbound_version_negotiation_test.go b/inbound_version_negotiation_test.go new file mode 100644 index 0000000..37f0ec8 --- /dev/null +++ b/inbound_version_negotiation_test.go @@ -0,0 +1,112 @@ +package goricochet + +import ( + "io" + "net" + "testing" + "github.com/s-rah/go-ricochet/utils" +) + +func TestBadProtcolLength(t *testing.T) { + + connect := func() { + conn, err := net.Dial("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + conn.Write([]byte{0x49, 0x4D}) + } + + l, err := net.Listen("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer l.Close() + go connect() + conn, err := l.Accept() + _, err = NegotiateVersionInbound(conn) + if err != io.ErrUnexpectedEOF { + t.Errorf("Invalid Error Received. Expected ErrUnexpectedEOF. Got %v", err) + } + +} + +func TestNoSupportedVersions(t *testing.T) { + + connect := func() { + conn, err := net.Dial("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + conn.Write([]byte{0x49, 0x4D, 0x00, 0xFF}) + } + + l, err := net.Listen("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer l.Close() + go connect() + conn, err := l.Accept() + _, err = NegotiateVersionInbound(conn) + if err != utils.VersionNegotiationError { + t.Errorf("Invalid Error Received. Expected VersionNegotiationError. Got %v", err) + } + +} + +func TestInvalidVersionList(t *testing.T) { + + connect := func() { + conn, err := net.Dial("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + conn.Write([]byte{0x49, 0x4D, 0x01}) + } + + l, err := net.Listen("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer l.Close() + go connect() + conn, err := l.Accept() + _, err = NegotiateVersionInbound(conn) + if err != utils.VersionNegotiationError { + t.Errorf("Invalid Error Received. Expected VersionNegotiationError. Got %v", err) + } + +} + +func TestNoCompatibleVersions(t *testing.T) { + + connect := func() { + conn, err := net.Dial("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + conn.Write([]byte{0x49, 0x4D, 0x01, 0xFF}) + } + + l, err := net.Listen("tcp", ":4000") + if err != nil { + t.Fatal(err) + } + defer l.Close() + go connect() + conn, err := l.Accept() + _, err = NegotiateVersionInbound(conn) + if err != utils.VersionNegotiationFailed { + t.Errorf("Invalid Error Received. Expected VersionNegotiationFailed. Got %v", err) + } + +} diff --git a/testing.md b/testing.md new file mode 100644 index 0000000..109b898 --- /dev/null +++ b/testing.md @@ -0,0 +1,35 @@ +# Ricochet Testing Specification + +This documents outlines each scenario this library must correctly handle and +links it to the automated test that exercises that functionality. + +We separate this document into two sections, one for inbound connections, and the +other for outbound connections. + +# Inbound + +## Version Negotiation + +File: [ricochet_test.go](./inbound_version_negotiation_test.go) + +### Invalid Protocol + +If the inbound listener receives: + +* Less than 4 bytes (`TestBadProtcolLength`) +* The first 2 bytes are not equal ot 0x49 and 0x4D +* A number of supported Versions < 1 (`TestNoSupportedVersions`, `TestInvalidVersionList`) + +Then it must close the connection. + +### No Compatible Version Found + +If the inbound listener does not receive a compatible version in the list of +supported versions. Then is must close the connection. `TestNoCompatibleVersions` + +### Successful Version Negotiation + +Assuming the inbound listener receives a valid protocol message, and that message +contains a known supported version. Then the connection should remain open. + +# Outbound