201 lines
4.7 KiB
Go
201 lines
4.7 KiB
Go
|
package mainline
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
"net"
|
||
|
)
|
||
|
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|