Questions regarding layout and composition of tests (bug#48598)

"J.P." <[email protected]>
Newsgroups gmane.emacs.erc.general
Message-ID <[email protected]>
Hi people,

I'm seeking feedback on (and perhaps tacit approval for) the following
files and their layout. AFAICT, aside from the whole

  test/lisp/foo-tests.el -> lisp/foo.el

correspondence for Make discovery, there doesn't seem to be much in the
way of rigid rules regarding naming, layout, or dependency inclusion.
(For anyone following this bug, none of those aspects has changed
dramatically in the past year or so with regard to these files).

  test/lisp/erc
  ├── erc-d
  │   ├── erc-d.el
  │   ├── erc-d-i.el
  │   ├── erc-d-self.el
  │   ├── erc-d-self-resources
  │   │   ├── basic.eld
  │   │   ├── depleted.eld
  │   │   ├── drop-a.eld
  │   │   ├── drop-b.eld
  │   │   ├── dynamic-barnet.eld
  │   │   ├── dynamic.eld
  │   │   ├── dynamic-foonet.eld
  │   │   ├── dynamic-stub.eld
  │   │   ├── eof.eld
  │   │   ├── fuzzy.eld
  │   │   ├── incremental.eld
  │   │   ├── irc-parser-tests.eld
  │   │   ├── linger.eld
  │   │   ├── linger-multi-a.eld
  │   │   ├── linger-multi-b.eld
  │   │   ├── no-block.eld
  │   │   ├── no-match.eld
  │   │   ├── nonstandard.eld
  │   │   ├── no-pong.eld
  │   │   ├── proxy-barnet.eld
  │   │   ├── proxy-foonet.eld
  │   │   ├── proxy-solo.eld
  │   │   ├── proxy-subprocess.el
  │   │   ├── timeout.eld
  │   │   └── unexpected.eld
  │   ├── erc-d-t.el
  │   └── erc-d-u.el
  ├── erc-join-tests.el
  ├── erc-networks-tests.el
  ├── erc-scenarios-common.el
  ├── erc-scenarios.el
  ├── erc-scenarios-resources
  │   ├── base
  │   │   ├── association
  │   │   │   ├── bouncer-history
  │   │   │   │   ├── barnet.eld
  │   │   │   │   └── foonet.eld
  │   │   │   ├── multi-net
  │   │   │   │   ├── barnet.eld
  │   │   │   │   └── foonet.eld
  │   │   │   ├── nick-bump
  │   │   │   │   ├── renicked-again.eld
  │   │   │   │   ├── renicked.eld
  │   │   │   │   ├── renicked-foisted-again.eld
  │   │   │   │   └── renicked-foisted.eld
  │   │   │   ├── reconnect-playback
  │   │   │   │   ├── foonet-again.eld
  │   │   │   │   └── foonet.eld
  │   │   │   └── same-network
  │   │   │       ├── chester.eld
  │   │   │       ├── tester-again.eld
  │   │   │       └── tester.eld
  │   │   ├── auth-source
  │   │   │   ├── foonet.eld
  │   │   │   └── nopass.eld
  │   │   ├── channel-buffer-revival
  │   │   │   └── foonet.eld
  │   │   ├── flood
  │   │   │   └── soju.eld
  │   │   ├── gapless-connect
  │   │   │   ├── barnet.eld
  │   │   │   ├── foonet.eld
  │   │   │   └── pass-stub.eld
  │   │   ├── mask-target-routing
  │   │   │   └── foonet.eld
  │   │   ├── network-id
  │   │   │   ├── bouncer
  │   │   │   │   ├── barnet-again.eld
  │   │   │   │   ├── barnet-drop.eld
  │   │   │   │   ├── barnet.eld
  │   │   │   │   ├── foonet-again.eld
  │   │   │   │   ├── foonet-drop.eld
  │   │   │   │   ├── foonet.eld
  │   │   │   │   └── stub-again.eld
  │   │   │   └── same-network
  │   │   │       ├── chester.eld
  │   │   │       └── tester.eld
  │   │   ├── reconnect
  │   │   │   ├── aborted-dupe.eld
  │   │   │   ├── aborted.eld
  │   │   │   ├── options-again.eld
  │   │   │   ├── options.eld
  │   │   │   ├── timer.eld
  │   │   │   └── timer-last.eld
  │   │   ├── renick
  │   │   │   ├── queries
  │   │   │   │   ├── bouncer-barnet.eld
  │   │   │   │   ├── bouncer-foonet.eld
  │   │   │   │   └── solo.eld
  │   │   │   └── self
  │   │   │       ├── auto.eld
  │   │   │       ├── manual.eld
  │   │   │       ├── qual-chester.eld
  │   │   │       └── qual-tester.eld
  │   │   └── reuse-buffers
  │   │       ├── channel-buffers
  │   │       │   ├── barnet.eld
  │   │       │   └── foonet.eld
  │   │       └── server-buffers
  │   │           ├── barnet.eld
  │   │           └── foonet.eld
  │   ├── join
  │   │   ├── legacy
  │   │   │   └── foonet.eld
  │   │   ├── network-id
  │   │   │   ├── barnet.eld
  │   │   │   ├── foonet-again.eld
  │   │   │   └── foonet.eld
  │   │   └── reconnect
  │   │       ├── foonet-again.eld
  │   │       └── foonet.eld
  │   ├── networks
  │   │   └── announced-missing
  │   │       └── foonet.eld
  │   └── services
  │       ├── auth-source
  │       │   └── libera.eld
  │       └── password
  │           └── libera.eld
  ├── erc-services-tests.el
  └── erc-tests.el
  
The files above introduce around a hundred nontrivial tests that
lengthen the overall running time for the entire Emacs suite by roughly
five minutes on EMBA [1]. Bug#49860 will likely stretch this by another
two. In spite of the cost, their utility extends to indirectly testing
the basic behavioral contracts of other libraries as well. The only
episode in the past year where these encountered any difficulty was in
the immediate wake of

  commit 0c7a7433dce1b93a685396986d3a560c9cc291f1
  Author: Miha Rihtaršič <[email protected]>
  Date:   Tue May 25 21:01:58 2021 +0200

  Try to not prioritise reading from lower file descriptors

  * src/process.c (wait_reading_process_output): When looping through
  fds, continue from where we left off.
  (syms_of_process): Vprocess_prioritize_lower_fds: New variable
  (bug#48118).

But that was a good thing because the only tests affected were those
intentionally demonstrating undesirable behavior.

A few of the more relevant patches are attached below, but the full set
is also available [2]. General comments and random spot checks are, of
course, always welcome.

Thanks,
J.P.


[1] https://emba.gnu.org/emacs/emacs/-/jobs/42826

    FWIW, it's more like two minutes on normal PCs and commercial cloud
    infra, like Gitlab.com's GCP runners.

[2] https://jpneverwas.gitlab.io/erc-tools/48598/patches.tar.gz
0016-Add-ERC-test-server-and-related-resources.patch (text/x-patch, 175.2 KB) - not displayed
0018-SQUASH-ME-Add-user-oriented-test-scenarios-for-ERC.patch (text/x-patch, 234.2 KB) - not displayed
0021-SQUASH-ME-Add-ERC-scenarios-for-identity-aware-msg-h.patch (text/x-patch, 6.2 KB)
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Thu, 30 Sep 2021 06:11:50 -0700
Subject: [PATCH 21/34] SQUASH-ME: Add ERC scenarios for identity-aware msg
 handlers

---
 .../base/mask-target-routing/foonet.eld       | 45 +++++++++++++++++++
 test/lisp/erc/erc-scenarios.el                | 34 ++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 test/lisp/erc/erc-scenarios-resources/base/mask-target-routing/foonet.eld

diff --git a/test/lisp/erc/erc-scenarios-resources/base/mask-target-routing/foonet.eld b/test/lisp/erc/erc-scenarios-resources/base/mask-target-routing/foonet.eld
new file mode 100644
index 0000000000..796d5566b6
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/base/mask-target-routing/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 31 May 2021 09:56:24 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":[email protected] JOIN #foo")
+ (0 ":irc.foonet.org 353 tester = #foo :alice @bob rando tester")
+ (0 ":irc.foonet.org 366 tester #foo :End of /NAMES list.")
+ (0 ":***[email protected] PRIVMSG #foo :Buffer Playback...")
+ (0 ":[email protected] PRIVMSG #foo :[10:00:02] bob: All that he is hath reference to your highness.")
+ (0 ":[email protected] PRIVMSG #foo :[10:00:06] alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0 ":***[email protected] PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 5 "MODE #foo")
+ (0 ":irc.foonet.org 324 tester #foo +nt")
+ (0 ":irc.foonet.org 329 tester #foo 1622454985")
+ ;; Invalid msg
+ (0.1 ":[email protected] PRIVMSG :")
+ (0.1 ":[email protected] PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
+ (0.1 ":[email protected] NOTICE $* :[Global notice] going down soon.")
+ (0.1 ":[email protected] PRIVMSG #foo :bob: Well, this is the forest of Arden.")
+ (0.1 ":[email protected] NOTICE $$* :[Global notice] this is a warning.")
+ (0.1 ":[email protected] PRIVMSG #foo :bob: Be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":[email protected] PRIVMSG $* :[Global msg] second warning.")
+ (0.1 ":[email protected] PRIVMSG #foo :bob: And will you, being a man of your breeding.")
+ (0.1 ":[email protected] NOTICE #* :[Global notice] final warning."))
diff --git a/test/lisp/erc/erc-scenarios.el b/test/lisp/erc/erc-scenarios.el
index 3d0d41b482..ba2abe732d 100644
--- a/test/lisp/erc/erc-scenarios.el
+++ b/test/lisp/erc/erc-scenarios.el
@@ -1798,4 +1798,38 @@ erc-scenarios-networks-announced-missing
         (should-not erc-network)
         (should (string= erc-server-announced-name "irc.foonet.org"))))))
 
+;; Targets that are host/server masks like $*, $$*, and #* are routed
+;; to the server buffer: https://github.com/ircdocs/wooooms/issues/5
+
+(ert-deftest erc-scenarios-base-mask-target-routing ()
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/mask-target-routing")
+       (erc-d-linger-secs 0.5)
+       (dumb-server (erc-d-run "localhost" t 'foonet))
+       (port (process-contact dumb-server :service))
+       (expect (erc-d-t-make-expecter)))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+    (erc-d-t-wait-for 1 (get-buffer "foonet"))
+
+    (ert-info ("Channel buffer #foo playback received")
+      (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#foo"))
+        (funcall expect 10 "Excellent workman")))
+
+    (ert-info ("Global notices routed to server buffer")
+      (with-current-buffer "foonet"
+        (funcall expect 10 "going down soon")
+        (funcall expect 10 "this is a warning")
+        (funcall expect 10 "second warning")
+        (funcall expect 10 "final warning")))
+
+    (should-not (get-buffer "$*"))))
+
 ;;; erc-scenarios.el ends here
-- 
2.35.1
0023-SQUASH-ME-Add-ERC-test-scenarios-for-identity-aware-.patch (text/x-patch, 31.4 KB)
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Thu, 30 Sep 2021 03:28:54 -0700
Subject: [PATCH 23/34] SQUASH-ME: Add ERC test scenarios for identity-aware
 autojoin

XXX this commit should not stand alone. It should be squashed or
fixup'd into "Favor network IDs and networks in erc-join.el"
---
 .../join/legacy/foonet.eld                    |  38 +++
 .../join/network-id/barnet.eld                |  43 ++++
 .../join/network-id/foonet-again.eld          |  46 ++++
 .../join/network-id/foonet.eld                |  39 +++
 .../join/reconnect/foonet-again.eld           |  45 ++++
 .../join/reconnect/foonet.eld                 |  45 ++++
 test/lisp/erc/erc-scenarios.el                | 238 +++++++++++++++++-
 7 files changed, 493 insertions(+), 1 deletion(-)
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/legacy/foonet.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/network-id/barnet.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/network-id/foonet-again.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/network-id/foonet.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet-again.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet.eld

diff --git a/test/lisp/erc/erc-scenarios-resources/join/legacy/foonet.eld b/test/lisp/erc/erc-scenarios-resources/join/legacy/foonet.eld
new file mode 100644
index 0000000000..344ba7c1da
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/legacy/foonet.eld
@@ -0,0 +1,38 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 6 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 5 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: Well, this is the forest of Arden.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: And will you, being a man of your breeding, be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Live, and be prosperous; and farewell, good fellow."))
diff --git a/test/lisp/erc/erc-scenarios-resources/join/network-id/barnet.eld b/test/lisp/erc/erc-scenarios-resources/join/network-id/barnet.eld
new file mode 100644
index 0000000000..1a13259383
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/network-id/barnet.eld
@@ -0,0 +1,43 @@
+;; -*- mode: lisp-data; -*-
+((pass 2 "PASS :barnet:changeme"))
+((nick 2 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i"))
+;; No mode answer
+
+((join 2 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0 ":[email protected] PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620608304")
+ ;; Wait for foonet's buffer playback
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Go take her hence, and marry her instantly.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: Of all the four, or the three, or the two, or one of the four.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: And gives the crutch the cradle's infancy.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: Such is the simplicity of man to hearken after the flesh.")
+ (0.05 ":[email protected] PRIVMSG #chan :joe: The leaf to read them. Let us toward the king.")
+ (0.05 ":[email protected] PRIVMSG #chan :mike: Many can brook the weather that love not the wind.")
+ (0.05 ":[email protected] PRIVMSG #chan :joe: And now, dear maid, be you as free to us.")
+ (0.00 ":[email protected] PRIVMSG #chan :mike: He hath an uncle here in Messina will be very much glad of it."))
+
+((linger 3.5 LINGER))
diff --git a/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet-again.eld b/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet-again.eld
new file mode 100644
index 0000000000..08e50dc62b
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet-again.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass-redux 10 "PASS :foonet:changeme"))
+((nick-redux 1 "NICK tester"))
+
+((user-redux 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ ;; No mode answer ^
+
+ ;; History
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***[email protected] PRIVMSG #chan :Buffer Playback...")
+ (0 ":[email protected] PRIVMSG #chan :[02:43:23] alice: And soar with them above a common bound.")
+ (0 ":[email protected] PRIVMSG #chan :[02:43:27] bob: And be aveng'd on cursed Tamora.")
+ (0 ":[email protected] PRIVMSG #chan :[02:43:29] alice: He did love her, sir, as a gentleman loves a woman.")
+ (0 ":***[email protected] PRIVMSG #chan :Playback Complete."))
+
+;; As a server, we ignore useless join sent by autojoin module
+((~join 10 "JOIN #chan"))
+
+((mode-redux 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620608304")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: Ay, madam, with the swiftest wing of speed.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Five times in that ere once in our five wits.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: And bid him come to take his last farewell.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: But we are spirits of another sort.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: It was not given me, nor I did not buy it."))
+
+((linger 6 LINGER))
diff --git a/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet.eld b/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet.eld
new file mode 100644
index 0000000000..1162cc3f24
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/network-id/foonet.eld
@@ -0,0 +1,39 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i"))
+;; No mode answer ^
+
+((join 1 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0 ":[email protected] PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620608304")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Pray you, sir, deliver me this paper.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: Wake when some vile thing is near."))
+
+((quit 1 "QUIT :\2ERC\2"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet-again.eld b/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet-again.eld
new file mode 100644
index 0000000000..f1fcc439cc
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet-again.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is still in debug mode."))
+
+((~join-chan 12 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((~join-spam 12 "JOIN #spam")
+ (0 ":[email protected] JOIN #spam")
+ (0 ":irc.foonet.org 353 tester = #spam :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #spam :End of NAMES list"))
+
+((~mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: Well, this is the forest of Arden."))
+
+((mode-spam 4 "MODE #spam")
+ (0 ":irc.foonet.org 324 tester #spam +nt")
+ (0 ":irc.foonet.org 329 tester #spam 1620104779")
+ (0.1 ":[email protected] PRIVMSG #spam :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":[email protected] PRIVMSG #spam :bob: Our queen and all her elves come here anon."))
diff --git a/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet.eld b/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet.eld
new file mode 100644
index 0000000000..efb269f5ae
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/join/reconnect/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode.")
+
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+
+ (0 ":[email protected] JOIN #spam")
+ (0 ":irc.foonet.org 353 tester = #spam :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #spam :End of NAMES list"))
+
+((mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!"))
+
+((mode-spam 4 "MODE #spam")
+ (0 ":irc.foonet.org 324 tester #spam +nt")
+ (0 ":irc.foonet.org 329 tester #spam 1620104779")
+ (0.1 ":[email protected] PRIVMSG #spam :tester, welcome!")
+ (0.1 ":[email protected] PRIVMSG #spam :tester, welcome!"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/erc-scenarios.el b/test/lisp/erc/erc-scenarios.el
index ba2abe732d..37b58227e7 100644
--- a/test/lisp/erc/erc-scenarios.el
+++ b/test/lisp/erc/erc-scenarios.el
@@ -272,6 +272,242 @@ erc-scenarios-base-association-same-network--new-buffer
        (funcall expect 5 "welcome again")
        (erc-cmd-QUIT "")))))
 
+;; XXX this is okay, but we also need to check that target buffers are
+;; already associated with a new process *before* a JOIN is sent by a
+;; server's playback burst.  This doesn't do that.
+;;
+;; This *does* check that superfluous JOINs sent by the autojoin
+;; module are harmless when they're not acked (superfluous because the
+;; bouncer/server intitates the JOIN).
+
+(defun erc-scenarios-common--join-network-id (foo-reconnector foo-id bar-id)
+  "Ensure channels rejoined by erc-join.el DTRT.
+Originally from scenario clash-of-chans/autojoin as described in
+Bug#48598: 28.0.50; buffer-naming collisions involving bouncers in ERC."
+  (erc-scenarios-common-with-cleanup
+      ((chan-buf-foo (format "#chan@%s" (or foo-id "foonet")))
+       (chan-buf-bar (format "#chan@%s" (or bar-id "barnet")))
+       (erc-scenarios-common-dialog "join/network-id")
+       (erc-d-t-cleanup-sleep-secs 1)
+       (erc-server-flood-penalty 0.5)
+       (dumb-server (erc-d-run "localhost" t 'foonet 'barnet 'foonet-again))
+       (port (process-contact dumb-server :service))
+       (expect (erc-d-t-make-expecter))
+       erc-server-buffer-foo erc-server-process-foo
+       erc-server-buffer-bar erc-server-process-bar)
+
+    (should (memq 'autojoin erc-modules))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer
+          (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+                                           :port port
+                                           :nick "tester"
+                                           :password "foonet:changeme"
+                                           :full-name "tester"
+                                           :id foo-id))
+        (setq erc-server-process-foo erc-server-process)
+        (erc-scenarios-common-assert-initial-buf-name foo-id port)
+        (erc-d-t-wait-for 1 (eq (erc-network) 'foonet))
+        (funcall expect 5 "foonet")))
+
+    (ert-info ("Join #chan, find sentinel, quit")
+      (with-current-buffer erc-server-buffer-foo (erc-cmd-JOIN "#chan"))
+      (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+        (funcall expect 5 "vile thing")
+        (erc-cmd-QUIT "")))
+
+    (erc-d-t-wait-for 2 "Foonet connection deceased"
+      (not (erc-server-process-alive erc-server-buffer-foo)))
+
+    (should (equal erc-autojoin-channels-alist
+                   (if foo-id '((oofnet "#chan")) '((foonet "#chan")))))
+
+    (ert-info ("Connect to barnet")
+      (with-current-buffer
+          (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+                                           :port port
+                                           :nick "tester"
+                                           :password "barnet:changeme"
+                                           :full-name "tester"
+                                           :id bar-id))
+        (setq erc-server-process-bar erc-server-process)
+        (erc-d-t-wait-for 5 (eq erc-network 'barnet))
+        (should (string= (buffer-name) (if bar-id "rabnet" "barnet")))))
+
+    (ert-info ("Server buffers are unique, no stray IP-based names")
+      (should-not (eq erc-server-buffer-foo erc-server-buffer-bar))
+      (should-not (erc-scenarios-common-buflist "127.0.0.1")))
+
+    (ert-info ("Only one #chan buffer exists")
+      (should (equal (list (get-buffer "#chan"))
+                     (erc-scenarios-common-buflist "#chan"))))
+
+    (ert-info ("#chan is not auto-joined")
+      (with-current-buffer "#chan"
+        (erc-d-t-absent-for 0.1 "<joe>")
+        (should-not (process-live-p erc-server-process))
+        (erc-d-t-ensure-for 0.1 "server buffer remains foonet"
+          (eq erc-server-process erc-server-process-foo))))
+
+    (with-current-buffer erc-server-buffer-bar
+      (erc-cmd-JOIN "#chan")
+      (erc-d-t-wait-for 3 (get-buffer chan-buf-foo))
+      (erc-d-t-wait-for 3 (get-buffer chan-buf-bar))
+      (with-current-buffer chan-buf-bar
+        (erc-d-t-wait-for 3 (eq erc-server-process erc-server-process-bar))
+        (funcall expect 5 "marry her instantly")))
+
+    (ert-info ("Reconnect to foonet")
+      (with-current-buffer (setq erc-server-buffer-foo
+                                 (funcall foo-reconnector))
+        (should (member (if foo-id '(oofnet "#chan") '(foonet "#chan"))
+                        erc-autojoin-channels-alist))
+        (erc-d-t-wait-for 3 (erc-server-process-alive))
+        (setq erc-server-process-foo erc-server-process)
+        (erc-d-t-wait-for 2 (eq erc-network 'foonet))
+        (should (string= (buffer-name) (if foo-id "oofnet" "foonet")))
+        (funcall expect 5 "foonet")))
+
+    (ert-info ("#chan@foonet is clean, no cross-contamination")
+      (with-current-buffer chan-buf-foo
+        (erc-d-t-wait-for 3 (eq erc-server-process erc-server-process-foo))
+        (funcall expect 3 "<bob>")
+        (erc-d-t-absent-for 0.1 "<joe>")
+        (while (accept-process-output erc-server-process-foo))
+        (funcall expect 3 "not given me")))
+
+    (ert-info ("All #chan@barnet output received")
+      (with-current-buffer chan-buf-bar
+        (while (accept-process-output erc-server-process-bar))
+        (funcall expect 3 "hath an uncle here")))))
+
+(ert-deftest erc-scenarios-join-network-id--cmd-reconnect ()
+  (let ((connect (lambda ()
+                   (with-current-buffer "foonet"
+                     (erc-cmd-RECONNECT)
+                     (should (eq (current-buffer)
+                                 (process-buffer erc-server-process)))
+                     (current-buffer)))))
+    (erc-scenarios-common--join-network-id connect nil nil)))
+
+(ert-deftest erc-scenarios-join-network-id--cmd-reconnect-id ()
+  (let ((connect (lambda ()
+                   (with-current-buffer "oofnet"
+                     (erc-cmd-RECONNECT)
+                     (should (eq (current-buffer)
+                                 (process-buffer erc-server-process)))
+                     (current-buffer)))))
+    (erc-scenarios-common--join-network-id connect 'oofnet nil)))
+
+(ert-deftest erc-scenarios-join-network-id--cmd-reconnect-ids ()
+  (let ((connect (lambda ()
+                   (with-current-buffer "oofnet"
+                     (erc-cmd-RECONNECT)
+                     (should (eq (current-buffer)
+                                 (process-buffer erc-server-process)))
+                     (current-buffer)))))
+    (erc-scenarios-common--join-network-id connect 'oofnet 'rabnet)))
+
+(ert-deftest erc-scenarios-join-network-id--new-invocation ()
+  (let ((connect (lambda ()
+                   (erc :server "127.0.0.1"
+                        :port (with-current-buffer "foonet"
+                                (process-contact erc-server-process :service))
+                        :nick "tester"
+                        :password "foonet:changeme"
+                        :full-name "tester"))))
+    (erc-scenarios-common--join-network-id connect nil nil)))
+
+(ert-deftest erc-scenarios-join-network-id--new-invocation-id ()
+  (let ((connect (lambda ()
+                   (erc :server "127.0.0.1"
+                        :port (with-current-buffer "oofnet"
+                                (process-contact erc-server-process :service))
+                        :nick "tester"
+                        :password "foonet:changeme"
+                        :full-name "tester"
+                        :id 'oofnet))))
+    (erc-scenarios-common--join-network-id connect 'oofnet nil)))
+
+(ert-deftest erc-scenarios-join-network-id--new-invocation-ids ()
+  (let ((connect (lambda ()
+                   (erc :server "127.0.0.1"
+                        :port (with-current-buffer "oofnet"
+                                (process-contact erc-server-process :service))
+                        :nick "tester"
+                        :password "foonet:changeme"
+                        :full-name "tester"
+                        :id 'oofnet))))
+    (erc-scenarios-common--join-network-id connect 'oofnet 'rabnet)))
+
+;; Ensure the old way of specifying a partial domain name still works.
+
+(ert-deftest erc-scenarios-base-legacy-autojoin--announced ()
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "join/legacy")
+       (erc-d-linger-secs 1)
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'foonet))
+       (port (process-contact dumb-server :service))
+       (erc-autojoin-channels-alist '(("libera\\.chat" "#erc")
+                                      ("foonet\\.org" "#chan"))))
+
+    (ert-info ("Connect")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+    (erc-d-t-wait-for 1 (get-buffer "FooNet"))
+
+    (ert-info ("Channel buffer #chan autojoined")
+      (with-current-buffer (erc-d-t-wait-for 6 (get-buffer "#chan"))
+        (erc-d-t-search-for 10 "Live, and be prosperous")))))
+
+(ert-deftest erc-scenarios-join-reconnect ()
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "join/reconnect")
+       (dumb-server (erc-d-run "localhost" t 'foonet 'foonet-again))
+       (port (process-contact dumb-server :service))
+       (expect (erc-d-t-make-expecter))
+       (erc-server-flood-penalty 0.1)
+       (erc-server-auto-reconnect t)
+       erc-autojoin-channels-alist
+       erc-server-buffer)
+
+    (should (memq 'autojoin erc-modules))
+
+    (ert-info ("Connect to foonet")
+      (setq erc-server-buffer (erc :server "127.0.0.1"
+                                   :port port
+                                   :nick "tester"
+                                   :password "changeme"
+                                   :full-name "tester"))
+      (with-current-buffer erc-server-buffer
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+        (funcall expect 1 "debug mode")))
+
+    (ert-info ("Wait for some output in channels")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+        (funcall expect 10 "welcome"))
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
+        (funcall expect 10 "welcome")))
+
+    (should (equal erc-autojoin-channels-alist '((FooNet "#spam" "#chan"))))
+
+    (ert-info ("Wait for auto reconnect")
+      (with-current-buffer erc-server-buffer
+        (funcall expect 10 "still in debug mode")))
+
+    (ert-info ("Wait for activity to recommence in channels")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+        (funcall expect 10 "forest of Arden"))
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
+        (funcall expect 10 "her elves come here anon")))))
+
 ;; Playback for same channel on two networks routed correctly.
 ;; Originally from Bug#48598: 28.0.50; buffer-naming collisions
 ;; involving bouncers in ERC.
@@ -1286,7 +1522,7 @@ erc-scenarios-common--base-reconnect-options
       (with-current-buffer erc-server-buffer
         (funcall expect 10 "Connection failed!  Re-establishing")))
 
-    (should (equal erc-autojoin-channels-alist '(("foonet.org" "#chan"))))
+    (should (equal erc-autojoin-channels-alist '((FooNet "#chan"))))
 
     (funcall test)
 
-- 
2.35.1
0025-SQUASH-ME-Add-ERC-test-scenarios-involving-auth-sour.patch (text/x-patch, 16.3 KB)
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Wed, 29 Sep 2021 01:30:16 -0700
Subject: [PATCH 25/34] SQUASH-ME: Add ERC test scenarios involving auth-source

XXX this should be combined with the commit entitled "Make auth-source
searches session-ID aware in ERC".  It was split off for the sake of
flexibility during code review.

* test/lisp/erc/erc-scenarios.el: Add session-aware scenarios
involving the auth-source queries.  See bug#48598 for background.
---
 .../base/auth-source/foonet.eld               |  23 +++
 .../base/auth-source/nopass.eld               |  22 +++
 .../services/auth-source/libera.eld           |  49 +++++++
 test/lisp/erc/erc-scenarios.el                | 132 ++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 test/lisp/erc/erc-scenarios-resources/base/auth-source/foonet.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/base/auth-source/nopass.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/services/auth-source/libera.eld

diff --git a/test/lisp/erc/erc-scenarios-resources/base/auth-source/foonet.eld b/test/lisp/erc/erc-scenarios-resources/base/auth-source/foonet.eld
new file mode 100644
index 0000000000..1fe772c7e2
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/base/auth-source/foonet.eld
@@ -0,0 +1,23 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
diff --git a/test/lisp/erc/erc-scenarios-resources/base/auth-source/nopass.eld b/test/lisp/erc/erc-scenarios-resources/base/auth-source/nopass.eld
new file mode 100644
index 0000000000..3fdb4ecf7b
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/base/auth-source/nopass.eld
@@ -0,0 +1,22 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
diff --git a/test/lisp/erc/erc-scenarios-resources/services/auth-source/libera.eld b/test/lisp/erc/erc-scenarios-resources/services/auth-source/libera.eld
new file mode 100644
index 0000000000..c8dbc9d425
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/services/auth-source/libera.eld
@@ -0,0 +1,49 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.26 ":zirconium.libera.chat NOTICE * :*** Checking Ident")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** Looking up your hostname...")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** No Ident response")
+ (0.02 ":zirconium.libera.chat NOTICE * :*** Found your hostname: static-198-54-131-100.cust.tzulo.com")
+ (0.02 ":zirconium.libera.chat 001 tester :Welcome to the Libera.Chat Internet Relay Chat Network tester")
+ (0.01 ":zirconium.libera.chat 002 tester :Your host is zirconium.libera.chat[46.16.175.175/6697], running version solanum-1.0-dev")
+ (0.03 ":zirconium.libera.chat 003 tester :This server was created Wed Jun 9 2021 at 01:38:28 UTC")
+ (0.02 ":zirconium.libera.chat 004 tester zirconium.libera.chat solanum-1.0-dev DGQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI")
+ (0.00 ":zirconium.libera.chat 005 tester ETRACE WHOX FNC MONITOR=100 SAFELIST ELIST=CTU CALLERID=g KNOCK CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz :are supported by this server")
+ (0.03 ":zirconium.libera.chat 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=Libera.Chat STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server")
+ (0.02 ":zirconium.libera.chat 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 :are supported by this server")
+ (0.02 ":zirconium.libera.chat 251 tester :There are 68 users and 37640 invisible on 25 servers")
+ (0.00 ":zirconium.libera.chat 252 tester 36 :IRC Operators online")
+ (0.01 ":zirconium.libera.chat 253 tester 5 :unknown connection(s)")
+ (0.00 ":zirconium.libera.chat 254 tester 19341 :channels formed")
+ (0.01 ":zirconium.libera.chat 255 tester :I have 3321 clients and 1 servers")
+ (0.01 ":zirconium.libera.chat 265 tester 3321 4289 :Current local users 3321, max 4289")
+ (0.00 ":zirconium.libera.chat 266 tester 37708 38929 :Current global users 37708, max 38929")
+ (0.01 ":zirconium.libera.chat 250 tester :Highest connection count: 4290 (4289 clients) (38580 connections received)")
+ (0.21 ":zirconium.libera.chat 375 tester :- zirconium.libera.chat Message of the Day - ")
+ (0.00 ":zirconium.libera.chat 372 tester :- This server provided by Seeweb <https://www.seeweb.it/>")
+ (0.01 ":zirconium.libera.chat 372 tester :- Welcome to Libera Chat, the IRC network for")
+ (0.01 ":zirconium.libera.chat 372 tester :- free & open-source software and peer directed projects.")
+ (0.00 ":zirconium.libera.chat 372 tester :-  ")
+ (0.00 ":zirconium.libera.chat 372 tester :- Use of Libera Chat is governed by our network policies.")
+ (0.00 ":zirconium.libera.chat 372 tester :-  ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Please visit us in #libera for questions and support.")
+ (0.01 ":zirconium.libera.chat 372 tester :-  ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Website and documentation:  https://libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Webchat:                    https://web.libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Network policies:           https://libera.chat/policies")
+ (0.01 ":zirconium.libera.chat 372 tester :- Email:                      [email protected]")
+ (0.00 ":zirconium.libera.chat 376 tester :End of /MOTD command."))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.02 ":tester MODE tester :+Zi")
+ (0.02 ":[email protected] NOTICE tester :This nickname is registered. Please choose a different nickname, or identify via \2/msg NickServ IDENTIFY tester <password>\2"))
+
+((privmsg 2 "PRIVMSG NickServ :IDENTIFY changeme")
+ (0.96 ":[email protected] NOTICE tester :You are now identified for \2tester\2.")
+ (0.25 ":[email protected] NOTICE tester :Last login from: \[email protected]/tester\2 on Jun 18 01:15:56 2021 +0000."))
+
+((quit 5 "QUIT :\2ERC\2")
+ (0.19 ":[email protected] QUIT :Client Quit"))
+
+((linger 1 LINGER))
diff --git a/test/lisp/erc/erc-scenarios.el b/test/lisp/erc/erc-scenarios.el
index 37b58227e7..94a3a5bb37 100644
--- a/test/lisp/erc/erc-scenarios.el
+++ b/test/lisp/erc/erc-scenarios.el
@@ -1899,6 +1899,138 @@ erc-scenarios-base-association-nick-bumped-mandated-renick
       (should (not (get-buffer "foonet/dummy")))
       (should (get-buffer "foonet")))))
 
+;; Auth source consulted for initial PASS arg.  Option
+;;  `erc-connect-auth-source-host' obeyed.
+
+(defun erc-scenarios-common--auth-source (id dialog &rest rest)
+  (push "machine GNU.chat port %d user \"#chan\" password spam" rest)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/auth-source")
+       (dumb-server (erc-d-run "localhost" t dialog))
+       (port (process-contact dumb-server :service))
+       (ents `(,@(mapcar (lambda (fmt) (format fmt port)) rest)
+               "machine MyHost port irc password 123"))
+       (netrc-file (make-temp-file "auth-source-test" nil nil
+                                   (string-join ents "\n")))
+       (auth-sources (list netrc-file))
+       (auth-source-do-cache nil)
+       (erc-scenarios-common-extra-teardown (lambda ()
+                                              (delete-file netrc-file))))
+
+    (ert-info ("Connect")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :full-name "tester"
+                                :id id)
+        (should (string= (buffer-name) (if id
+                                           (symbol-name id)
+                                         (format "127.0.0.1:%d" port))))
+        (erc-d-t-wait-for 1 (eq erc-network 'FooNet))))))
+
+(ert-deftest erc-scenarios-base-auth-source--dialed ()
+  (should (eq erc-connect-auth-source-host 'server))
+  (erc-scenarios-common--auth-source
+   nil 'foonet
+   "machine GNU.chat port %d user tester password fake"
+   "machine 127.0.0.1 port %d user tester password changeme"
+   "machine 127.0.0.1 port %d user imposter password fake"))
+
+(ert-deftest erc-scenarios-base-auth-source--dialed-fallback ()
+  (let ((erc-connect-auth-source-host t))
+    (erc-scenarios-common--auth-source
+     nil 'foonet
+     "machine FooNet port %d user tester password fake"
+     "machine 127.0.0.1 port %d user tester password changeme"
+     "machine 127.0.0.1 port %d user imposter password fake")))
+
+(ert-deftest erc-scenarios-base-auth-source--network-id ()
+  (let ((erc-connect-auth-source-host t))
+    (erc-scenarios-common--auth-source
+     'MySession 'foonet
+     "machine MySession port %d user tester password changeme"
+     "machine 127.0.0.1 port %d user tester password fake"
+     "machine FooNet port %d user tester password fake")))
+
+(ert-deftest erc-scenarios-base-auth-source--string--network-id ()
+  (let ((erc-connect-auth-source-host "MyHost"))
+    (erc-scenarios-common--auth-source
+     'MySession 'foonet
+     "machine 127.0.0.1 port %d user tester password fake"
+     "machine MyHost port %d user tester password changeme"
+     "machine MySession port %d user tester password fake")))
+
+(ert-deftest erc-scenarios-base-auth-source--nopass ()
+  (let (erc-connect-auth-source-host) ; nil
+    (erc-scenarios-common--auth-source nil 'nopass)))
+
+(ert-deftest erc-scenarios-base-auth-source--nopass--network-id ()
+  (let (erc-connect-auth-source-host) ; nil
+    (erc-scenarios-common--auth-source 'MySession 'nopass)))
+
+;; Identify via auth source with no initial password
+
+(defun erc-scenarios-common--services-auth-source (&rest rest)
+  (defvar erc-use-auth-source-for-nickserv-password)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "services/auth-source")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'libera))
+       (port (process-contact dumb-server :service))
+       (ents `(,@(mapcar (lambda (fmt) (format fmt port)) rest)
+               "machine MyHost port irc password 123"))
+       (netrc-file (make-temp-file "auth-source-test" nil nil
+                                   (string-join ents "\n")))
+       (auth-sources (list netrc-file))
+       (auth-source-do-cache nil)
+       (erc-modules (cons 'services erc-modules))
+       (erc-use-auth-source-for-nickserv-password t) ; do consult for NickServ
+       (expect (erc-d-t-make-expecter))
+       (erc-scenarios-common-extra-teardown (lambda ()
+                                              (delete-file netrc-file))))
+
+    (cl-letf (((symbol-function 'read-passwd)
+               (lambda (&rest _) (error "Unexpected read-passwd call"))))
+      (ert-info ("Connect without password")
+        (with-current-buffer (erc :server "127.0.0.1"
+                                  :port port
+                                  :nick "tester"
+                                  :full-name "tester")
+          (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+          (erc-d-t-wait-for 3 (eq erc-network 'Libera.Chat))
+          (funcall expect 3 "This nickname is registered.")
+          (funcall expect 3 "You are now identified")
+          (funcall expect 3 "Last login from")
+          (erc-cmd-QUIT ""))))
+
+    (erc-services-mode -1)
+
+    (should-not (memq 'services erc-modules))))
+
+(ert-deftest erc-scenarios-services-auth-source--network ()
+  (let (erc-connect-auth-source-host) ; don't consult auth-source for PASS
+    (erc-scenarios-common--services-auth-source
+     "machine 127.0.0.1 port %d user tester password spam"
+     "machine zirconium.libera.chat port %d user tester password fake"
+     "machine Libera.Chat port %d user tester password changeme")))
+
+(ert-deftest erc-scenarios-services-auth-source--network-connect-lookup ()
+  (should (eq erc-connect-auth-source-host 'server))
+  (erc-scenarios-common--services-auth-source
+   "machine zirconium.libera.chat port %d user tester password fake"
+   "machine Libera.Chat port %d user tester password changeme"))
+
+(ert-deftest erc-scenarios-services-auth-source--announced ()
+  (let (erc-connect-auth-source-host) ; don't consult auth-source for PASS
+    (erc-scenarios-common--services-auth-source
+     "machine 127.0.0.1 port %d user tester password spam"
+     "machine zirconium.libera.chat port %d user tester password changeme")))
+
+(ert-deftest erc-scenarios-services-auth-source--dialed ()
+  (let (erc-connect-auth-source-host) ; don't consult auth-source for PASS
+    (erc-scenarios-common--services-auth-source
+     "machine 127.0.0.1 port %d user tester password changeme")))
+
 (ert-deftest erc-scenarios-services-password ()
 
   (erc-scenarios-common-with-cleanup
-- 
2.35.1
0026-SQUASH-ME-Add-ERC-test-scenario-for-erc-cmd-JOIN.patch (text/x-patch, 17.6 KB)
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Thu, 30 Sep 2021 06:29:24 -0700
Subject: [PATCH 26/34] SQUASH-ME: Add ERC test scenario for erc-cmd-JOIN

DELETE THIS NOTE: This scenario belongs here because it indirectly
asserts that the changes to erc-cmd-JOIN work as intended.  See note
atop the `ert-deftest' and helper.

The assertion involving the presence of an entry for the current user
in a defunct channel buffer has to do with trying to shift to a
cleaner means of checking whether a channel buffer is subscribed
to (whether it's JOINed or PARTed).  The old means of checking,
basically seeing whether `erc-default-target' is non-nil, depends on
`erc-default-recipients', whose purpose has never been well defined.
---
 .../reuse-buffers/channel-buffers/barnet.eld  |  68 +++++++++++
 .../reuse-buffers/channel-buffers/foonet.eld  |  66 +++++++++++
 test/lisp/erc/erc-scenarios.el                | 109 ++++++++++++++++++
 3 files changed, 243 insertions(+)
 create mode 100644 test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/barnet.eld
 create mode 100644 test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/foonet.eld

diff --git a/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/barnet.eld b/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/barnet.eld
new file mode 100644
index 0000000000..c90c399aed
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/barnet.eld
@@ -0,0 +1,68 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :barnet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 05 May 2021 09:05:33 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :joe @mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***[email protected] PRIVMSG #chan :Buffer Playback...")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:16] joe: Tush! none but minstrels like of sonneting.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:19] mike: Prithee, nuncle, be contented; 'tis a naughty night to swim in. Now a little fire in a wide field were like an old lecher's heart; a small spark, all the rest on's body cold. Look! here comes a walking fire.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:22] joe: My name is Edgar, and thy father's son.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:26] mike: Good my lord, be good to me; your honour is accounted a merciful man; good my lord.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:31] joe: Thy child shall live, and I will see it nourish'd.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:33] mike: Quick, quick; fear nothing; I'll be at thy elbow.")
+ (0 ":***[email protected] PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.barnet.org NOTICE tester :[09:05:35] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620205534")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: That will be given to the loudest noise we make.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: If it please your honour, I am the poor duke's constable, and my name is Elbow: I do lean upon justice, sir; and do bring in here before your good honour two notorious benefactors.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Following the signs, woo'd but the sign of she.")
+ (0.5 ":[email protected] PRIVMSG #chan :mike: That, sir, which I will not report after her.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Boyet, prepare: I will away to-night.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: If the man be a bachelor, sir, I can; but if he be a married man, he is his wife's head, and I can never cut off a woman's head.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Thyself upon thy virtues, they on thee.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: Arm it in rags, a pigmy's straw doth pierce it."))
+
+((part 5.1 "PART #chan :" quit)
+ (0 ":[email protected] PART #chan :" quit))
+
+((join 10.1 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@mike joe tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0 ":[email protected] PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620205534")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Chi non te vede, non te pretia.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: Well, if ever thou dost fall from this faith, thou wilt prove a notable argument.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Of heavenly oaths, vow'd with integrity.")
+ (0.1 ":[email protected] PRIVMSG #chan :mike: These herblets shall, which we upon you strew.")
+ (0.1 ":[email protected] PRIVMSG #chan :joe: Aaron will have his soul black like his face."))
+
+((linger 0.5 LINGER))
diff --git a/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/foonet.eld b/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/foonet.eld
new file mode 100644
index 0000000000..648321875b
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-resources/base/reuse-buffers/channel-buffers/foonet.eld
@@ -0,0 +1,66 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 05 May 2021 09:05:34 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***[email protected] PRIVMSG #chan :Buffer Playback...")
+ (0 ":[email protected] PRIVMSG #chan :[09:07:19] bob: Is this; she hath bought the name of whore thus dearly.")
+ (0 ":[email protected] PRIVMSG #chan :[09:07:24] alice: He sent to me, sir,Here he comes.")
+ (0 ":[email protected] PRIVMSG #chan :[09:07:26] bob: Till I torment thee for this injury.")
+ (0 ":[email protected] PRIVMSG #chan :[09:07:29] alice: There's an Italian come; and 'tis thought, one of Leonatus' friends.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:33] bob: Ay, and the particular confirmations, point from point, to the full arming of the verity.")
+ (0 ":[email protected] PRIVMSG #chan :[09:09:35] alice: Kneel in the streets and beg for grace in vain.")
+ (0 ":***[email protected] PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:06:05] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620205534")
+ (0.5 ":[email protected] PRIVMSG #chan :alice: Nor I no strength to climb without thy help.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: Nothing, but let him have thanks. Demand of him my condition, and what credit I have with the duke.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Show me this piece. I am joyful of your sights.")
+ (0.2 ":[email protected] PRIVMSG #chan :bob: Whilst I can shake my sword or hear the drum."))
+
+((part 5 "PART #chan :" quit)
+ (0 ":[email protected] PART #chan :" quit))
+
+((join 10 "JOIN #chan")
+ (0 ":[email protected] JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@bob alice tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":[email protected] PRIVMSG #chan :tester, welcome!")
+ (0 ":[email protected] PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620205534")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Thou desirest me to stop in my tale against the hair.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: And dar'st not stand, nor look me in the face.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: It should not be, by the persuasion of his new feasting.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: It was not given me, nor I did not buy it.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: He that would vouch it in any place but here.")
+ (0.1 ":[email protected] PRIVMSG #chan :bob: In everything I wait upon his will.")
+ (0.1 ":[email protected] PRIVMSG #chan :alice: Thou counterfeit'st most lively."))
+
+((linger 8 LINGER))
diff --git a/test/lisp/erc/erc-scenarios.el b/test/lisp/erc/erc-scenarios.el
index 94a3a5bb37..2fbb7b51da 100644
--- a/test/lisp/erc/erc-scenarios.el
+++ b/test/lisp/erc/erc-scenarios.el
@@ -1014,6 +1014,115 @@ erc-scenarios-base-reuse-buffers-server-buffers--disabled
         erc-reuse-buffers)
     (erc-scenarios-common--base-reuse-buffers-server-buffers)))
 
+;; This also asserts that `erc-cmd-JOIN' is no longer susceptible to a
+;; regression introduced in 28.1 (ERC 5.4) that caused phantom target
+;; buffers of the form target/server to be created via
+;; `switch-to-buffer' ("phantom" because they would go unused").  This
+;; would happen (in place of a JOIN being sent out) when a previously
+;; used (parted) target buffer existed and `erc-reuse-buffers' was
+;; nil.
+;;
+;; Note: All the `erc-get-channel-user' calls have to do with the fact
+;; that `erc-default-target' relies on the less-than-well-defined
+;; `erc-default-recipients' and is thus overloaded in the sense of
+;; being used both for retrieving a target name and checking if
+;; channel has been PARTed.  While not ideal, `erc-get-channel-user'
+;; can (also) be used to detect the latter.
+
+(defun erc-scenarios-common--base-reuse-buffers-channel-buffers ()
+  "The option `erc-reuse-buffers' is still respected when nil.
+Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
+28.0.50; buffer-naming collisions involving bouncers in ERC."
+  (let ((expect (erc-d-t-make-expecter))
+        (server-process-bar (with-current-buffer "barnet" erc-server-process))
+        (server-process-foo (with-current-buffer "foonet" erc-server-process)))
+
+    (ert-info ("Unique #chan buffers exist")
+      (let ((chan-bufs (erc-scenarios-common-buflist "#chan"))
+            (names '("#chan@barnet" "#chan@foonet")))
+        (should (member (buffer-name (pop chan-bufs)) names))
+        (should (member (buffer-name (pop chan-bufs)) names))
+        (should-not chan-bufs)))
+
+    (ert-info ("#chan@foonet is exclusive and not contaminated")
+      (with-current-buffer "#chan@foonet"
+        (funcall expect 1 "<bob>")
+        (erc-d-t-absent-for 0.1 "<joe>")
+        (funcall expect 1 "strength to climb")
+        (should (eq erc-server-process server-process-foo))))
+
+    (ert-info ("#chan@barnet is exclusive and not contaminated")
+      (with-current-buffer "#chan@barnet"
+        (funcall expect 1 "<joe>")
+        (erc-d-t-absent-for 0.1 "<bob>")
+        (funcall expect 1 "the loudest noise")
+        (should (eq erc-server-process server-process-bar))))
+
+    (ert-info ("Part #chan@foonet")
+      (with-current-buffer "#chan@foonet"
+        (erc-d-t-search-for 1 "shake my sword")
+        (erc-cmd-PART "#chan")
+        (funcall expect 3 "You have left channel #chan")
+        (erc-cmd-JOIN "#chan")))
+
+    (ert-info ("Part #chan@barnet")
+      (with-current-buffer "#chan@barnet"
+        (funcall expect 3 "Arm it in rags")
+        (should (erc-get-channel-user (erc-current-nick)))
+        (erc-cmd-PART "#chan")
+        (funcall expect 3 "You have left channel #chan")
+        (should-not (erc-get-channel-user (erc-current-nick)))
+        (erc-cmd-JOIN "#chan")))
+
+    (erc-d-t-wait-for 3 "New unique target buffer for #chan@foonet created"
+      (get-buffer "#chan@foonet<2>"))
+
+    (ert-info ("Activity continues in new, <n>-suffixed #chan@foonet buffer")
+      (with-current-buffer "#chan@foonet"
+        (should-not (erc-get-channel-user (erc-current-nick))))
+      (with-current-buffer "#chan@foonet<2>"
+        (should (erc-get-channel-user (erc-current-nick)))
+        (funcall expect 2 "You have joined channel #chan")
+        (funcall expect 2 "#chan was created on")
+        (funcall expect 2 "<alice>")
+        (should (eq erc-server-process server-process-foo))
+        (erc-d-t-absent-for 0.2 "<joe>")))
+
+    (erc-d-t-wait-for 3 "New unique target buffer for #chan@barnet created"
+      (get-buffer "#chan@barnet<2>"))
+
+    (ert-info ("Activity continues in new, <n>-suffixed #chan@barnet buffer")
+      (with-current-buffer "#chan@barnet"
+        (should-not (erc-get-channel-user (erc-current-nick))))
+      (with-current-buffer "#chan@barnet<2>"
+        (funcall expect 2 "You have joined channel #chan")
+        (funcall expect 1 "Users on #chan: @mike joe tester")
+        (funcall expect 2 "<mike>")
+        (should (eq erc-server-process server-process-bar))
+        (erc-d-t-absent-for 0.2 "<bob>")))
+
+    (ert-info ("Two new chans created for a total of four")
+      (let* ((bufs (erc-scenarios-common-buflist "#chan"))
+             (names (sort (mapcar #'buffer-name bufs) #'string<)))
+        (should (equal names '("#chan@barnet" "#chan@barnet<2>"
+                               "#chan@foonet" "#chan@foonet<2>")))))
+
+    (ert-info ("All output sent")
+      (with-current-buffer "#chan@foonet<2>"
+        (while (accept-process-output server-process-foo))
+        (funcall expect 3 "most lively"))
+      (with-current-buffer "#chan@barnet<2>"
+        (while (accept-process-output server-process-bar))
+        (funcall expect 3 "soul black")))))
+
+(ert-deftest erc-scenarios-base-reuse-buffers-channel-buffers--disabled ()
+  (should erc-reuse-buffers)
+  (let ((erc-scenarios-common-dialog "base/reuse-buffers/channel-buffers")
+        (erc-server-flood-penalty 0.1)
+        erc-reuse-buffers)
+    (erc-scenarios-common--base-reuse-buffers-server-buffers
+     #'erc-scenarios-common--base-reuse-buffers-channel-buffers)))
+
 ;; The server changes your nick just after registration.
 
 (ert-deftest erc-scenarios-base-renick-self-auto ()
-- 
2.35.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.