From 9af8dfb46d25bb6263fc26a7a7ea827691b2b506 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 2 Jun 2024 23:28:46 -0400 Subject: [PATCH 01/30] add various channel mode tests --- irctest/server_tests/chmodes/modeis.py | 59 +++++++++++++++++++ irctest/server_tests/chmodes/operator.py | 73 ++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 irctest/server_tests/chmodes/modeis.py create mode 100644 irctest/server_tests/chmodes/operator.py diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py new file mode 100644 index 00000000..1a618e35 --- /dev/null +++ b/irctest/server_tests/chmodes/modeis.py @@ -0,0 +1,59 @@ +""" +Test RPL_CHANNELMODEIS and RPL_CHANNELCREATED as responses to +`MODE #channel`: + + +""" + +from irctest import cases +from irctest.numerics import RPL_CHANNELMODEIS, RPL_CHANNELCREATED +from irctest.patma import ANYSTR + + +class RplChannelModeIsTestCase(cases.BaseServerTestCase): + @cases.mark_specifications("Modern") + def testChannelModeIs(self): + self.connectClient("chanop", name="chanop") + self.joinChannel("chanop", "#chan") + # i, n, and t are specified by RFC1459; some of them may be on by default, + # but after this, at least those three should be enabled: + self.sendLine("chanop", "MODE #chan +int") + self.getMessages("chanop") + + self.sendLine("chanop", "MODE #chan") + messages = self.getMessages("chanop") + self.assertLessEqual( + {RPL_CHANNELMODEIS, RPL_CHANNELCREATED}, {msg.command for msg in messages} + ) + for message in messages: + if message.command == RPL_CHANNELMODEIS: + self.assertMessageMatch( + message, + command=RPL_CHANNELMODEIS, + params=["chanop", "#chan", ANYSTR], + ) + final_param = message.params[2] + self.assertEqual(final_param[0], "+") + enabled_modes = list(final_param[1:]) + break + + # remove all the modes listed by RPL_CHANNELMODEIS + self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") + response = self.getMessage("chanop") + self.assertMessageMatch(response, command="MODE", params=["#chan", ANYSTR]) + self.assertEqual(response.params[1][0], "-") + self.assertEqual(set(response.params[1][1:]), set(enabled_modes)) + + self.sendLine("chanop", "MODE #chan") + messages = self.getMessages("chanop") + self.assertLessEqual( + {RPL_CHANNELMODEIS, RPL_CHANNELCREATED}, {msg.command for msg in messages} + ) + # all modes have been disabled; the correct representation of this is `+` + for message in messages: + if message.command == RPL_CHANNELMODEIS: + self.assertMessageMatch( + message, + command=RPL_CHANNELMODEIS, + params=["chanop", "#chan", "+"], + ) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py new file mode 100644 index 00000000..351bec74 --- /dev/null +++ b/irctest/server_tests/chmodes/operator.py @@ -0,0 +1,73 @@ +""" +Test various error and success cases around the channel operator mode: + + +""" + +from irctest import cases +from irctest.numerics import ( + ERR_CHANOPRIVSNEEDED, + ERR_USERNOTINCHANNEL, + ERR_NOSUCHNICK, + ERR_NOSUCHCHANNEL, + ERR_NOTONCHANNEL, +) + + +class ChannelOperatorModeTestCase(cases.BaseServerTestCase): + @cases.mark_specifications("RFC1459") + def testChannelOperatorMode(self): + self.connectClient("chanop", name="chanop") + self.joinChannel("chanop", "#chan") + + self.connectClient("unprivileged", name="unprivileged") + self.joinChannel("unprivileged", "#chan") + self.getMessages("chanop") + + self.connectClient("unrelated", name="unrelated") + self.joinChannel("unrelated", "#unrelated") + + self.sendLine("unprivileged", "MODE #chan +o unprivileged") + messages = self.getMessages("unprivileged") + self.assertEqual(len(messages), 1) + self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) + + self.sendLine("chanop", "MODE #chan +o unrelated") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) + + self.sendLine("chanop", "MODE #nonexistentchan +o chanop") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_CHANOPRIVSNEEDED]) + + self.sendLine("chanop", "MODE #nonexistentchan +o nonexistentnick") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn( + messages[0].command, + [ERR_NOSUCHCHANNEL, ERR_NOTONCHANNEL, ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL], + ) + + self.sendLine("chanop", "MODE #unrelated +o chanop") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + + # test an actually successful mode grant + self.sendLine("chanop", "MODE #chan +o unprivileged") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertMessageMatch( + messages[0], + command="MODE", + params=["#chan", "+o", "unprivileged"], + ) + messages = self.getMessages("unprivileged") + self.assertEqual(len(messages), 1) + self.assertMessageMatch( + messages[0], + command="MODE", + params=["#chan", "+o", "unprivileged"], + ) From b37f3204ce42089279b0250877090e59fe06fdf1 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 2 Jun 2024 23:32:21 -0400 Subject: [PATCH 02/30] fix isort --- irctest/server_tests/chmodes/modeis.py | 2 +- irctest/server_tests/chmodes/operator.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 1a618e35..422dad8c 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -6,7 +6,7 @@ """ from irctest import cases -from irctest.numerics import RPL_CHANNELMODEIS, RPL_CHANNELCREATED +from irctest.numerics import RPL_CHANNELCREATED, RPL_CHANNELMODEIS from irctest.patma import ANYSTR diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 351bec74..900ffa03 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -7,10 +7,10 @@ from irctest import cases from irctest.numerics import ( ERR_CHANOPRIVSNEEDED, - ERR_USERNOTINCHANNEL, - ERR_NOSUCHNICK, ERR_NOSUCHCHANNEL, + ERR_NOSUCHNICK, ERR_NOTONCHANNEL, + ERR_USERNOTINCHANNEL, ) From 7536ae5a038cd3cc8815912bf72a0d1942f4b2cf Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 2 Jun 2024 23:48:56 -0400 Subject: [PATCH 03/30] comply with ngircd nick limit --- irctest/server_tests/chmodes/operator.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 900ffa03..17dedd12 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -20,19 +20,19 @@ def testChannelOperatorMode(self): self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") - self.connectClient("unprivileged", name="unprivileged") - self.joinChannel("unprivileged", "#chan") + self.connectClient("unprivd", name="unprivd") + self.joinChannel("unprivd", "#chan") self.getMessages("chanop") - self.connectClient("unrelated", name="unrelated") - self.joinChannel("unrelated", "#unrelated") + self.connectClient("otherguy", name="otherguy") + self.joinChannel("otherguy", "#otherguy") - self.sendLine("unprivileged", "MODE #chan +o unprivileged") - messages = self.getMessages("unprivileged") + self.sendLine("unprivd", "MODE #chan +o unprivd") + messages = self.getMessages("unprivd") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) - self.sendLine("chanop", "MODE #chan +o unrelated") + self.sendLine("chanop", "MODE #chan +o otherguy") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) @@ -50,24 +50,24 @@ def testChannelOperatorMode(self): [ERR_NOSUCHCHANNEL, ERR_NOTONCHANNEL, ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL], ) - self.sendLine("chanop", "MODE #unrelated +o chanop") + self.sendLine("chanop", "MODE #otherguy +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) # test an actually successful mode grant - self.sendLine("chanop", "MODE #chan +o unprivileged") + self.sendLine("chanop", "MODE #chan +o unprivd") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch( messages[0], command="MODE", - params=["#chan", "+o", "unprivileged"], + params=["#chan", "+o", "unprivd"], ) - messages = self.getMessages("unprivileged") + messages = self.getMessages("unprivd") self.assertEqual(len(messages), 1) self.assertMessageMatch( messages[0], command="MODE", - params=["#chan", "+o", "unprivileged"], + params=["#chan", "+o", "unprivd"], ) From 14524bbad0f48efbcc8aa0475ee4c75b7c6028b2 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 2 Jun 2024 23:51:57 -0400 Subject: [PATCH 04/30] strengthen one of the error cases as per Modern --- irctest/server_tests/chmodes/operator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 17dedd12..2332d667 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -15,7 +15,7 @@ class ChannelOperatorModeTestCase(cases.BaseServerTestCase): - @cases.mark_specifications("RFC1459") + @cases.mark_specifications("Modern") def testChannelOperatorMode(self): self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") @@ -40,7 +40,9 @@ def testChannelOperatorMode(self): self.sendLine("chanop", "MODE #nonexistentchan +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) - self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_CHANOPRIVSNEEDED]) + # Modern: "If is a channel that does not exist on the network, + # the ERR_NOSUCHCHANNEL (403) numeric is returned." + self.assertMessageMatch(messages[0], command=ERR_NOSUCHCHANNEL) self.sendLine("chanop", "MODE #nonexistentchan +o nonexistentnick") messages = self.getMessages("chanop") From 87a3a9ca70759cf1da6d7a7465cb3ac42e2e1eeb Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 00:23:52 -0400 Subject: [PATCH 05/30] fix 324 parameter assertion --- irctest/server_tests/chmodes/modeis.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 422dad8c..d156dcb5 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -7,7 +7,7 @@ from irctest import cases from irctest.numerics import RPL_CHANNELCREATED, RPL_CHANNELMODEIS -from irctest.patma import ANYSTR +from irctest.patma import ANYSTR, ListRemainder class RplChannelModeIsTestCase(cases.BaseServerTestCase): @@ -27,10 +27,13 @@ def testChannelModeIs(self): ) for message in messages: if message.command == RPL_CHANNELMODEIS: + # the final parameters are the mode string (e.g. `+int`), + # and then optionally any mode parameters (in case the ircd + # lists a mode that takes a parameter) self.assertMessageMatch( message, command=RPL_CHANNELMODEIS, - params=["chanop", "#chan", ANYSTR], + params=["chanop", "#chan", ListRemainder(ANYSTR, min_length=1)], ) final_param = message.params[2] self.assertEqual(final_param[0], "+") From bf2633a8f75d3372fc3d4d7c94b2d4f09e945ffe Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 00:41:12 -0400 Subject: [PATCH 06/30] relax ERR_NOSUCHCHANNEL requirement for Unreal --- irctest/server_tests/chmodes/operator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 2332d667..5f16d4cc 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -42,7 +42,8 @@ def testChannelOperatorMode(self): self.assertEqual(len(messages), 1) # Modern: "If is a channel that does not exist on the network, # the ERR_NOSUCHCHANNEL (403) numeric is returned." - self.assertMessageMatch(messages[0], command=ERR_NOSUCHCHANNEL) + # However, Unreal sends 401 ERR_NOSUCHNICK here instead: + self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) self.sendLine("chanop", "MODE #nonexistentchan +o nonexistentnick") messages = self.getMessages("chanop") From 14f40ea0a4d40f9a8f1238f84a682e78c48df0d5 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 00:56:34 -0400 Subject: [PATCH 07/30] test existing channel + nonexistent nick --- irctest/server_tests/chmodes/operator.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 5f16d4cc..fad6f2b8 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -37,6 +37,11 @@ def testChannelOperatorMode(self): self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) + self.sendLine("chanop", "MODE #chan +o nobody") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn(messages[0].command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) + self.sendLine("chanop", "MODE #nonexistentchan +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) @@ -45,7 +50,7 @@ def testChannelOperatorMode(self): # However, Unreal sends 401 ERR_NOSUCHNICK here instead: self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) - self.sendLine("chanop", "MODE #nonexistentchan +o nonexistentnick") + self.sendLine("chanop", "MODE #nonexistentchan +o nobody") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn( From 1cf762729a31635741fa76681238251602f78755 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 01:02:32 -0400 Subject: [PATCH 08/30] add comments explaining the cases --- irctest/server_tests/chmodes/operator.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index fad6f2b8..4878ad4b 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -27,21 +27,25 @@ def testChannelOperatorMode(self): self.connectClient("otherguy", name="otherguy") self.joinChannel("otherguy", "#otherguy") + # sender is a channel member but without the necessary privileges: self.sendLine("unprivd", "MODE #chan +o unprivd") messages = self.getMessages("unprivd") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) + # sender is a chanop, but target nick is not in the channel: self.sendLine("chanop", "MODE #chan +o otherguy") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) + # sender is a chanop, but target nick does not exist: self.sendLine("chanop", "MODE #chan +o nobody") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) + # target channel does not exist, but target nick does: self.sendLine("chanop", "MODE #nonexistentchan +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) @@ -50,6 +54,7 @@ def testChannelOperatorMode(self): # However, Unreal sends 401 ERR_NOSUCHNICK here instead: self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) + # neither target channel nor target nick exist: self.sendLine("chanop", "MODE #nonexistentchan +o nobody") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) @@ -58,12 +63,13 @@ def testChannelOperatorMode(self): [ERR_NOSUCHCHANNEL, ERR_NOTONCHANNEL, ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL], ) + # sender is not a channel member, target nick exists but is not a channel member: self.sendLine("chanop", "MODE #otherguy +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) - # test an actually successful mode grant + # test an actually successful mode grant: self.sendLine("chanop", "MODE #chan +o unprivd") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) From 689fcb634e4cc848c8cf18e370507bdbd15ddf2d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 01:04:07 -0400 Subject: [PATCH 09/30] add another case --- irctest/server_tests/chmodes/operator.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 4878ad4b..2b1d75f8 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -26,6 +26,8 @@ def testChannelOperatorMode(self): self.connectClient("otherguy", name="otherguy") self.joinChannel("otherguy", "#otherguy") + self.joinChannel("unprivd", "#otherguy") + self.getMessages("otherguy") # sender is a channel member but without the necessary privileges: self.sendLine("unprivd", "MODE #chan +o unprivd") @@ -69,6 +71,12 @@ def testChannelOperatorMode(self): self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + # sender is not a channel member, target nick exists and is a channel member: + self.sendLine("chanop", "MODE #otherguy +o unprivd") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + # test an actually successful mode grant: self.sendLine("chanop", "MODE #chan +o unprivd") messages = self.getMessages("chanop") From e7b723d7ebd5a85f92fd9ddc6d71a1ed4c6d2606 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 22:22:54 -0400 Subject: [PATCH 10/30] raise ngircd nick limit --- irctest/controllers/ngircd.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/irctest/controllers/ngircd.py b/irctest/controllers/ngircd.py index 7b1a3ec1..460bba78 100644 --- a/irctest/controllers/ngircd.py +++ b/irctest/controllers/ngircd.py @@ -28,6 +28,9 @@ [Operator] Name = operuser Password = operpassword + +[Limits] + MaxNickLength = 32 # defaults to 9 """ From cad1869bc0b92f09f894d6fb40b078574755374c Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 3 Jun 2024 22:25:48 -0400 Subject: [PATCH 11/30] use longer nicknames again --- irctest/server_tests/chmodes/operator.py | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 2b1d75f8..52b46563 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -20,23 +20,23 @@ def testChannelOperatorMode(self): self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") - self.connectClient("unprivd", name="unprivd") - self.joinChannel("unprivd", "#chan") + self.connectClient("unprivileged", name="unprivileged") + self.joinChannel("unprivileged", "#chan") self.getMessages("chanop") - self.connectClient("otherguy", name="otherguy") - self.joinChannel("otherguy", "#otherguy") - self.joinChannel("unprivd", "#otherguy") - self.getMessages("otherguy") + self.connectClient("unrelated", name="unrelated") + self.joinChannel("unrelated", "#unrelated") + self.joinChannel("unprivileged", "#unrelated") + self.getMessages("unrelated") # sender is a channel member but without the necessary privileges: - self.sendLine("unprivd", "MODE #chan +o unprivd") - messages = self.getMessages("unprivd") + self.sendLine("unprivileged", "MODE #chan +o unprivileged") + messages = self.getMessages("unprivileged") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) # sender is a chanop, but target nick is not in the channel: - self.sendLine("chanop", "MODE #chan +o otherguy") + self.sendLine("chanop", "MODE #chan +o unrelated") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) @@ -66,30 +66,30 @@ def testChannelOperatorMode(self): ) # sender is not a channel member, target nick exists but is not a channel member: - self.sendLine("chanop", "MODE #otherguy +o chanop") + self.sendLine("chanop", "MODE #unrelated +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) # sender is not a channel member, target nick exists and is a channel member: - self.sendLine("chanop", "MODE #otherguy +o unprivd") + self.sendLine("chanop", "MODE #unrelated +o unprivileged") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) # test an actually successful mode grant: - self.sendLine("chanop", "MODE #chan +o unprivd") + self.sendLine("chanop", "MODE #chan +o unprivileged") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch( messages[0], command="MODE", - params=["#chan", "+o", "unprivd"], + params=["#chan", "+o", "unprivileged"], ) - messages = self.getMessages("unprivd") + messages = self.getMessages("unprivileged") self.assertEqual(len(messages), 1) self.assertMessageMatch( messages[0], command="MODE", - params=["#chan", "+o", "unprivd"], + params=["#chan", "+o", "unprivileged"], ) From fb803cbf199b0fde3440f286b5bb77d6e09f84db Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 00:39:10 -0400 Subject: [PATCH 12/30] fix compatibility with bahamut --- irctest/server_tests/chmodes/operator.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 52b46563..0095d967 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -44,8 +44,11 @@ def testChannelOperatorMode(self): # sender is a chanop, but target nick does not exist: self.sendLine("chanop", "MODE #chan +o nobody") messages = self.getMessages("chanop") - self.assertEqual(len(messages), 1) - self.assertIn(messages[0].command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) + # ERR_NOSUCHNICK is typical, Bahamut additionally sends ERR_USERNOTINCHANNEL + self.assertGreaterEqual(len(messages), 1) + self.assertLessEqual(len(messages), 2) + for message in messages: + self.assertIn(message.command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) # target channel does not exist, but target nick does: self.sendLine("chanop", "MODE #nonexistentchan +o chanop") From 5b797c80ce6e254b21c68c1a90b3f5b392d9f587 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 04:37:29 -0400 Subject: [PATCH 13/30] fix compatibility with sable in one case --- irctest/server_tests/chmodes/operator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 0095d967..ebe3d446 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -72,7 +72,10 @@ def testChannelOperatorMode(self): self.sendLine("chanop", "MODE #unrelated +o chanop") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) - self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + self.assertIn( + messages[0].command, + [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED, ERR_USERNOTINCHANNEL], + ) # sender is not a channel member, target nick exists and is a channel member: self.sendLine("chanop", "MODE #unrelated +o unprivileged") From a09430f342df6acff654564bcdacfa5b0219aa2e Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 04:47:06 -0400 Subject: [PATCH 14/30] mark expected fail for irc2 and sable --- irctest/server_tests/chmodes/modeis.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index d156dcb5..69f6d925 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -12,6 +12,11 @@ class RplChannelModeIsTestCase(cases.BaseServerTestCase): @cases.mark_specifications("Modern") + @cases.xfailIfSoftware( + ["irc2", "Sable"], + "irc2 doesn't support 329 RPL_CHANNELCREATED" + "https://github.com/Libera-Chat/sable/issues/130", + ) def testChannelModeIs(self): self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") From cb0558e2f9c48bd4cfed5fccadf3044117e7369e Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 18:18:10 -0400 Subject: [PATCH 15/30] remove xfail, special-case irc2 and sable instead --- irctest/server_tests/chmodes/modeis.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 69f6d925..54e1a248 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -12,12 +12,14 @@ class RplChannelModeIsTestCase(cases.BaseServerTestCase): @cases.mark_specifications("Modern") - @cases.xfailIfSoftware( - ["irc2", "Sable"], - "irc2 doesn't support 329 RPL_CHANNELCREATED" - "https://github.com/Libera-Chat/sable/issues/130", - ) def testChannelModeIs(self): + expected_numerics = {RPL_CHANNELMODEIS, RPL_CHANNELCREATED} + if self.controller.software_name in ("irc2", "Sable"): + # irc2 and Sable don't use timestamps for conflict resolution, + # consequently they don't store the channel creation timestamp + # and don't send RPL_CHANNELCREATED + expected_numerics = {RPL_CHANNELMODEIS} + self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") # i, n, and t are specified by RFC1459; some of them may be on by default, @@ -27,9 +29,7 @@ def testChannelModeIs(self): self.sendLine("chanop", "MODE #chan") messages = self.getMessages("chanop") - self.assertLessEqual( - {RPL_CHANNELMODEIS, RPL_CHANNELCREATED}, {msg.command for msg in messages} - ) + self.assertLessEqual(expected_numerics, {msg.command for msg in messages}) for message in messages: if message.command == RPL_CHANNELMODEIS: # the final parameters are the mode string (e.g. `+int`), @@ -54,9 +54,7 @@ def testChannelModeIs(self): self.sendLine("chanop", "MODE #chan") messages = self.getMessages("chanop") - self.assertLessEqual( - {RPL_CHANNELMODEIS, RPL_CHANNELCREATED}, {msg.command for msg in messages} - ) + self.assertLessEqual(expected_numerics, {msg.command for msg in messages}) # all modes have been disabled; the correct representation of this is `+` for message in messages: if message.command == RPL_CHANNELMODEIS: From c6ed67530bd22229b7abedda5ae9748f6e23ae1d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 18:19:40 -0400 Subject: [PATCH 16/30] assert that +int got enabled --- irctest/server_tests/chmodes/modeis.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 54e1a248..a7d64c64 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -45,6 +45,8 @@ def testChannelModeIs(self): enabled_modes = list(final_param[1:]) break + self.assertLessEqual(set(enabled_modes), {"i", "n", "t"}) + # remove all the modes listed by RPL_CHANNELMODEIS self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") response = self.getMessage("chanop") From d89641372fc12d836d671fcccfaa4e69d7bb3840 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 18:50:44 -0400 Subject: [PATCH 17/30] split up operator mode test cases --- irctest/server_tests/chmodes/operator.py | 71 +++++++++++++++++++----- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index ebe3d446..9533e201 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -1,9 +1,3 @@ -""" -Test various error and success cases around the channel operator mode: - - -""" - from irctest import cases from irctest.numerics import ( ERR_CHANOPRIVSNEEDED, @@ -15,8 +9,15 @@ class ChannelOperatorModeTestCase(cases.BaseServerTestCase): - @cases.mark_specifications("Modern") - def testChannelOperatorMode(self): + """Test various error and success cases around the channel operator mode: + + + """ + + def setupNicks(self): + """Set up a standard set of three nicknames and two channels + for testing channel-user MODE interactions.""" + # first nick to join the channel is privileged: self.connectClient("chanop", name="chanop") self.joinChannel("chanop", "#chan") @@ -29,18 +30,32 @@ def testChannelOperatorMode(self): self.joinChannel("unprivileged", "#unrelated") self.getMessages("unrelated") + @cases.mark_specifications("Modern") + def testChannelOperatorModeSenderPrivsNeeded(self): + """Test that +o from a channel member without the necessary privileges + fails as expected.""" + self.setupNicks() # sender is a channel member but without the necessary privileges: self.sendLine("unprivileged", "MODE #chan +o unprivileged") messages = self.getMessages("unprivileged") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) + @cases.mark_specifications("Modern") + def testChannelOperatorModeTargetNotInChannel(self): + """Test that +o targeting a user not present in the channel fails + as expected.""" + self.setupNicks() # sender is a chanop, but target nick is not in the channel: self.sendLine("chanop", "MODE #chan +o unrelated") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL) + @cases.mark_specifications("Modern") + def testChannelOperatorModeTargetDoesNotExist(self): + """Test that +o targeting a nonexistent nick fails as expected.""" + self.setupNicks() # sender is a chanop, but target nick does not exist: self.sendLine("chanop", "MODE #chan +o nobody") messages = self.getMessages("chanop") @@ -50,6 +65,10 @@ def testChannelOperatorMode(self): for message in messages: self.assertIn(message.command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) + @cases.mark_specifications("Modern") + def testChannelOperatorModeChannelDoesNotExist(self): + """Test that +o targeting a nonexistent channel fails as expected.""" + self.setupNicks() # target channel does not exist, but target nick does: self.sendLine("chanop", "MODE #nonexistentchan +o chanop") messages = self.getMessages("chanop") @@ -57,8 +76,16 @@ def testChannelOperatorMode(self): # Modern: "If is a channel that does not exist on the network, # the ERR_NOSUCHCHANNEL (403) numeric is returned." # However, Unreal sends 401 ERR_NOSUCHNICK here instead: - self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) + if self.controller.software_name != "UnrealIRCd": + self.assertEqual(messages[0].command, ERR_NOSUCHCHANNEL) + else: + self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) + @cases.mark_specifications("Modern") + def testChannelOperatorModeChannelAndTargetDoNotExist(self): + """Test that +o targeting a nonexistent channel and nickname + fails as expected.""" + self.setupNicks() # neither target channel nor target nick exist: self.sendLine("chanop", "MODE #nonexistentchan +o nobody") messages = self.getMessages("chanop") @@ -68,6 +95,22 @@ def testChannelOperatorMode(self): [ERR_NOSUCHCHANNEL, ERR_NOTONCHANNEL, ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL], ) + @cases.mark_specifications("Modern") + def testChannelOperatorModeSenderNonMember(self): + """Test that +o where the sender is not a channel member + fails as expected.""" + self.setupNicks() + # sender is not a channel member, target nick exists and is a channel member: + self.sendLine("chanop", "MODE #unrelated +o unprivileged") + messages = self.getMessages("chanop") + self.assertEqual(len(messages), 1) + self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + + @cases.mark_specifications("Modern") + def testChannelOperatorModeSenderAndTargetNonMembers(self): + """Test that +o where neither the sender nor the target is a channel + member fails as expected.""" + self.setupNicks() # sender is not a channel member, target nick exists but is not a channel member: self.sendLine("chanop", "MODE #unrelated +o chanop") messages = self.getMessages("chanop") @@ -77,13 +120,11 @@ def testChannelOperatorMode(self): [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED, ERR_USERNOTINCHANNEL], ) - # sender is not a channel member, target nick exists and is a channel member: - self.sendLine("chanop", "MODE #unrelated +o unprivileged") - messages = self.getMessages("chanop") - self.assertEqual(len(messages), 1) - self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED]) + @cases.mark_specifications("Modern") + def testChannelOperatorModeSuccess(self): + """Tests a successful grant of +o in a channel.""" + self.setupNicks() - # test an actually successful mode grant: self.sendLine("chanop", "MODE #chan +o unprivileged") messages = self.getMessages("chanop") self.assertEqual(len(messages), 1) From f4c45394cdd2c0dae4ca560d324ba9f0b638de71 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 18:53:06 -0400 Subject: [PATCH 18/30] move docstring --- irctest/server_tests/chmodes/modeis.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index a7d64c64..e9f0a9d7 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -1,10 +1,3 @@ -""" -Test RPL_CHANNELMODEIS and RPL_CHANNELCREATED as responses to -`MODE #channel`: - - -""" - from irctest import cases from irctest.numerics import RPL_CHANNELCREATED, RPL_CHANNELMODEIS from irctest.patma import ANYSTR, ListRemainder @@ -13,6 +6,11 @@ class RplChannelModeIsTestCase(cases.BaseServerTestCase): @cases.mark_specifications("Modern") def testChannelModeIs(self): + """Test RPL_CHANNELMODEIS and RPL_CHANNELCREATED as responses to + `MODE #channel`: + + + """ expected_numerics = {RPL_CHANNELMODEIS, RPL_CHANNELCREATED} if self.controller.software_name in ("irc2", "Sable"): # irc2 and Sable don't use timestamps for conflict resolution, From bceb1322c00b0710333f34bfeaeb5ec57b3cdff5 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 18:59:13 -0400 Subject: [PATCH 19/30] tweak special-casing --- irctest/server_tests/chmodes/operator.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 9533e201..960d1543 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -31,6 +31,7 @@ def setupNicks(self): self.getMessages("unrelated") @cases.mark_specifications("Modern") + @cases.xfailIfSoftware(["irc2"], "broken in irc2") def testChannelOperatorModeSenderPrivsNeeded(self): """Test that +o from a channel member without the necessary privileges fails as expected.""" @@ -60,10 +61,14 @@ def testChannelOperatorModeTargetDoesNotExist(self): self.sendLine("chanop", "MODE #chan +o nobody") messages = self.getMessages("chanop") # ERR_NOSUCHNICK is typical, Bahamut additionally sends ERR_USERNOTINCHANNEL - self.assertGreaterEqual(len(messages), 1) - self.assertLessEqual(len(messages), 2) - for message in messages: - self.assertIn(message.command, [ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL]) + if self.controller.software_name != "Bahamut": + self.assertEqual(len(messages), 1) + self.assertMessageMatch(messages[0], command=ERR_NOSUCHNICK) + else: + self.assertLessEqual(len(messages), 2) + commands = {message.command for message in messages} + self.assertLessEqual({ERR_NOSUCHNICK}, commands) + self.assertLessEqual(commands, {ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL}) @cases.mark_specifications("Modern") def testChannelOperatorModeChannelDoesNotExist(self): From 53b7e719d73f552c322fd78b7f1963b7b7b7710a Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 19:10:30 -0400 Subject: [PATCH 20/30] fix inverted comparison --- irctest/server_tests/chmodes/modeis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index e9f0a9d7..8d62f41b 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -43,7 +43,7 @@ def testChannelModeIs(self): enabled_modes = list(final_param[1:]) break - self.assertLessEqual(set(enabled_modes), {"i", "n", "t"}) + self.assertLessEqual({"i", "n", "t"}, set(enabled_modes)) # remove all the modes listed by RPL_CHANNELMODEIS self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") From 6f91d4495dd3c220f112baa69dfc4d22baf4affc Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 19:15:31 -0400 Subject: [PATCH 21/30] ngircd is also weird --- irctest/server_tests/chmodes/operator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 960d1543..a4b04658 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -80,8 +80,8 @@ def testChannelOperatorModeChannelDoesNotExist(self): self.assertEqual(len(messages), 1) # Modern: "If is a channel that does not exist on the network, # the ERR_NOSUCHCHANNEL (403) numeric is returned." - # However, Unreal sends 401 ERR_NOSUCHNICK here instead: - if self.controller.software_name != "UnrealIRCd": + # However, Unreal and ngircd send 401 ERR_NOSUCHNICK here instead: + if self.controller.software_name not in ("UnrealIRCd", "ngIRCd"): self.assertEqual(messages[0].command, ERR_NOSUCHCHANNEL) else: self.assertIn(messages[0].command, [ERR_NOSUCHCHANNEL, ERR_NOSUCHNICK]) From 95be93996961751f4b5a06659a2041874cf3bfd2 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 19:30:11 -0400 Subject: [PATCH 22/30] strengthen comparison to equality --- irctest/server_tests/chmodes/modeis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 8d62f41b..bbb84c98 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -27,7 +27,7 @@ def testChannelModeIs(self): self.sendLine("chanop", "MODE #chan") messages = self.getMessages("chanop") - self.assertLessEqual(expected_numerics, {msg.command for msg in messages}) + self.assertEqual(expected_numerics, {msg.command for msg in messages}) for message in messages: if message.command == RPL_CHANNELMODEIS: # the final parameters are the mode string (e.g. `+int`), @@ -54,7 +54,7 @@ def testChannelModeIs(self): self.sendLine("chanop", "MODE #chan") messages = self.getMessages("chanop") - self.assertLessEqual(expected_numerics, {msg.command for msg in messages}) + self.assertEqual(expected_numerics, {msg.command for msg in messages}) # all modes have been disabled; the correct representation of this is `+` for message in messages: if message.command == RPL_CHANNELMODEIS: From 34534df17f79c0871bb63f86cae4f2583870fd3d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 9 Jun 2024 19:57:53 -0400 Subject: [PATCH 23/30] bump inspircd to 4.0 release candidate --- .github/workflows/test-stable.yml | 2 +- workflows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-stable.yml b/.github/workflows/test-stable.yml index 07b44e66..04e40112 100644 --- a/.github/workflows/test-stable.yml +++ b/.github/workflows/test-stable.yml @@ -189,7 +189,7 @@ jobs: uses: actions/checkout@v3 with: path: inspircd - ref: v3.17.0 + ref: v4.0.0rc1 repository: inspircd/inspircd - name: Build InspIRCd run: | diff --git a/workflows.yml b/workflows.yml index 01cf465e..181b367b 100644 --- a/workflows.yml +++ b/workflows.yml @@ -148,7 +148,7 @@ software: name: InspIRCd repository: inspircd/inspircd refs: &inspircd_refs - stable: v3.17.0 + stable: v4.0.0rc1 release: null devel: master devel_release: insp3 From cc78133d1e65c30263ca28c727d5547815582a27 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 10 Jun 2024 01:33:56 -0400 Subject: [PATCH 24/30] Revert "bump inspircd to 4.0 release candidate" This reverts commit 34534df17f79c0871bb63f86cae4f2583870fd3d. --- .github/workflows/test-stable.yml | 2 +- workflows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-stable.yml b/.github/workflows/test-stable.yml index 04e40112..07b44e66 100644 --- a/.github/workflows/test-stable.yml +++ b/.github/workflows/test-stable.yml @@ -189,7 +189,7 @@ jobs: uses: actions/checkout@v3 with: path: inspircd - ref: v4.0.0rc1 + ref: v3.17.0 repository: inspircd/inspircd - name: Build InspIRCd run: | diff --git a/workflows.yml b/workflows.yml index 181b367b..01cf465e 100644 --- a/workflows.yml +++ b/workflows.yml @@ -148,7 +148,7 @@ software: name: InspIRCd repository: inspircd/inspircd refs: &inspircd_refs - stable: v4.0.0rc1 + stable: v3.17.0 release: null devel: master devel_release: insp3 From 0ca37d3fb30f34cd0b640cd606c361a7a50a6797 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 10 Jun 2024 01:35:28 -0400 Subject: [PATCH 25/30] mark inspircd case x-fail --- irctest/server_tests/chmodes/operator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index a4b04658..11a6c283 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -43,6 +43,7 @@ def testChannelOperatorModeSenderPrivsNeeded(self): self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) @cases.mark_specifications("Modern") + @cases.xfailIfSoftware(["InspIRCd"], "fixed in InspIRCd 4.x") def testChannelOperatorModeTargetNotInChannel(self): """Test that +o targeting a user not present in the channel fails as expected.""" From 4b9df3956d14fc7934883be6044334ed858784e8 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 16 Jun 2024 04:36:06 -0400 Subject: [PATCH 26/30] Update irctest/server_tests/chmodes/modeis.py Co-authored-by: Val Lorentz --- irctest/server_tests/chmodes/modeis.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index bbb84c98..4540df68 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -48,8 +48,7 @@ def testChannelModeIs(self): # remove all the modes listed by RPL_CHANNELMODEIS self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") response = self.getMessage("chanop") - self.assertMessageMatch(response, command="MODE", params=["#chan", ANYSTR]) - self.assertEqual(response.params[1][0], "-") + self.assertMessageMatch(response, command="MODE", params=["#chan", StrRe("^-.*")]) self.assertEqual(set(response.params[1][1:]), set(enabled_modes)) self.sendLine("chanop", "MODE #chan") From d1546e687bad3a5bf73742a55564ebae7141f17f Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 16 Jun 2024 04:39:21 -0400 Subject: [PATCH 27/30] fix --- irctest/server_tests/chmodes/modeis.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 4540df68..8c3f8078 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -1,6 +1,6 @@ from irctest import cases from irctest.numerics import RPL_CHANNELCREATED, RPL_CHANNELMODEIS -from irctest.patma import ANYSTR, ListRemainder +from irctest.patma import ANYSTR, ListRemainder, StrRe class RplChannelModeIsTestCase(cases.BaseServerTestCase): @@ -48,6 +48,7 @@ def testChannelModeIs(self): # remove all the modes listed by RPL_CHANNELMODEIS self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") response = self.getMessage("chanop") + # we should get something like: MODE #chan -int self.assertMessageMatch(response, command="MODE", params=["#chan", StrRe("^-.*")]) self.assertEqual(set(response.params[1][1:]), set(enabled_modes)) From 3ae33e37eafd06c74cc0e741e716e27a27cfb969 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 16 Jun 2024 04:45:04 -0400 Subject: [PATCH 28/30] fix lint --- irctest/server_tests/chmodes/modeis.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irctest/server_tests/chmodes/modeis.py b/irctest/server_tests/chmodes/modeis.py index 8c3f8078..e1df129f 100644 --- a/irctest/server_tests/chmodes/modeis.py +++ b/irctest/server_tests/chmodes/modeis.py @@ -49,7 +49,9 @@ def testChannelModeIs(self): self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}") response = self.getMessage("chanop") # we should get something like: MODE #chan -int - self.assertMessageMatch(response, command="MODE", params=["#chan", StrRe("^-.*")]) + self.assertMessageMatch( + response, command="MODE", params=["#chan", StrRe("^-.*")] + ) self.assertEqual(set(response.params[1][1:]), set(enabled_modes)) self.sendLine("chanop", "MODE #chan") From f3544cab8e3fde658aa2549078c6e6e76f01c4ee Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Tue, 2 Jul 2024 00:45:56 -0400 Subject: [PATCH 29/30] remove inspircd x-fail --- irctest/server_tests/chmodes/operator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/irctest/server_tests/chmodes/operator.py b/irctest/server_tests/chmodes/operator.py index 11a6c283..a4b04658 100644 --- a/irctest/server_tests/chmodes/operator.py +++ b/irctest/server_tests/chmodes/operator.py @@ -43,7 +43,6 @@ def testChannelOperatorModeSenderPrivsNeeded(self): self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED) @cases.mark_specifications("Modern") - @cases.xfailIfSoftware(["InspIRCd"], "fixed in InspIRCd 4.x") def testChannelOperatorModeTargetNotInChannel(self): """Test that +o targeting a user not present in the channel fails as expected.""" From 209b5655bb1908cb05490fb0bfbea630b56869e4 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Tue, 2 Jul 2024 00:54:59 -0400 Subject: [PATCH 30/30] upgrade inspircd stable to v3.17.1 --- .github/workflows/test-stable.yml | 2 +- workflows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-stable.yml b/.github/workflows/test-stable.yml index dfe76569..e09d1c7f 100644 --- a/.github/workflows/test-stable.yml +++ b/.github/workflows/test-stable.yml @@ -189,7 +189,7 @@ jobs: uses: actions/checkout@v4 with: path: inspircd - ref: v3.17.0 + ref: v3.17.1 repository: inspircd/inspircd - name: Build InspIRCd run: | diff --git a/workflows.yml b/workflows.yml index 01cf465e..2a2991ff 100644 --- a/workflows.yml +++ b/workflows.yml @@ -148,7 +148,7 @@ software: name: InspIRCd repository: inspircd/inspircd refs: &inspircd_refs - stable: v3.17.0 + stable: v3.17.1 release: null devel: master devel_release: insp3