2018-05-21 16:36:45 +02:00
|
|
|
// Copyright 2018 Google LLC
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2021-02-20 00:41:10 +01:00
|
|
|
"context"
|
2018-05-21 16:36:45 +02:00
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2019-12-27 14:07:33 +01:00
|
|
|
|
|
|
|
irc "github.com/fluffle/goirc/client"
|
2018-05-21 16:36:45 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func makeTestIRCConfig(IRCPort int) *Config {
|
|
|
|
return &Config{
|
|
|
|
IRCNick: "foo",
|
|
|
|
IRCNickPass: "",
|
|
|
|
IRCHost: "127.0.0.1",
|
|
|
|
IRCPort: IRCPort,
|
|
|
|
IRCUseSSL: false,
|
|
|
|
IRCChannels: []IRCChannel{
|
|
|
|
IRCChannel{Name: "#foo"},
|
|
|
|
IRCChannel{Name: "#bar"},
|
|
|
|
IRCChannel{Name: "#baz"},
|
|
|
|
},
|
2020-01-25 19:03:13 +01:00
|
|
|
UsePrivmsg: false,
|
2018-05-21 16:36:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
func makeTestNotifier(t *testing.T, config *Config) (*IRCNotifier, chan AlertMsg, context.CancelFunc, *sync.WaitGroup) {
|
2021-03-25 23:58:27 +01:00
|
|
|
fakeDelayerMaker := &FakeDelayerMaker{}
|
2020-01-25 17:42:59 +01:00
|
|
|
alertMsgs := make(chan AlertMsg)
|
2021-02-20 00:41:10 +01:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
stopWg := sync.WaitGroup{}
|
|
|
|
stopWg.Add(1)
|
2021-03-25 23:58:27 +01:00
|
|
|
notifier, err := NewIRCNotifier(ctx, &stopWg, config, alertMsgs, fakeDelayerMaker)
|
2018-05-21 16:36:45 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(fmt.Sprintf("Could not create IRC notifier: %s", err))
|
|
|
|
}
|
|
|
|
notifier.Client.Config().Flood = true
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
return notifier, alertMsgs, cancel, &stopWg
|
2018-05-21 16:36:45 +02:00
|
|
|
}
|
|
|
|
|
2020-11-05 11:05:15 +01:00
|
|
|
func TestServerPassword(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
|
|
|
config.IRCHostPass = "hostsecret"
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, _ := makeTestNotifier(t, config)
|
2020-11-05 11:05:15 +01:00
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2020-11-05 11:05:15 +01:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"PASS hostsecret",
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Did not send IRC server password")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 16:36:45 +02:00
|
|
|
func TestSendAlertOnPreJoinedChannel(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
testChannel := "#foo"
|
|
|
|
testMessage := "test message"
|
|
|
|
|
|
|
|
// Send the alert after configured channels have joined, to ensure we
|
|
|
|
// check for no re-join attempt.
|
|
|
|
joinedHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
if line.Args[0] == testChannel {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinedHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
server.SetHandler("JOIN", nil)
|
|
|
|
|
|
|
|
noticeHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
testStep.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("NOTICE", noticeHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
2020-01-25 17:42:59 +01:00
|
|
|
alertMsgs <- AlertMsg{Channel: testChannel, Alert: testMessage}
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"NOTICE #foo :test message",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Alert not sent correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 19:03:13 +01:00
|
|
|
func TestUsePrivmsgToSendAlertOnPreJoinedChannel(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
|
|
|
config.UsePrivmsg = true
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config)
|
2020-01-25 19:03:13 +01:00
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
testChannel := "#foo"
|
|
|
|
testMessage := "test message"
|
|
|
|
|
|
|
|
// Send the alert after configured channels have joined, to ensure we
|
|
|
|
// check for no re-join attempt.
|
|
|
|
joinedHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
if line.Args[0] == testChannel {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinedHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
server.SetHandler("JOIN", nil)
|
|
|
|
|
|
|
|
privmsgHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
testStep.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("PRIVMSG", privmsgHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
alertMsgs <- AlertMsg{Channel: testChannel, Alert: testMessage}
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2020-01-25 19:03:13 +01:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"PRIVMSG #foo :test message",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Alert not sent correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 16:36:45 +02:00
|
|
|
func TestSendAlertAndJoinChannel(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
testChannel := "#foobar"
|
|
|
|
testMessage := "test message"
|
|
|
|
|
|
|
|
// Send the alert after configured channels have joined, to ensure log
|
|
|
|
// ordering.
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
server.SetHandler("JOIN", nil)
|
|
|
|
|
|
|
|
noticeHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
testStep.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("NOTICE", noticeHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
2020-01-25 17:42:59 +01:00
|
|
|
alertMsgs <- AlertMsg{Channel: testChannel, Alert: testMessage}
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
// #foobar joined before sending message
|
|
|
|
"JOIN #foobar",
|
|
|
|
"NOTICE #foobar :test message",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Alert not sent correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSendAlertDisconnected(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, alertMsgs, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep, holdUserStep sync.WaitGroup
|
|
|
|
|
|
|
|
testChannel := "#foo"
|
|
|
|
disconnectedTestMessage := "disconnected test message"
|
|
|
|
connectedTestMessage := "connected test message"
|
|
|
|
|
|
|
|
// First send an alert while the session is not established.
|
|
|
|
testStep.Add(1)
|
|
|
|
holdUserStep.Add(1)
|
|
|
|
holdUser := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
log.Printf("=Server= Wait before completing session")
|
|
|
|
testStep.Wait()
|
|
|
|
log.Printf("=Server= Completing session")
|
|
|
|
holdUserStep.Done()
|
2019-12-27 14:07:33 +01:00
|
|
|
return hUSER(conn, line)
|
2018-05-21 16:36:45 +02:00
|
|
|
}
|
|
|
|
server.SetHandler("USER", holdUser)
|
|
|
|
|
|
|
|
go notifier.Run()
|
|
|
|
|
2021-02-20 11:17:32 +01:00
|
|
|
// Alert channels is not consumed while disconnected
|
|
|
|
select {
|
|
|
|
case alertMsgs <- AlertMsg{Channel: testChannel, Alert: disconnectedTestMessage}:
|
|
|
|
t.Error("Alert consumed while disconnected")
|
|
|
|
default:
|
|
|
|
}
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
testStep.Done()
|
|
|
|
holdUserStep.Wait()
|
|
|
|
|
|
|
|
// Make sure session is established by checking that pre-joined
|
|
|
|
// channels are there.
|
|
|
|
testStep.Add(1)
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
// Now send and wait until a notice has been received.
|
|
|
|
testStep.Add(1)
|
|
|
|
noticeHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
testStep.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("NOTICE", noticeHandler)
|
|
|
|
|
2020-01-25 17:42:59 +01:00
|
|
|
alertMsgs <- AlertMsg{Channel: testChannel, Alert: connectedTestMessage}
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
// Only message sent while being connected is received.
|
|
|
|
"NOTICE #foo :connected test message",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Alert not sent correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReconnect(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
// Wait until the last pre-joined channel is seen.
|
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
// Simulate disconnection.
|
|
|
|
testStep.Add(1)
|
|
|
|
server.Client.Close()
|
|
|
|
|
|
|
|
// Wait again until the last pre-joined channel is seen.
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
// Commands from first connection
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
// Commands from reconnection
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Reconnection did not happen correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestConnectErrorRetry(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
|
|
|
// Attempt SSL handshake. The server does not support it, resulting in
|
|
|
|
// a connection error.
|
|
|
|
config.IRCUseSSL = true
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, _ := makeTestNotifier(t, config)
|
2021-02-24 20:45:52 +01:00
|
|
|
// Pilot reconnect attempts via backoff delay to prevent race
|
|
|
|
// conditions in the test while we change the components behavior on
|
|
|
|
// the fly.
|
|
|
|
delayer := notifier.BackoffCounter.(*FakeDelayer)
|
|
|
|
delayer.DelayOnChan = true
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep, joinStep sync.WaitGroup
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
earlyHandler := func() {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
server.SetCloseEarly(earlyHandler)
|
|
|
|
|
|
|
|
go notifier.Run()
|
|
|
|
|
2021-02-24 20:45:52 +01:00
|
|
|
delayer.StopDelay <- true
|
|
|
|
|
2018-05-21 16:36:45 +02:00
|
|
|
testStep.Wait()
|
|
|
|
|
|
|
|
// We have caused a connection failure, now check for a reconnection
|
|
|
|
notifier.Client.Config().SSL = false
|
|
|
|
joinStep.Add(1)
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
joinStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
server.SetCloseEarly(nil)
|
|
|
|
|
2021-02-24 20:45:52 +01:00
|
|
|
delayer.StopDelay <- true
|
|
|
|
|
2018-05-21 16:36:45 +02:00
|
|
|
joinStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Reconnection did not happen correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIdentify(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
|
|
|
config.IRCNickPass = "nickpassword"
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
notifier.NickservDelayWait = 0 * time.Second
|
|
|
|
|
|
|
|
var testStep sync.WaitGroup
|
|
|
|
|
|
|
|
// Wait until the last pre-joined channel is seen (joining happens
|
|
|
|
// after identification).
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"PRIVMSG NickServ :IDENTIFY nickpassword",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Identification did not happen correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGhostAndIdentify(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
|
|
|
config.IRCNickPass = "nickpassword"
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, _ := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
notifier.NickservDelayWait = 0 * time.Second
|
|
|
|
|
|
|
|
var testStep, usedNick, unregisteredNickHandler sync.WaitGroup
|
|
|
|
|
|
|
|
// Trigger 433 for first nick
|
|
|
|
usedNick.Add(1)
|
|
|
|
unregisteredNickHandler.Add(1)
|
|
|
|
nickHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
2019-12-27 14:07:33 +01:00
|
|
|
var err error
|
2018-05-21 16:36:45 +02:00
|
|
|
if line.Args[0] == "foo" {
|
2019-12-27 14:07:33 +01:00
|
|
|
_, err = conn.WriteString(":example.com 433 * foo :nick in use\n")
|
2018-05-21 16:36:45 +02:00
|
|
|
}
|
|
|
|
usedNick.Done()
|
|
|
|
unregisteredNickHandler.Wait()
|
2019-12-27 14:07:33 +01:00
|
|
|
return err
|
2018-05-21 16:36:45 +02:00
|
|
|
}
|
|
|
|
server.SetHandler("NICK", nickHandler)
|
|
|
|
|
|
|
|
// Wait until the last pre-joined channel is seen (joining happens
|
|
|
|
// after identification).
|
|
|
|
joinHandler := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
// #baz is configured as the last channel to pre-join
|
|
|
|
if line.Args[0] == "#baz" {
|
|
|
|
testStep.Done()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("JOIN", joinHandler)
|
|
|
|
|
|
|
|
testStep.Add(1)
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
usedNick.Wait()
|
|
|
|
server.SetHandler("NICK", nil)
|
|
|
|
unregisteredNickHandler.Done()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"NICK foo^",
|
|
|
|
"PRIVMSG NickServ :GHOST foo nickpassword",
|
|
|
|
"NICK foo",
|
|
|
|
"PRIVMSG NickServ :IDENTIFY nickpassword",
|
|
|
|
"JOIN #foo",
|
|
|
|
"JOIN #bar",
|
|
|
|
"JOIN #baz",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Ghosting did not happen correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStopRunningWhenHalfConnected(t *testing.T) {
|
|
|
|
server, port := makeTestServer(t)
|
|
|
|
config := makeTestIRCConfig(port)
|
2021-02-20 00:41:10 +01:00
|
|
|
notifier, _, cancel, stopWg := makeTestNotifier(t, config)
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
var testStep, holdQuitWait sync.WaitGroup
|
|
|
|
|
|
|
|
// Send a StopRunning request while the client is connected but the
|
|
|
|
// session is not up
|
|
|
|
testStep.Add(1)
|
|
|
|
holdUser := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
log.Printf("=Server= NOT completing session")
|
|
|
|
testStep.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("USER", holdUser)
|
|
|
|
|
|
|
|
// Ignore quit, but wait for it to have deterministic test commands
|
|
|
|
holdQuitWait.Add(1)
|
|
|
|
holdQuit := func(conn *bufio.ReadWriter, line *irc.Line) error {
|
|
|
|
log.Printf("=Server= Ignoring quit")
|
|
|
|
holdQuitWait.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
server.SetHandler("QUIT", holdQuit)
|
|
|
|
|
|
|
|
go notifier.Run()
|
|
|
|
|
|
|
|
testStep.Wait()
|
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
cancel()
|
2018-05-21 16:36:45 +02:00
|
|
|
|
2021-02-20 00:41:10 +01:00
|
|
|
stopWg.Wait()
|
2018-05-21 16:36:45 +02:00
|
|
|
|
|
|
|
holdQuitWait.Wait()
|
|
|
|
|
|
|
|
// Client has left, cleanup the server side before stopping
|
|
|
|
server.Client.Close()
|
|
|
|
|
|
|
|
server.Stop()
|
|
|
|
|
|
|
|
expectedCommands := []string{
|
|
|
|
"NICK foo",
|
|
|
|
"USER foo 12 * :",
|
|
|
|
"QUIT :see ya",
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedCommands, server.Log) {
|
|
|
|
t.Error("Alert not sent correctly. Received commands:\n", strings.Join(server.Log, "\n"))
|
|
|
|
}
|
|
|
|
}
|