Reassociate erc-networks--id for orphaned queries

* lisp/erc/erc-networks.el (erc-networks--examine-targets): Adopt the
server's network ID in query buffers created before MOTD's end.  Do
this to avoid a type error in the process filter when renaming
buffers.
* lisp/erc/erc-networks.el (erc-networks--examine-targets): New test.
* test/lisp/erc/erc-scenarios-base-upstream-recon-znc.el
(erc-scenarios-upstream-recon--znc/severed): New test.
* test/lisp/erc/erc-scenarios-misc.el
(erc-scenarios-base-mask-target-routing): Adjust timeout.
* test/lisp/erc/resources/base/upstream-reconnect/znc-severed.eld:
New file.
* test/lisp/erc/resources/erc-tests-common.el
(erc-tests-common-make-server-buf): Use NAME parameter for creating
ID.
This commit is contained in:
F. Jason Park 2024-01-31 06:01:54 -08:00
parent b7cdce0970
commit aa6315ee68
6 changed files with 202 additions and 6 deletions

View file

@ -1123,10 +1123,27 @@ TARGET to be an `erc--target' object."
(lambda ()
(when (and erc--target (eq (erc--target-symbol erc--target)
(erc--target-symbol target)))
(let ((oursp (if (erc--target-channel-local-p target)
(equal announced erc-server-announced-name)
(erc-networks--id-equal-p identity erc-networks--id))))
(funcall (if oursp on-dupe on-collision))))))))
;; When a server sends administrative queries immediately
;; after connection registration and before the session has a
;; net-id, the buffer remains orphaned until reassociated
;; here retroactively.
(unless erc-networks--id
(let ((id (erc-with-server-buffer erc-networks--id))
(server-buffer (process-buffer erc-server-process)))
(apply #'erc-button--display-error-notice-with-keys
server-buffer
(concat "Missing network session (ID) for %S. "
(if id "Using `%S' from %S." "Ignoring."))
(current-buffer)
(and id (list (erc-networks--id-symbol
(setq erc-networks--id id))
server-buffer)))))
(when erc-networks--id
(let ((oursp (if (erc--target-channel-local-p target)
(equal announced erc-server-announced-name)
(erc-networks--id-equal-p identity
erc-networks--id))))
(funcall (if oursp on-dupe on-collision)))))))))
(defconst erc-networks--qualified-sep "@"
"Separator used for naming a target buffer.")

View file

@ -1761,4 +1761,50 @@
(should (equal (erc-ports-list (nth 4 srv))
'(6697 9999))))))
(ert-deftest erc-networks--examine-targets ()
(with-current-buffer (erc-tests-common-make-server-buf "foonet")
(erc--open-target "#chan")
(erc--open-target "#spam"))
(with-current-buffer (erc-tests-common-make-server-buf "barnet")
(with-current-buffer (erc--open-target "*query")
(setq erc-networks--id nil))
(with-current-buffer (erc--open-target "#chan")
(let ((calls ())
(snap (lambda (parameter)
(list parameter
(erc-target)
(erc-networks--id-symbol erc-networks--id)))))
;; Search for "#chan" dupes among targets of all servers.
(should (equal
(erc-networks--examine-targets erc-networks--id erc--target
(lambda () (push (funcall snap 'ON-DUPE) calls))
(lambda () (push (funcall snap 'ON-COLL) calls)))
(list (get-buffer "#chan@foonet")
(get-buffer "#chan@barnet"))))
(should (equal (pop calls) '(ON-DUPE "#chan" barnet)))
(should (equal (pop calls) '(ON-COLL "#chan" foonet)))
(should-not calls)
(should-not (get-buffer "#chan"))
(should (get-buffer "#chan@barnet"))
(should (get-buffer "#chan@foonet"))
;; Search for "*query" dupes among targets of all servers.
(should (equal (erc-networks--examine-targets erc-networks--id
(buffer-local-value 'erc--target
(get-buffer "*query"))
(lambda () (push (funcall snap 'ON-DUPE) calls))
(lambda () (push (funcall snap 'ON-COLL) calls)))
(list (get-buffer "*query"))))
(should (equal (pop calls) '(ON-DUPE "*query" barnet)))
(should-not calls)))
(goto-char (point-min))
(should (search-forward "Missing network session" nil t)))
(erc-tests-common-kill-buffers))
;;; erc-networks-tests.el ends here

View file

@ -42,4 +42,50 @@
'znc-foonet
'znc-barnet))
;; Here, the upstream connection is already severed when first
;; connecting. The bouncer therefore sends query messages from an
;; administrative bot before the first numerics burst, which results
;; in a target buffer not being associated with an `erc-networks--id'.
;; The problem only manifests later, when the buffer-association
;; machinery checks the names of all target buffers and assumes a
;; non-nil `erc-networks--id'.
(ert-deftest erc-scenarios-upstream-recon--znc/severed ()
(erc-scenarios-common-with-cleanup
((erc-scenarios-common-dialog "base/upstream-reconnect")
(erc-d-t-cleanup-sleep-secs 1)
(erc-server-flood-penalty 0.1)
(dumb-server (erc-d-run "localhost" t 'znc-severed))
(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"
:user "tester@vanilla/foonet"
:password "changeme"
:full-name "tester")
(erc-scenarios-common-assert-initial-buf-name nil port)
(erc-d-t-wait-for 6 (eq (erc-network) 'foonet))))
(with-current-buffer (erc-d-t-wait-for 5 (get-buffer "*status"))
(funcall expect 10 "Connection Refused. Reconnecting...")
(funcall expect 10 "Connected!"))
(ert-info ("Join #chan")
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
(funcall expect 10 "<alice> tester, welcome!")
(funcall expect 10 "<bob> alice: And see a fearful sight")
(funcall expect 10 "<eve> hola")
(funcall expect 10 "<Evel> hell o")
;;
(funcall expect 10 "<alice> bob: Or to drown my clothes")))
(ert-info ("Buffer not renamed with net id")
(should (get-buffer "*status")))
(ert-info ("No error")
(with-current-buffer (messages-buffer)
(funcall expect -0.1 "error in process filter")))))
;;; erc-scenarios-base-upstream-recon-znc.el ends here

View file

@ -126,7 +126,7 @@
(erc-d-t-wait-for 10 (get-buffer "foonet"))
(ert-info ("Channel buffer #foo playback received")
(with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#foo"))
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#foo"))
(funcall expect 10 "Excellent workman")))
(ert-info ("Global notices routed to server buffer")

View file

@ -0,0 +1,87 @@
;; -*- mode: lisp-data; -*-
((pass 10 "PASS :changeme"))
((nick 10 "NICK tester"))
((user 10 "USER tester@vanilla/foonet 0 * :tester")
(0.00 ":irc.znc.in 001 tester :Welcome to ZNC")
(0.03 ":*status!znc@znc.in PRIVMSG tester :Connection Refused. Reconnecting...")
(0.01 ":*status!znc@znc.in PRIVMSG tester :Connection Refused. Reconnecting...")
(0.00 ":*status!znc@znc.in PRIVMSG tester :Connection Refused. Reconnecting...")
(0.01 ":*status!znc@znc.in PRIVMSG tester :Connected!")
(0.02 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
(0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
(0.01 ":irc.foonet.org 003 tester :This server was created Wed, 31 Jan 2024 10:58:16 UTC")
(0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
(0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
(0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
(0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server")
(0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
(0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
(0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
(0.00 ":irc.foonet.org 254 tester 1 :channels formed")
(0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
(0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
(0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
(0.00 ":irc.foonet.org 422 tester :MOTD File is missing")
(0.00 ":irc.foonet.org 221 tester +Zi")
(0.00 ":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."))
((mode 10 "MODE tester +i")
(0.01 ":irc.foonet.org 352 tester * ~u pfa3tpa5ig5ty.irc irc.foonet.org tester H :0 ZNC - https://znc.in")
(0.01 ":irc.foonet.org 315 tester tester :End of WHO list")
(0.02 ":tester!~u@pfa3tpa5ig5ty.irc JOIN #chan")
(0.03 ":irc.foonet.org 353 tester = #chan :bob tester @alice eve"))
((mode 10 "MODE #chan")
(0.00 ":irc.foonet.org 366 tester #chan :End of NAMES list")
(0.00 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :tester, welcome!")
(0.01 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :tester, welcome!")
(0.01 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :alice: And see how he will take it at your hands.")
(0.02 ":irc.foonet.org 221 tester +Zi")
(0.01 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: Fear not, my lord, your servant shall do so.")
(0.02 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :alice: If I thrive well, I'll visit thee again.")
(0.01 ":irc.foonet.org 324 tester #chan +Cnt")
(0.03 ":irc.foonet.org 329 tester #chan 1706698713")
(0.05 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: Let it be forbid, sir; so should I be a great deal of his act.")
(0.04 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :alice: And see a fearful sight of blood and death.")
(0.00 ":eve!~u@euegh6mj3y8r2.irc PRIVMSG #chan :hola")
(0.01 ":eve!~u@euegh6mj3y8r2.irc NICK :Evel")
(0.01 ":Evel!~u@euegh6mj3y8r2.irc PRIVMSG #chan :hell o")
(0.02 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: His highness comes post from Marseilles, of as able body as when he numbered thirty: he will be here to-morrow, or I am deceived by him that in such intelligence hath seldom failed.")
(0.03 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :alice: See, by good hap, yonder's my lord; I have sweat to see his honour.")
(0.02 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: With the rich worth of your virginity.")
(0.02 ":*status!znc@znc.in PRIVMSG tester :Disconnected from IRC. Reconnecting...")
(0.05 ":*status!znc@znc.in PRIVMSG tester :Connection Refused. Reconnecting...")
(0.03 ":*status!znc@znc.in PRIVMSG tester :Connected!")
(0.01 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
(0.04 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
(0.01 ":irc.foonet.org 003 tester :This server was created Wed, 31 Jan 2024 10:58:16 UTC")
(0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
(0.03 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
(0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
(0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server")
(0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
(0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
(0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
(0.00 ":irc.foonet.org 254 tester 1 :channels formed")
(0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
(0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
(0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
(0.00 ":irc.foonet.org 422 tester :MOTD File is missing")
(0.02 ":irc.foonet.org 221 tester +i")
(0.01 ":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.")
(0.02 ":irc.foonet.org 352 tester * ~u hrn2ea3rpeyck.irc irc.foonet.org tester H :0 ZNC - https://znc.in")
(0.01 ":irc.foonet.org 315 tester tester :End of WHO list")
(0.02 ":tester!~u@hrn2ea3rpeyck.irc JOIN #chan"))
((mode 10 "MODE #chan")
(0.00 ":irc.foonet.org 353 tester = #chan :tester @alice bob")
(0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list")
(0.00 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :tester, welcome!")
(0.01 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :tester, welcome!")
(0.02 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: Nay, I assure you, a peace concluded.")
(0.03 ":irc.foonet.org 324 tester #chan +Cnt")
(0.01 ":irc.foonet.org 329 tester #chan 1706698713")
(0.05 ":bob!~u@euegh6mj3y8r2.irc PRIVMSG #chan :alice: But, in defence, by mercy, 'tis most just.")
(0.04 ":alice!~u@euegh6mj3y8r2.irc PRIVMSG #chan :bob: Or to drown my clothes, and say I was stripped."))

View file

@ -122,7 +122,7 @@ Use NAME for the network and the session server as well."
erc--isupport-params (make-hash-table)
erc-session-port 6667
erc-network (intern name)
erc-networks--id (erc-networks--id-create nil))
erc-networks--id (erc-networks--id-create name))
(current-buffer)))
(defun erc-tests-common-string-to-propertized-parts (string)