snowflake/server/lib/turbotunnel_test.go
Cecylia Bocovich 6634f2bec9 Store net.Addr in clientIDAddrMap
This fixes a stats collection bug where we were converting client
addresses between a string and net.Addr using the clientAddr function
multiple times, resulting in an empty string for all addresses.
2021-06-19 11:16:38 -04:00

129 lines
3.8 KiB
Go

package lib
import (
"encoding/binary"
"net"
"testing"
"git.torproject.org/pluggable-transports/snowflake.git/common/turbotunnel"
)
func TestClientIDMap(t *testing.T) {
// Convert a uint64 into a ClientID.
id := func(n uint64) turbotunnel.ClientID {
var clientID turbotunnel.ClientID
binary.PutUvarint(clientID[:], n)
return clientID
}
// Does m.Get(key) and checks that the output matches what is expected.
expectGet := func(m *clientIDMap, clientID turbotunnel.ClientID, expectedAddr string, expectedOK bool) {
t.Helper()
addr, ok := m.Get(clientID)
if (ok && addr.String() != expectedAddr) || ok != expectedOK {
t.Errorf("expected (%+q, %v), got (%+q, %v)", expectedAddr, expectedOK, addr, ok)
}
}
// Checks that the len of m.current is as expected.
expectSize := func(m *clientIDMap, expectedLen int) {
t.Helper()
if len(m.current) != expectedLen {
t.Errorf("expected map len %d, got %d %+v", expectedLen, len(m.current), m.current)
}
}
// Convert a string to a net.Addr
ip := func(addr string) net.Addr {
ret, err := net.ResolveIPAddr("ip", addr)
if err != nil {
t.Errorf("received error: %s", err.Error())
}
return ret
}
// Zero-capacity map can't remember anything.
{
m := newClientIDMap(0)
expectSize(m, 0)
expectGet(m, id(0), "", false)
expectGet(m, id(1234), "", false)
m.Set(id(0), ip("1.1.1.1"))
expectSize(m, 0)
expectGet(m, id(0), "", false)
expectGet(m, id(1234), "", false)
m.Set(id(1234), ip("1.1.1.1"))
expectSize(m, 0)
expectGet(m, id(0), "", false)
expectGet(m, id(1234), "", false)
}
{
m := newClientIDMap(1)
expectSize(m, 0)
expectGet(m, id(0), "", false)
expectGet(m, id(1), "", false)
m.Set(id(0), ip("1.1.1.1"))
expectSize(m, 1)
expectGet(m, id(0), "1.1.1.1", true)
expectGet(m, id(1), "", false)
m.Set(id(1), ip("1.1.1.2")) // forgets the (0, "1.1.1.1") entry
expectSize(m, 1)
expectGet(m, id(0), "", false)
expectGet(m, id(1), "1.1.1.2", true)
m.Set(id(1), ip("1.1.1.3")) // forgets the (1, "1.1.1.2") entry
expectSize(m, 1)
expectGet(m, id(0), "", false)
expectGet(m, id(1), "1.1.1.3", true)
}
{
m := newClientIDMap(5)
m.Set(id(0), ip("1.1.1.1"))
m.Set(id(1), ip("1.1.1.2"))
m.Set(id(2), ip("1.1.1.3"))
m.Set(id(0), ip("1.1.1.4")) // shadows the (0, "1.1.1.1") entry
m.Set(id(3), ip("1.1.1.5"))
expectSize(m, 4)
expectGet(m, id(0), "1.1.1.4", true)
expectGet(m, id(1), "1.1.1.2", true)
expectGet(m, id(2), "1.1.1.3", true)
expectGet(m, id(3), "1.1.1.5", true)
expectGet(m, id(4), "", false)
m.Set(id(4), ip("1.1.1.6")) // forgets the (0, "1.1.1.1") entry but should preserve (0, "1.1.1.4")
expectSize(m, 5)
expectGet(m, id(0), "1.1.1.4", true)
expectGet(m, id(1), "1.1.1.2", true)
expectGet(m, id(2), "1.1.1.3", true)
expectGet(m, id(3), "1.1.1.5", true)
expectGet(m, id(4), "1.1.1.6", true)
m.Set(id(5), ip("1.1.1.7")) // forgets the (1, "1.1.1.2") entry
m.Set(id(0), ip("1.1.1.8")) // forgets the (2, "1.1.1.3") entry and shadows (0, "1.1.1.4")
expectSize(m, 4)
expectGet(m, id(0), "1.1.1.8", true)
expectGet(m, id(1), "", false)
expectGet(m, id(2), "", false)
expectGet(m, id(3), "1.1.1.5", true)
expectGet(m, id(4), "1.1.1.6", true)
expectGet(m, id(5), "1.1.1.7", true)
m.Set(id(0), ip("1.1.1.9")) // forgets the (0, "1.1.1.4") entry and shadows (0, "1.1.1.8")
m.Set(id(0), ip("1.1.1.10")) // forgets the (3, "1.1.1.5") entry and shadows (0, "1.1.1.9")
m.Set(id(0), ip("1.1.1.11")) // forgets the (4, "1.1.1.6") entry and shadows (0, "1.1.1.10")
m.Set(id(0), ip("1.1.1.12")) // forgets the (5, "1.1.1.7") entry and shadows (0, "1.1.1.11")
expectSize(m, 1)
expectGet(m, id(0), "1.1.1.12", true)
expectGet(m, id(1), "", false)
expectGet(m, id(2), "", false)
expectGet(m, id(3), "", false)
expectGet(m, id(4), "", false)
expectGet(m, id(5), "", false)
}
}