Skip to content

Commit

Permalink
Simplify IRC, more IT
Browse files Browse the repository at this point in the history
  • Loading branch information
Tillerino committed Apr 15, 2023
1 parent ca96c83 commit 48839d7
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 44 deletions.
6 changes: 6 additions & 0 deletions tillerinobot-irc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.kitteh.irc</groupId>
<artifactId>client-lib</artifactId>
<version>8.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ class IrcHooks extends CoreHooks {
private final AtomicLong lastSerial;
private final AtomicLong lastListTime;

private final Queue<ServerResponseEvent> userListEvents = new LinkedList<>();

@SuppressFBWarnings(value = "EI_EXPOSE_REP2")
public IrcHooks(GameChatEventConsumer downStream,
GameChatClientMetrics botInfo,
Expand Down Expand Up @@ -157,14 +155,6 @@ public void onEvent(Event event) throws Exception {

super.onEvent(event);
}

if (event instanceof PrivateMessageEvent || event instanceof ActionEvent) {
// we want to process these on events which are regular but not too frequent to clog up things.
ServerResponseEvent listEvent = userListEvents.poll();
if (listEvent != null) {
processUserListEvent(listEvent);
}
}
}

@Override
Expand All @@ -190,34 +180,32 @@ public void onJoin(JoinEvent event) throws Exception {
@Override
public void onServerResponse(ServerResponseEvent event) throws Exception {
if(event.getCode() == 353) {
// these come in bursts and we don't want them to clog up our processing pipeline.
// especially when going online, this is awkward since the bot doesn't answer for a while.
// since the original event is the most compact form for this, we store it for later processing.
userListEvents.add(event);
processUserListEvent(event);
} else {
super.onServerResponse(event);
}
}

@SuppressFBWarnings("TQ")
private void processUserListEvent(ServerResponseEvent event) throws InterruptedException {
private void processUserListEvent(ServerResponseEvent<?> event) throws InterruptedException {
ImmutableList<String> parsedResponse = event.getParsedResponse();

String[] usernames = parsedResponse.get(parsedResponse.size() - 1).split(" ");

for (int i = 0; i < usernames.length; i++) {
try (MdcAttributes mdc = MdcUtils.with(MdcUtils.MDC_EVENT, lastSerial.getAndIncrement())) {
String nick = usernames[i];

if (nick.startsWith("@") || nick.startsWith("+"))
if (nick.startsWith("@") || nick.startsWith("+")) {
nick = nick.substring(1);

}
if (nick.equals(event.getBot().getNick())) {
continue;
}

downStream.onEvent(new Sighted(MdcUtils.getLong(MdcUtils.MDC_EVENT).orElseThrow(IllegalStateException::new),
nick, timestamp(event)));
}
}

System.out.println("processed user list event " + userListEvents.size() + " remaining");
}

@SuppressFBWarnings("TQ")
Expand Down
1 change: 1 addition & 0 deletions tillerinobot-irc/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
<Logger name="io.undertow.request.error-response" level="info"/>
</Loggers>
</Configuration>
Original file line number Diff line number Diff line change
@@ -1,36 +1,150 @@
package org.tillerino.ppaddict.chat.irc;

import org.awaitility.Awaitility;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.tillerino.ppaddict.chat.irc.IrcContainer.TILLERINOBOT_IRC;
import static org.tillerino.ppaddict.chat.irc.NgircdContainer.NGIRCD;
import static org.tillerino.ppaddict.rabbit.RabbitMqContainer.RABBIT_MQ;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.tillerino.ppaddict.rabbit.RabbitMqContainer;
import org.junit.rules.TestName;
import org.kitteh.irc.client.library.Client;
import org.kitteh.irc.client.library.Client.Builder.Server.SecurityType;
import org.kitteh.irc.client.library.exception.KittehNagException;
import org.tillerino.ppaddict.chat.GameChatEvent;
import org.tillerino.ppaddict.chat.Joined;
import org.tillerino.ppaddict.chat.PrivateAction;
import org.tillerino.ppaddict.chat.PrivateMessage;
import org.tillerino.ppaddict.chat.Sighted;
import org.tillerino.ppaddict.rabbit.RabbitMqConfiguration;
import org.tillerino.ppaddict.rabbit.RemoteEventQueue;
import org.tillerino.ppaddict.rabbit.RemoteResponseQueue;

import com.rabbitmq.client.Connection;

import io.restassured.RestAssured;

public class BotIT {
@Rule
public final TestName testName = new TestName();

private Connection connection;
private List<GameChatEvent> incoming = Collections.synchronizedList(new ArrayList<>());
private RemoteResponseQueue outgoingQueue;
private Client kitteh;

@Before
public void setUp() throws Exception {
RabbitMqContainer.RABBIT_MQ.start();
NgircdContainer.NGIRCD.start();
IrcContainer.TILLERINOBOT_IRC.start();
RestAssured.baseURI = "http://" + IrcContainer.TILLERINOBOT_IRC.getHost() + ":"
+ IrcContainer.TILLERINOBOT_IRC.getMappedPort(8080) + "/";
Awaitility.await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));
System.out.println("Running " + testName.getMethodName());
RABBIT_MQ.start();
NGIRCD.start();
TILLERINOBOT_IRC.start();

RestAssured.baseURI = "http://" + TILLERINOBOT_IRC.getHost() + ":"
+ TILLERINOBOT_IRC.getMappedPort(8080) + "/";
await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));

kitteh = Client.builder()
.nick("test")
.server()
.host(NGIRCD.getHost())
.port(NGIRCD.getMappedPort(6667), SecurityType.INSECURE)
.then().listeners()
.exception(e -> {
if (e instanceof KittehNagException) {
return;
}
e.printStackTrace();
})
.then().build();

connection = RabbitMqConfiguration.connectionFactory(RABBIT_MQ.getHost(), RABBIT_MQ.getAmqpPort())
.newConnection("test");
RemoteEventQueue incomingQueue = RabbitMqConfiguration.externalEventQueue(connection);
incomingQueue.setup();
incomingQueue.subscribe(incoming::add);
outgoingQueue = RabbitMqConfiguration.responseQueue(connection);
outgoingQueue.setup();
}

@After
public void tearDown() throws Exception {
if (connection.isOpen()) {
connection.close();
}
kitteh.shutdown();
}

@Test
public void livenessReactsToRabbit() throws Exception {
RabbitMqContainer.RABBIT_MQ.stop();
Awaitility.await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(503));
RabbitMqContainer.RABBIT_MQ.start();
Awaitility.await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));
RABBIT_MQ.stop();
await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(503));
RABBIT_MQ.start();
await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));
}

@Test
public void livenessReactsToNgircd() throws Exception {
NgircdContainer.NGIRCD.stop();
Awaitility.await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(503));
NgircdContainer.NGIRCD.start();
Awaitility.await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));
NGIRCD.stop();
await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(503));
NGIRCD.start();
await().untilAsserted(() -> RestAssured.when().get("/live").then().statusCode(200));
}

@Test
public void incomingPrivateMessage() throws Exception {
kitteh.connect();
kitteh.sendMessage("tillerinobot", "hello");

await().untilAsserted(() -> assertThat(incoming)
.singleElement()
.isInstanceOfSatisfying(PrivateMessage.class, message -> {
assertThat(message.getNick()).isEqualTo("test");
assertThat(message.getMessage()).isEqualTo("hello");
}));
}

@Test
public void incomingPrivateAction() throws Exception {
kitteh.connect();
kitteh.sendMessage("tillerinobot", "\u0001ACTION hello\u0001");

await().untilAsserted(() -> assertThat(incoming)
.singleElement()
.isInstanceOfSatisfying(PrivateAction.class, message -> {
assertThat(message.getNick()).isEqualTo("test");
assertThat(message.getAction()).isEqualTo("hello");
}));
}

@Test
public void joiningChannelResultsInJoinedEvent() throws Exception {
kitteh.connect();
kitteh.addChannel("#osu");
await().untilAsserted(() -> assertThat(incoming)
.singleElement()
.isInstanceOfSatisfying(Joined.class, message -> {
assertThat(message.getNick()).isEqualTo("test");
}));
}

@Test
public void startingTillerinobotAfterJoiningServerResultsInSightedEvent() throws Exception {
TILLERINOBOT_IRC.stop();
kitteh.connect();
kitteh.addChannel("#osu");
TILLERINOBOT_IRC.start();
await().untilAsserted(() -> assertThat(incoming)
.singleElement()
.isInstanceOfSatisfying(Sighted.class, message -> {
assertThat(message.getNick()).isEqualTo("test");
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,11 @@ public void testListingOnlineUsers() throws Exception {
when(event.getParsedResponse()).thenReturn(ImmutableList.of("stuff", "nick1 @nick2 +nick3"));
when(event.getCode()).thenReturn(353);
irc.onEvent(event);
verifyNoInteractions(eventHandler);
irc.onEvent(mockPrivateMessage("bump"));
// event 0 was original server event
// event 1 was bump
verify(eventHandler).onEvent(new Sighted(12_302, "nick1", 123));
verify(eventHandler).onEvent(new Sighted(12_303, "nick2", 123));
verify(eventHandler).onEvent(new Sighted(12_304, "nick3", 123));
// event 1 is ours
verify(eventHandler).onEvent(new Sighted(12_301, "nick1", 123));
verify(eventHandler).onEvent(new Sighted(12_302, "nick2", 123));
verify(eventHandler).onEvent(new Sighted(12_303, "nick3", 123));
}

@Test
Expand Down
2 changes: 0 additions & 2 deletions tillerinobot-irc/src/test/resources/log4j2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
<PatternLayout
pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<TestAppender name="Test" />
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="Test" />
</Root>
<Logger name="org.pircbotx" level="error"/>
<Logger name="org.eclipse.jetty" level="info"/>
Expand Down

0 comments on commit 48839d7

Please sign in to comment.