func TestParseLine_privmsg(t *testing.T) { common.SetGlogFlags() line1 := ":[email protected] PRIVMSG #linode :totally" line, err := parseLine(line1) if err != nil { t.Error("parseLine error: ", err) } if line.Command != "PRIVMSG" { t.Error("Command incorrect. Got", line.Command) } if line.Host != "[email protected]" { t.Error("Host incorrect. Got", line.Host) } if line.User != "rnowak" { t.Error("User incorrect. Got", line.User) } if line.Channel != "#linode" { t.Error("Channel incorrect. Got", line.Channel) } if line.Content != "totally" { t.Error("Content incorrect. Got", line.Content) } }
func TestParseLine_list(t *testing.T) { common.SetGlogFlags() line1 := ":oxygen.oftc.net 322 graham_king #linode 412 :Linode Community Support | http://www.linode.com/ | Linodes in Asia-Pacific! - http://bit.ly/ooBzhV" line, err := parseLine(line1) if err != nil { t.Error("parseLine error: ", err) } if line.Command != "322" { t.Error("Command incorrect. Got", line.Command) } if line.Host != "oxygen.oftc.net" { t.Error("Host incorrect. Got", line.Host) } if line.Channel != "#linode" { t.Error("Channel incorrect. Got", line.Channel) } if !strings.Contains(line.Content, "Community Support") { t.Error("Content incorrect. Got", line.Content) } if line.Args[2] != "412" { t.Error("Args incorrect. Got", line.Args) } }
func TestSplitChannels(t *testing.T) { common.SetGlogFlags() input := "#aone, #btwo, #cthree" result := splitChannels(input) if len(result) != 3 || result[2] != "#cthree" { t.Error("Error. Splitting", input, "gave", result) } }
func TestToUnicodeUTF8(t *testing.T) { common.SetGlogFlags() msg := "ελληνικά" result := toUnicode([]byte(msg)) if result != msg { t.Error("UTF8 error.", msg, "became", result) } }
func TestToUnicodeLatin1(t *testing.T) { common.SetGlogFlags() msg := "âôé" latin1_bytes := []byte{0xe2, 0xf4, 0xe9} result := toUnicode(latin1_bytes) if result != msg { t.Error("ISO-8859-1 error.", msg, "became", result) } }
func TestParseLine_quit(t *testing.T) { common.SetGlogFlags() line1 := ":[email protected] QUIT :" line, err := parseLine(line1) if err != nil { t.Error("parse line error:", err) } if line.Command != "QUIT" { t.Error("Command incorrect. Got", line) } }
func TestParseLine_part(t *testing.T) { common.SetGlogFlags() line1 := ":[email protected] PART #lincolnloop-internal" line, err := parseLine(line1) if err != nil { t.Error("parse line error:", err) } if line.Command != "PART" { t.Error("Command incorrect. Got", line) } if line.Channel != "#lincolnloop-internal" { t.Error("Channel incorrect. Got", line.Channel) } }
// Test joining additional channels func TestUpdate(t *testing.T) { common.SetGlogFlags() glog.Infoln("[DEBUG] starting TestUpdate") fromServer := make(chan *line.Line) receiver := make(chan string, 10) mockSocket := common.MockSocket{Receiver: receiver} channels := make([]*common.Channel, 0, 2) channel := common.Channel{Name: "#test", Fingerprint: "uuid-string"} channels = append(channels, &channel) chatbot := &ircBot{ id: 99, address: "localhost", nick: "test", realname: "Unit Test", password: "******", serverIdentifier: "localhost.test1", fromServer: fromServer, channels: channels, rateLimit: time.Second, pingResponse: make(chan struct{}, 10), // HACK: This is to avoid the current deadlock sendQueue: make(chan []byte, 256), } chatbot.init(&mockSocket) conf := map[string]string{ "nick": "test", "password": "******", "server": "localhost"} channels = append(channels, &NEW_CHANNEL) newConfig := &common.BotConfig{Id: 1, Config: conf, Channels: channels} // TODO (yml) there is probably better than sleeping but we need to wait // until chatbot is fully ready time.Sleep(time.Second * 2) chatbot.Update(newConfig) isFound := false for received := range mockSocket.Receiver { glog.Infoln("[DEBUG] received", received) if strings.TrimSpace(received) == "JOIN "+NEW_CHANNEL.Credential() { isFound = true close(mockSocket.Receiver) } else if received == "JOIN #test" { t.Error("Should not rejoin channels already in, can cause flood") } } if !isFound { t.Error("Expected JOIN " + NEW_CHANNEL.Credential()) } }
func TestParseLine_welcome(t *testing.T) { common.SetGlogFlags() line1 := ":barjavel.freenode.net 001 graham_king :Welcome to the freenode Internet Relay Chat Network graham_king" line, err := parseLine(line1) if err != nil { t.Error("parseLine error: ", err) } if line.Command != "001" { t.Error("Command incorrect") } if line.Host != "barjavel.freenode.net" { t.Error("Host incorrect") } }
// Test sending messages too fast func TestFlood(t *testing.T) { common.SetGlogFlags() NUM := 5 fromServer := make(chan *line.Line) receivedCounter := make(chan bool) mockSocket := common.MockSocket{Counter: receivedCounter} channels := make([]*common.Channel, 1) channels = append(channels, &common.Channel{Name: "test", Fingerprint: "uuid-string"}) chatbot := &ircBot{ id: 99, address: "fakehost", nick: "test", realname: "Unit Test", password: "******", serverIdentifier: "localhost.test", rateLimit: time.Second, fromServer: fromServer, channels: channels, pingResponse: make(chan struct{}, 10), // HACK: This is to avoid the current deadlock sendQueue: make(chan []byte, 256), } chatbot.init(&mockSocket) startTime := time.Now() // Send the messages for i := 0; i < NUM; i++ { chatbot.Send("test", "Msg "+strconv.Itoa(i)) } // Wait for them to 'arrive' at the socket for numGot := 0; numGot <= NUM; numGot++ { <-receivedCounter } elapsed := int64(time.Since(startTime)) expected := int64((NUM-1)/4) * int64(chatbot.rateLimit) if elapsed < expected { t.Error("Flood prevention did not work") } }
func TestParseLine_353(t *testing.T) { common.SetGlogFlags() line1 := ":hybrid7.debian.local 353 botbot = #test :@botbot graham_king" line, err := parseLine(line1) if err != nil { t.Error("parse line error:", err) } if line.Command != "353" { t.Error("Command incorrect. Got", line) } if line.Channel != "#test" { t.Error("Channel incorrect. Got", line.Channel) } if line.Content != "@botbot graham_king" { t.Error("Content incorrect. Got", line.Content) } }
func TestParseLine_pm(t *testing.T) { common.SetGlogFlags() line1 := ":[email protected] PRIVMSG botbotme :hello" line, err := parseLine(line1) if err != nil { t.Error("parseLine error: ", err) } if line.Command != "PRIVMSG" { t.Error("Command incorrect. Got", line.Command) } if line.Channel != "botbotme" { t.Error("Channel incorrect. Got", line.Channel) } if line.Content != "hello" { t.Error("Content incorrect. Got", line.Content) } }
// A serious integration test for BotBot. // This covers BotBot, the IRC code, and the dispatcher. func TestBotBotIRC(t *testing.T) { common.SetGlogFlags() // Create a mock storage with configuration in it storage := common.NewMockStorage(SERVER_PORT) // Create a mock queue to gather BotBot output queue := common.NewMockQueue() // Start a Mock IRC server, and gather writes to it server := common.NewMockIRCServer(TEST_MSG, SERVER_PORT) go server.Run(t) // Run BotBot time.Sleep(time.Second) // Sleep of one second to avoid the 5s backoff botbot := NewBotBot(storage, queue) go botbot.listen("testcmds") go botbot.mainLoop() waitForServer(server, 4) // this sleep allow us to keep the answer in the right order time.Sleep(time.Second) // Test sending a reply - should probably be separate test queue.ReadChannel <- "WRITE 1 #unit I am a plugin response" waitForServer(server, 6) tries := 0 queue.RLock() q := queue.Got["q"] queue.RUnlock() for len(q) < 4 && tries < 4 { queue.RLock() q = queue.Got["q"] queue.RUnlock() glog.V(4).Infoln("[Debug] queue.Got[\"q\"]", len(q), "/", 4, q) time.Sleep(time.Second) tries++ } checkContains(q, TEST_MSG, t) // Check IRC server expectations if server.GotLength() != 6 { t.Fatal("Expected exactly 6 IRC messages from the bot. Got ", server.GotLength()) } glog.Infoln("[Debug] server.Got", server.Got) expect := []string{"PING", "USER", "NICK", "NickServ", "JOIN", "PRIVMSG"} for i := 0; i < 5; i++ { if !strings.Contains(string(server.Got[i]), expect[i]) { t.Error("Line ", i, " did not contain ", expect[i], ". It is: ", server.Got[i]) } } // test shutdown - should probably be separate test botbot.shutdown() tries = 0 val := 5 for len(q) < val && tries < val { queue.RLock() q = queue.Got["q"] queue.RUnlock() glog.V(4).Infoln("[Debug] queue.Got[\"q\"]", len(q), "/", val, q) time.Sleep(time.Second) tries++ } queue.RLock() checkContains(queue.Got["q"], "SHUTDOWN", t) queue.RUnlock() }