magnetico/magneticod/dht/mainline/protocol_test.go
Bora Alper ae691ada79 started cleaning up for v0.7.0
I've decided instead to release a minimum viable product for v0.7.0 and
get some feedback from the community, and most importantly some
motivation as well to be able to keep working on magnetico as it
currently feels like a Sisyphean where the development seem to never
going to end...
2017-11-02 23:15:13 +00:00

217 lines
5.4 KiB
Go

package mainline
import (
"net"
"testing"
)
var protocolTest_validInstances = []struct {
validator func(*Message) bool
msg Message
}{
// ping Query:
{
validator: validatePingQueryMessage,
msg: Message{
T: []byte("aa"),
Y: "q",
Q: "ping",
A: QueryArguments{
ID: []byte("abcdefghij0123456789"),
},
},
},
// ping or announce_peer Response:
// Also, includes NUL and EOT characters as transaction ID (`t`).
{
validator: validatePingORannouncePeerResponseMessage,
msg: Message{
T: []byte("\x00\x04"),
Y: "r",
R: ResponseValues{
ID: []byte("mnopqrstuvwxyz123456"),
},
},
},
// find_node Query:
{
validator: validateFindNodeQueryMessage,
msg: Message{
T: []byte("\x09\x0a"),
Y: "q",
Q: "find_node",
A: QueryArguments{
ID: []byte("abcdefghij0123456789"),
Target: []byte("mnopqrstuvwxyz123456"),
},
},
},
// find_node Response with no nodes (`nodes` key still exists):
{
validator: validateFindNodeResponseMessage,
msg: Message{
T: []byte("aa"),
Y: "r",
R: ResponseValues{
ID: []byte("0123456789abcdefghij"),
Nodes: []CompactNodeInfo{},
},
},
},
// find_node Response with a single node:
{
validator: validateFindNodeResponseMessage,
msg: Message{
T: []byte("aa"),
Y: "r",
R: ResponseValues{
ID: []byte("0123456789abcdefghij"),
Nodes: []CompactNodeInfo{
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
},
},
},
},
// find_node Response with 8 nodes (all the same except the very last one):
{
validator: validateFindNodeResponseMessage,
msg: Message{
T: []byte("aa"),
Y: "r",
R: ResponseValues{
ID: []byte("0123456789abcdefghij"),
Nodes: []CompactNodeInfo{
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("zyxwvutsrqponmlkjihg"),
Addr: net.UDPAddr{IP: []byte("\xf5\x8e\x82\x8b"), Port: 6931, Zone: ""},
},
},
},
},
},
// get_peers Query:
{
validator: validateGetPeersQueryMessage,
msg: Message{
T: []byte("aa"),
Y: "q",
Q: "get_peers",
A: QueryArguments{
ID: []byte("abcdefghij0123456789"),
InfoHash: []byte("mnopqrstuvwxyz123456"),
},
},
},
// get_peers Response with 2 peers (`values`):
{
validator: validateGetPeersResponseMessage,
msg: Message{
T: []byte("aa"),
Y: "r",
R: ResponseValues{
ID: []byte("abcdefghij0123456789"),
Token: []byte("aoeusnth"),
Values: []CompactPeer{
{IP: []byte("axje"), Port: 11893},
{IP: []byte("idht"), Port: 28269},
},
},
},
},
// get_peers Response with 2 closest nodes (`nodes`):
{
validator: validateGetPeersResponseMessage,
msg: Message{
T: []byte("aa"),
Y: "r",
R: ResponseValues{
ID: []byte("abcdefghij0123456789"),
Token: []byte("aoeusnth"),
Nodes: []CompactNodeInfo{
{
ID: []byte("abcdefghijklmnopqrst"),
Addr: net.UDPAddr{IP: []byte("\x8b\x82\x8e\xf5"), Port: 3169, Zone: ""},
},
{
ID: []byte("zyxwvutsrqponmlkjihg"),
Addr: net.UDPAddr{IP: []byte("\xf5\x8e\x82\x8b"), Port: 6931, Zone: ""},
},
},
},
},
},
// announce_peer Query without optional `implied_port` argument:
{
validator: validateAnnouncePeerQueryMessage,
msg: Message{
T: []byte("aa"),
Y: "q",
Q: "announce_peer",
A: QueryArguments{
ID: []byte("abcdefghij0123456789"),
InfoHash: []byte("mnopqrstuvwxyz123456"),
Port: 6881,
Token: []byte("aoeusnth"),
},
},
},
// TODO: Add announce_peer Query with optional `implied_port` argument.
}
func TestValidators(t *testing.T) {
for i, instance := range protocolTest_validInstances {
if isValid := instance.validator(&instance.msg); !isValid {
t.Errorf("False-positive for valid msg #%d!", i+1)
}
}
}
func TestNewFindNodeQuery(t *testing.T) {
if !validateFindNodeQueryMessage(NewFindNodeQuery([]byte("qwertyuopasdfghjklzx"), []byte("xzlkjhgfdsapouytrewq"))) {
t.Errorf("NewFindNodeQuery returned an invalid message!")
}
}
func TestNewPingResponse(t *testing.T) {
if !validatePingORannouncePeerResponseMessage(NewPingResponse([]byte("tt"), []byte("qwertyuopasdfghjklzx"))) {
t.Errorf("NewPingResponse returned an invalid message!")
}
}
func TestNewGetPeersResponseWithNodes(t *testing.T) {
if !validateGetPeersResponseMessage(NewGetPeersResponseWithNodes([]byte("tt"), []byte("qwertyuopasdfghjklzx"), []byte("token"), []CompactNodeInfo{})) {
t.Errorf("NewGetPeersResponseWithNodes returned an invalid message!")
}
}