12 Commits

Author SHA1 Message Date
James Mills
0e07999cb2 Add TestSASL 2017-12-06 02:12:31 -08:00
James Mills
79c60eafaf Added some topic tests 2017-12-06 02:02:23 -08:00
James Mills
0ec9aaa5eb Fix all tests :D yay 2017-12-06 01:49:15 -08:00
James Mills
90910a20b1 Removed use of deadlock sync package 2017-12-03 23:30:20 -08:00
James Mills
43e4726461 Update vendored 3rd-party deps 2017-12-03 20:34:48 -08:00
James Mills
493b58459d Bah humbut 2017-12-03 20:22:23 -08:00
James Mills
d53b08b3a0 Added TestChannel_BadChannelKey and TestChannel_GoodChannelKey tests 2017-12-03 18:06:16 -08:00
James Mills
8ba7a2c1e2 Added TestChannel_NoExternal test 2017-12-03 17:41:56 -08:00
James Mills
aed917ea2f Fuck it 2017-12-03 17:28:55 -08:00
James Mills
94bbfe4baf Try to fix TestChannel_PRIVMSG test 2017-12-03 16:11:23 -08:00
James Mills
8732f70630 Refactored integration testing framework for better timtouts and added TestChannel_InviteOnly test 2017-12-03 14:34:31 -08:00
James Mills
b7f798d600 Added TestChannel_PRIVMSG test 2017-12-03 13:01:11 -08:00
17 changed files with 415 additions and 76 deletions

12
.gitmodules vendored
View File

@@ -43,15 +43,15 @@
[submodule "vendor/github.com/prometheus/procfs"]
path = vendor/github.com/prometheus/procfs
url = https://github.com/prometheus/procfs
[submodule "vendor/github.com/sasha-s/go-deadlock"]
path = vendor/github.com/sasha-s/go-deadlock
url = https://github.com/sasha-s/go-deadlock
[submodule "vendor/github.com/petermattis/goid"]
path = vendor/github.com/petermattis/goid
url = https://github.com/petermattis/goid
[submodule "vendor/github.com/thoj/go-ircevent"]
path = vendor/github.com/thoj/go-ircevent
url = https://github.com/thoj/go-ircevent
[submodule "vendor/github.com/stretchr/testify"]
path = vendor/github.com/stretchr/testify
url = https://github.com/stretchr/testify
[submodule "vendor/github.com/renstrom/shortuuid"]
path = vendor/github.com/renstrom/shortuuid
url = https://github.com/renstrom/shortuuid
[submodule "vendor/github.com/satori/go.uuid"]
path = vendor/github.com/satori/go.uuid
url = https://github.com/satori/go.uuid

View File

@@ -72,8 +72,14 @@ func NewClient(server *Server, conn net.Conn) *Client {
//
func (client *Client) writeloop() {
for reply := range client.replies {
client.socket.Write(reply)
for {
select {
case reply, ok := <-client.replies:
if !ok || reply == "" || client.socket == nil {
return
}
client.socket.Write(reply)
}
}
}

View File

@@ -4,9 +4,7 @@ import (
"errors"
"regexp"
"strings"
//"sync"
sync "github.com/sasha-s/go-deadlock"
"sync"
"github.com/DanielOaks/girc-go/ircmatch"
)

View File

@@ -4,9 +4,7 @@ import (
"errors"
"io/ioutil"
"log"
//"sync"
sync "github.com/sasha-s/go-deadlock"
"sync"
"github.com/imdario/mergo"
"gopkg.in/yaml.v2"

View File

@@ -4,9 +4,8 @@ import (
"encoding/base64"
"fmt"
"golang.org/x/crypto/bcrypt"
//"sync"
"sync"
sync "github.com/sasha-s/go-deadlock"
log "github.com/sirupsen/logrus"
)

View File

@@ -2,9 +2,7 @@ package irc
import (
"bytes"
//"sync"
sync "github.com/sasha-s/go-deadlock"
"sync"
)
type SaslState struct {

View File

@@ -3,9 +3,7 @@ package irc
import (
"fmt"
"strings"
//"sync"
sync "github.com/sasha-s/go-deadlock"
"sync"
)
//

View File

@@ -1,9 +1,7 @@
package irc
import (
//"sync"
sync "github.com/sasha-s/go-deadlock"
"sync"
)
type WhoWasList struct {

View File

@@ -2,25 +2,29 @@ package main
import (
"flag"
"log"
"fmt"
"os"
"strings"
"testing"
"time"
log "github.com/sirupsen/logrus"
"github.com/renstrom/shortuuid"
"github.com/stretchr/testify/assert"
"github.com/thoj/go-ircevent"
eris "github.com/prologic/eris/irc"
)
const (
TIMEOUT = 3 * time.Second
)
var (
done chan bool
server *eris.Server
client *irc.Connection
clients map[string]*irc.Connection
tls = flag.Bool("tls", false, "run tests with TLS")
debug = flag.Bool("d", false, "enable debug logging")
)
func setupServer() *eris.Server {
@@ -31,6 +35,11 @@ func setupServer() *eris.Server {
config.Server.Description = "Test"
config.Server.Listen = []string{":6667"}
// SASL
config.Account = map[string]*eris.PassConfig{
"admin": &eris.PassConfig{"JDJhJDA0JGtUU1JVc1JOUy9DbEh1WEdvYVlMdGVnclp6YnA3NDBOZGY1WUZhdTZtRzVmb1VKdXQ5ckZD"},
}
server := eris.NewServer(config)
go server.Run()
@@ -38,9 +47,21 @@ func setupServer() *eris.Server {
return server
}
func newClient(nick, user, name string, start bool) *irc.Connection {
client := irc.IRC(nick, user)
client.RealName = name
func randomValidName() string {
var name eris.Name
for {
name = eris.NewName(shortuuid.New())
if name.IsNickname() {
break
}
}
return name.String()
}
func newClient(start bool) *irc.Connection {
name := randomValidName()
client := irc.IRC(name, name)
client.RealName = fmt.Sprintf("Test Client: %s", name)
err := client.Connect("localhost:6667")
if err != nil {
@@ -57,21 +78,16 @@ func newClient(nick, user, name string, start bool) *irc.Connection {
func TestMain(m *testing.M) {
flag.Parse()
done = make(chan bool)
if *debug {
log.SetLevel(log.DebugLevel)
} else {
log.SetLevel(log.WarnLevel)
}
server = setupServer()
client = newClient("test", "test", "Test", true)
clients = make(map[string]*irc.Connection)
clients["test1"] = newClient("test1", "test", "Test 1", true)
clients["test2"] = newClient("test2", "test", "Test 2", true)
result := m.Run()
for _, client := range clients {
client.Quit()
}
server.Stop()
os.Exit(result)
@@ -88,20 +104,46 @@ func TestConnection(t *testing.T) {
expected = true
actual = make(chan bool)
client := newClient("connect", "connect", "Connect", false)
client := newClient(false)
client.AddCallback("001", func(e *irc.Event) {
defer func() { done <- true }()
actual <- true
})
time.AfterFunc(1*time.Second, func() { done <- true })
defer client.Quit()
go client.Loop()
<-done
assert.Equal(expected, <-actual)
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestSASL(t *testing.T) {
assert := assert.New(t)
expected := true
actual := make(chan bool)
client := newClient(false)
client.SASLLogin = "admin"
client.SASLPassword = "admin"
client.AddCallback("001", func(e *irc.Event) {
actual <- true
})
defer client.Quit()
go client.Loop()
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestRplWelcome(t *testing.T) {
@@ -115,20 +157,21 @@ func TestRplWelcome(t *testing.T) {
expected = "Welcome to the .* Internet Relay Network .*!.*@.*"
actual = make(chan string)
client := newClient("connect", "connect", "Connect", false)
client := newClient(false)
client.AddCallback("001", func(e *irc.Event) {
defer func() { done <- true }()
actual <- e.Message()
})
time.AfterFunc(1*time.Second, func() { done <- true })
defer client.Quit()
go client.Loop()
<-done
assert.Regexp(expected, <-actual)
select {
case res := <-actual:
assert.Regexp(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestUser_JOIN(t *testing.T) {
@@ -139,24 +182,75 @@ func TestUser_JOIN(t *testing.T) {
actual chan string
)
expected = []string{"test", "=", "#test", "@test"}
actual = make(chan string)
client.AddCallback("353", func(e *irc.Event) {
defer func() { done <- true }()
client := newClient(true)
client.AddCallback("001", func(e *irc.Event) {
expected = []string{e.Arguments[0], "=", "#join", fmt.Sprintf("@%s", e.Arguments[0])}
})
client.AddCallback("353", func(e *irc.Event) {
for i := range e.Arguments {
actual <- e.Arguments[i]
}
})
time.AfterFunc(1*time.Second, func() { done <- true })
client.Join("#test")
client.SendRaw("NAMES #test")
<-done
defer client.Quit()
client.Join("#join")
client.SendRaw("NAMES #join")
for i := range expected {
assert.Equal(expected[i], <-actual)
select {
case res := <-actual:
assert.Equal(expected[i], res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
}
func TestChannel_InviteOnly(t *testing.T) {
assert := assert.New(t)
var (
expected bool
actual chan bool
)
expected = true
actual = make(chan bool)
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("324", func(e *irc.Event) {
if strings.Contains(e.Arguments[2], "i") {
client2.Join("#inviteonly")
} else {
client1.Mode("#inviteonly")
}
})
client2.AddCallback("473", func(e *irc.Event) {
actual <- true
})
client2.AddCallback("JOIN", func(e *irc.Event) {
actual <- false
})
defer client1.Quit()
defer client2.Quit()
client1.Join("#inviteonly")
client1.Mode("#inviteonly", "+i")
client1.Mode("#inviteonly")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
@@ -171,15 +265,265 @@ func TestUser_PRIVMSG(t *testing.T) {
expected = "Hello World!"
actual = make(chan string)
clients["test1"].AddCallback("PRIVMSG", func(e *irc.Event) {
defer func() { done <- true }()
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("001", func(e *irc.Event) {
client1.Privmsg(client2.GetNick(), expected)
})
client1.AddCallback("PRIVMSG", func(e *irc.Event) {
actual <- e.Message()
})
time.AfterFunc(1*time.Second, func() { done <- true })
client.Privmsg("test1", expected)
<-done
client2.AddCallback("001", func(e *irc.Event) {
client2.Privmsg(client1.GetNick(), expected)
})
client2.AddCallback("PRIVMSG", func(e *irc.Event) {
actual <- e.Message()
})
assert.Equal(expected, <-actual)
defer client1.Quit()
defer client2.Quit()
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_PRIVMSG(t *testing.T) {
assert := assert.New(t)
var (
expected string
actual chan string
)
expected = "Hello World!"
actual = make(chan string)
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("JOIN", func(e *irc.Event) {
client1.Privmsg(e.Arguments[0], expected)
})
client2.AddCallback("JOIN", func(e *irc.Event) {
client2.Privmsg(e.Arguments[0], expected)
})
client1.AddCallback("PRIVMSG", func(e *irc.Event) {
actual <- e.Message()
})
client2.AddCallback("PRIVMSG", func(e *irc.Event) {
actual <- e.Message()
})
defer client1.Quit()
defer client2.Quit()
client1.Join("#channelprivmsg")
client2.Join("#channelprivmsg")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_NoExternal(t *testing.T) {
assert := assert.New(t)
var (
expected bool
actual chan bool
)
expected = true
actual = make(chan bool)
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("JOIN", func(e *irc.Event) {
channel := e.Arguments[0]
if channel == "#noexternal" {
if e.Nick == client1.GetNick() {
client2.Privmsg("#noexternal", "FooBar!")
} else {
assert.Fail(fmt.Sprintf("unexpected user %s joined %s", e.Nick, channel))
}
} else {
assert.Fail(fmt.Sprintf("unexpected channel %s", channel))
}
})
client2.AddCallback("PRIVMSG", func(e *irc.Event) {
if e.Arguments[0] == "#noexternal" {
actual <- false
}
})
client2.AddCallback("404", func(e *irc.Event) {
actual <- true
})
defer client1.Quit()
defer client2.Quit()
client1.Join("#noexternal")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_SetTopic_InvalidChannel(t *testing.T) {
assert := assert.New(t)
expected := true
actual := make(chan bool)
client1 := newClient(true)
defer client1.Quit()
client1.AddCallback("403", func(e *irc.Event) {
actual <- true
})
client1.SendRaw("TOPIC #invalidchannel :FooBar")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_SetTopic_NotOnChannel(t *testing.T) {
assert := assert.New(t)
expected := true
actual := make(chan bool)
client1 := newClient(true)
client2 := newClient(true)
defer client1.Quit()
defer client2.Quit()
client1.AddCallback("442", func(e *irc.Event) {
actual <- true
})
client2.AddCallback("JOIN", func(e *irc.Event) {
client1.SendRaw("TOPIC #notonchannel :FooBar")
})
client2.Join("#notonchannel")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_BadChannelKey(t *testing.T) {
assert := assert.New(t)
var (
expected bool
actual chan bool
)
expected = true
actual = make(chan bool)
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("324", func(e *irc.Event) {
if strings.Contains(e.Arguments[2], "k") {
client2.Join(e.Arguments[1])
} else {
client1.Mode("#badchannelkey")
}
})
client2.AddCallback("JOIN", func(e *irc.Event) {
if e.Nick == client2.GetNick() && e.Arguments[0] == "#badchannelkey" {
actual <- false
}
})
client2.AddCallback("475", func(e *irc.Event) {
actual <- true
})
defer client1.Quit()
defer client2.Quit()
client1.Join("#badchannelkey")
client1.Mode("#badchannelkey", "+k", "opensesame")
client1.Mode("#badchannelkey")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}
func TestChannel_GoodChannelKey(t *testing.T) {
assert := assert.New(t)
var (
expected bool
actual chan bool
)
expected = true
actual = make(chan bool)
client1 := newClient(true)
client2 := newClient(true)
client1.AddCallback("324", func(e *irc.Event) {
if strings.Contains(e.Arguments[2], "k") {
client2.SendRawf("JOIN %s :opensesame", e.Arguments[1])
} else {
client1.Mode("#goodchannelkey")
}
})
client2.AddCallback("JOIN", func(e *irc.Event) {
if e.Nick == client2.GetNick() && e.Arguments[0] == "#goodchannelkey" {
actual <- true
}
})
client2.AddCallback("475", func(e *irc.Event) {
actual <- false
})
defer client1.Quit()
defer client2.Quit()
client1.Join("#goodchannelkey")
client1.Mode("#goodchannelkey", "+k", "opensesame")
client1.Mode("#goodchannelkey")
select {
case res := <-actual:
assert.Equal(expected, res)
case <-time.After(TIMEOUT):
assert.Fail("timeout")
}
}

1
vendor/github.com/satori/go.uuid generated vendored Submodule