test: add upstream

This commit is contained in:
Simon Ser 2021-10-05 14:03:17 +02:00
parent 1626ffb97b
commit 74297d607b

View file

@ -8,14 +8,17 @@ import (
"gopkg.in/irc.v3" "gopkg.in/irc.v3"
) )
var testServerPrefix = &irc.Prefix{Name: "soju-test-server"}
const ( const (
testUsername = "soju-test-user" testUsername = "soju-test-user"
testPassword = testUsername testPassword = testUsername
) )
func ircPipe() (ircConn, ircConn) { func createTestDownstream(t *testing.T, srv *Server) ircConn {
c1, c2 := net.Pipe() c1, c2 := net.Pipe()
return newNetIRCConn(c1), newNetIRCConn(c2) go srv.handle(newNetIRCConn(c1))
return newNetIRCConn(c2)
} }
func createTempDB(t *testing.T) Database { func createTempDB(t *testing.T) Database {
@ -30,9 +33,7 @@ func createTempDB(t *testing.T) Database {
return db return db
} }
func createTestUser(t *testing.T) *Server { func createTestUser(t *testing.T, db Database) *User {
db := createTempDB(t)
hashed, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost) hashed, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost)
if err != nil { if err != nil {
t.Fatalf("failed to generate bcrypt hash: %v", err) t.Fatalf("failed to generate bcrypt hash: %v", err)
@ -43,7 +44,50 @@ func createTestUser(t *testing.T) *Server {
t.Fatalf("failed to store test user: %v", err) t.Fatalf("failed to store test user: %v", err)
} }
return NewServer(db) return record
}
type testUpstream struct {
net.Listener
Accept chan ircConn
}
func createTestUpstream(t *testing.T, db Database, user *User) (*Network, *testUpstream) {
ln, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("failed to create TCP listener: %v", err)
}
tu := &testUpstream{
Listener: ln,
Accept: make(chan ircConn),
}
go func() {
defer close(tu.Accept)
for {
c, err := ln.Accept()
if isErrClosed(err) {
break
} else if err != nil {
t.Fatalf("failed accepting connection: %v", err)
}
tu.Accept <- newNetIRCConn(c)
}
}()
network := &Network{
Name: "testnet",
Addr: "irc+insecure://" + ln.Addr().String(),
Nick: user.Username,
Enabled: true,
}
if err := db.StoreNetwork(user.ID, network); err != nil {
t.Fatalf("failed to store test network: %v", err)
}
return network, tu
} }
func expectMessage(t *testing.T, c ircConn, cmd string) *irc.Message { func expectMessage(t *testing.T, c ircConn, cmd string) *irc.Message {
@ -57,7 +101,7 @@ func expectMessage(t *testing.T, c ircConn, cmd string) *irc.Message {
return msg return msg
} }
func authTestUser(t *testing.T, c ircConn) { func registerDownstreamConn(t *testing.T, c ircConn, network *Network) {
c.WriteMessage(&irc.Message{ c.WriteMessage(&irc.Message{
Command: "PASS", Command: "PASS",
Params: []string{testPassword}, Params: []string{testPassword},
@ -68,22 +112,69 @@ func authTestUser(t *testing.T, c ircConn) {
}) })
c.WriteMessage(&irc.Message{ c.WriteMessage(&irc.Message{
Command: "USER", Command: "USER",
Params: []string{testUsername, "0", "*", testUsername}, Params: []string{testUsername + "/" + network.Name, "0", "*", testUsername},
}) })
expectMessage(t, c, irc.RPL_WELCOME) expectMessage(t, c, irc.RPL_WELCOME)
} }
func registerUpstreamConn(t *testing.T, c ircConn) {
msg := expectMessage(t, c, "CAP")
if msg.Params[0] != "LS" {
t.Fatalf("invalid CAP LS: got: %v", msg)
}
msg = expectMessage(t, c, "NICK")
nick := msg.Params[0]
if nick != testUsername {
t.Fatalf("invalid NICK: want %q, got: %v", testUsername, msg)
}
expectMessage(t, c, "USER")
c.WriteMessage(&irc.Message{
Prefix: testServerPrefix,
Command: irc.RPL_WELCOME,
Params: []string{nick, "Welcome!"},
})
c.WriteMessage(&irc.Message{
Prefix: testServerPrefix,
Command: irc.RPL_YOURHOST,
Params: []string{nick, "Your host is soju-test-server"},
})
c.WriteMessage(&irc.Message{
Prefix: testServerPrefix,
Command: irc.RPL_CREATED,
Params: []string{nick, "Who cares when the server was created?"},
})
c.WriteMessage(&irc.Message{
Prefix: testServerPrefix,
Command: irc.RPL_MYINFO,
Params: []string{nick, testServerPrefix.Name, "soju", "aiwroO", "OovaimnqpsrtklbeI"},
})
c.WriteMessage(&irc.Message{
Prefix: testServerPrefix,
Command: irc.ERR_NOMOTD,
Params: []string{nick, "No MOTD"},
})
}
func TestServer(t *testing.T) { func TestServer(t *testing.T) {
srv := createTestUser(t) db := createTempDB(t)
user := createTestUser(t, db)
network, upstream := createTestUpstream(t, db, user)
defer upstream.Close()
srv := NewServer(db)
if err := srv.Start(); err != nil { if err := srv.Start(); err != nil {
t.Fatalf("failed to start server: %v", err) t.Fatalf("failed to start server: %v", err)
} }
defer srv.Shutdown() defer srv.Shutdown()
c, srvConn := ircPipe() uc := <-upstream.Accept
defer c.Close() defer uc.Close()
go srv.handle(srvConn) registerUpstreamConn(t, uc)
authTestUser(t, c) dc := createTestDownstream(t, srv)
defer dc.Close()
registerDownstreamConn(t, dc, network)
} }