2 Commits

35 changed files with 224 additions and 550 deletions

View File

@ -453,9 +453,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut
timeout-minutes: 30
@ -494,9 +492,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut-anope
timeout-minutes: 30
@ -529,9 +525,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut-atheme
timeout-minutes: 30
@ -558,7 +552,7 @@ jobs:
repository: ergochat/ergo
- uses: actions/setup-go@v3
with:
go-version: ^1.23.0
go-version: ^1.22.0
- run: go version
- name: Build Ergo
run: |
@ -571,9 +565,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/go/sbin:~/go/bin:~/go:$PATH
make ergo
timeout-minutes: 30
@ -612,9 +604,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
hybrid
timeout-minutes: 30
@ -647,9 +637,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH
make inspircd
timeout-minutes: 30
@ -688,9 +676,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH make
inspircd-anope
timeout-minutes: 30
@ -729,9 +715,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
ircu2
timeout-minutes: 30
@ -759,9 +743,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
limnoria
timeout-minutes: 30
@ -799,9 +781,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
nefarious
timeout-minutes: 30
@ -834,9 +814,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH
make ngircd
timeout-minutes: 30
@ -875,9 +853,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH make
ngircd-anope
timeout-minutes: 30
@ -910,9 +886,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH
make ngircd-atheme
timeout-minutes: 30
@ -951,9 +925,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
plexus4
timeout-minutes: 30
@ -1000,9 +972,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=$GITHUB_WORKSPACE/sable/target/debug/sbin:$GITHUB_WORKSPACE/sable/target/debug/bin:$GITHUB_WORKSPACE/sable/target/debug:$PATH
make sable
timeout-minutes: 30
@ -1035,9 +1005,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
solanum
timeout-minutes: 30
@ -1064,9 +1032,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
sopel
timeout-minutes: 30
@ -1104,9 +1070,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
thelounge
timeout-minutes: 30
@ -1139,9 +1103,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd
timeout-minutes: 30
@ -1174,9 +1136,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd-5
timeout-minutes: 30
@ -1215,9 +1175,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH make
unrealircd-anope
timeout-minutes: 30
@ -1250,9 +1208,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd-atheme
timeout-minutes: 30
@ -1296,9 +1252,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
IRCTEST_DLK_PATH="${{ github.workspace }}/Dlk-Services" IRCTEST_WP_CLI_PATH="${{
github.workspace }}/wp-cli.phar" IRCTEST_WP_ZIP_PATH="${{ github.workspace

View File

@ -126,9 +126,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH
make inspircd
timeout-minutes: 30
@ -167,9 +165,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH make
inspircd-anope
timeout-minutes: 30
@ -202,9 +198,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH
make inspircd-atheme
timeout-minutes: 30

View File

@ -65,7 +65,7 @@ jobs:
uses: actions/checkout@v4
with:
path: Bahamut
ref: v2.2.4
ref: v2.2.1
repository: DALnet/Bahamut
- name: Build Bahamut
run: |
@ -189,7 +189,7 @@ jobs:
uses: actions/checkout@v4
with:
path: inspircd
ref: v3.17.1
ref: v3.17.0
repository: inspircd/inspircd
- name: Build InspIRCd
run: |
@ -228,7 +228,7 @@ jobs:
uses: actions/checkout@v4
with:
path: ngircd
ref: acf8409c60ccc96beed0a1f990c4f9374823c0ce
ref: 3e3f6cbeceefd9357b53b27c2386bb39306ab353
repository: ngircd/ngircd
- name: Build ngircd
run: |
@ -351,7 +351,7 @@ jobs:
uses: actions/checkout@v4
with:
path: unrealircd
ref: a68625454078641ce984eeb197f7e02b1857ab6c
ref: da3c1c654481a33035b9c703957e1c25d0158259
repository: unrealircd/unrealircd
- name: Build UnrealIRCd 6
run: |
@ -496,9 +496,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut
timeout-minutes: 30
@ -537,9 +535,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut-anope
timeout-minutes: 30
@ -572,9 +568,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
bahamut-atheme
timeout-minutes: 30
@ -607,9 +601,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
charybdis
timeout-minutes: 30
@ -636,7 +628,7 @@ jobs:
repository: ergochat/ergo
- uses: actions/setup-go@v3
with:
go-version: ^1.23.0
go-version: ^1.22.0
- run: go version
- name: Build Ergo
run: |
@ -649,9 +641,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/go/sbin:~/go/bin:~/go:$PATH
make ergo
timeout-minutes: 30
@ -690,9 +680,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
hybrid
timeout-minutes: 30
@ -725,9 +713,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH
make inspircd
timeout-minutes: 30
@ -766,9 +752,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH make
inspircd-anope
timeout-minutes: 30
@ -801,9 +785,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/inspircd/sbin:~/.local/inspircd/bin:~/.local/inspircd:$PATH
make inspircd-atheme
timeout-minutes: 30
@ -853,9 +835,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
irc2
timeout-minutes: 30
@ -894,9 +874,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
ircu2
timeout-minutes: 30
@ -923,9 +901,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
limnoria
timeout-minutes: 30
@ -963,9 +939,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
nefarious
timeout-minutes: 30
@ -998,9 +972,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH
make ngircd
timeout-minutes: 30
@ -1039,9 +1011,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH make
ngircd-anope
timeout-minutes: 30
@ -1074,9 +1044,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local//sbin:~/.local//bin:~/.local/:$PATH
make ngircd-atheme
timeout-minutes: 30
@ -1115,9 +1083,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
plexus4
timeout-minutes: 30
@ -1140,7 +1106,7 @@ jobs:
uses: actions/checkout@v4
with:
path: sable
ref: baed3ef9ac4550dc36a45b758436769e82e8ec58
ref: e9701e5e8d0c4f278ddd61ce7285f4918ecf99e9
repository: Libera-Chat/sable
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
@ -1164,9 +1130,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=$GITHUB_WORKSPACE/sable/target/debug/sbin:$GITHUB_WORKSPACE/sable/target/debug/bin:$GITHUB_WORKSPACE/sable/target/debug:$PATH
make sable
timeout-minutes: 30
@ -1199,9 +1163,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
solanum
timeout-minutes: 30
@ -1228,9 +1190,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
sopel
timeout-minutes: 30
@ -1268,9 +1228,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH make
thelounge
timeout-minutes: 30
@ -1303,9 +1261,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd
timeout-minutes: 30
@ -1338,9 +1294,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd-5
timeout-minutes: 30
@ -1379,9 +1333,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH make
unrealircd-anope
timeout-minutes: 30
@ -1414,9 +1366,7 @@ jobs:
run: |-
python -m pip install --upgrade pip
pip install pytest pytest-xdist pytest-timeout -r requirements.txt
- env:
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
name: Test with pytest
- name: Test with pytest
run: PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' PATH=$HOME/.local/bin:$PATH PATH=~/.local/unrealircd/sbin:~/.local/unrealircd/bin:~/.local/unrealircd:$PATH
make unrealircd-atheme
timeout-minutes: 30

View File

@ -84,12 +84,15 @@ LIMNORIA_SELECTORS := \
$(EXTRA_SELECTORS)
# Tests marked with arbitrary_client_tags or react_tag can't pass because Sable does not support client tags yet
# Tests marked with private_chathistory can't pass because Sable does not implement CHATHISTORY for DMs
SABLE_SELECTORS := \
not Ergo \
and not deprecated \
and not strict \
and not arbitrary_client_tags \
and not react_tag \
and not private_chathistory \
and not list and not lusers and not time and not info \
$(EXTRA_SELECTORS)

View File

@ -11,20 +11,7 @@ import subprocess
import tempfile
import textwrap
import time
from typing import (
IO,
Any,
Callable,
Dict,
Iterator,
List,
Optional,
Sequence,
Set,
Tuple,
Type,
Union,
)
from typing import IO, Any, Callable, Dict, Iterator, List, Optional, Set, Tuple, Type
import irctest
@ -87,7 +74,6 @@ class _BaseController:
_port_lock = FileLock(Path(tempfile.gettempdir()) / "irctest_ports.json.lock")
def __init__(self, test_config: TestCaseControllerConfig):
self.debug_mode = os.getenv("IRCTEST_DEBUG_LOGS", "0").lower() in ("true", "1")
self.test_config = test_config
self.proc = None
self._own_ports: Set[Tuple[str, int]] = set()
@ -144,12 +130,6 @@ class _BaseController:
used_ports.remove((hostname, port))
self._own_ports.remove((hostname, port))
def execute(
self, command: Sequence[Union[str, Path]], **kwargs: Any
) -> subprocess.Popen:
output_to = None if self.debug_mode else subprocess.DEVNULL
return subprocess.Popen(command, stderr=output_to, stdout=output_to, **kwargs)
class DirectoryBasedController(_BaseController):
"""Helper for controllers whose software configuration is based on an

View File

@ -8,7 +8,7 @@ from irctest.basecontrollers import BaseServicesController, DirectoryBasedContro
TEMPLATE_CONFIG = """
serverinfo {{
name = "My.Little.Services"
name = "services.example.org"
description = "Anope IRC Services"
numeric = "00A"
pid = "services.pid"
@ -136,19 +136,16 @@ class AnopeController(BaseServicesController, DirectoryBasedController):
Path(services_path).parent.parent / "modules"
)
extra_args = []
if self.debug_mode:
extra_args.append("--debug")
self.proc = self.execute(
self.proc = subprocess.Popen(
[
"anope",
"--config=services.conf", # can't be an absolute path in 2.0
"--nofork", # don't fork
"--nopid", # don't write a pid
*extra_args,
],
cwd=self.directory,
# stdout=subprocess.DEVNULL,
# stderr=subprocess.DEVNULL,
)

View File

@ -1,3 +1,4 @@
import subprocess
from typing import Optional, Type
import irctest
@ -24,7 +25,7 @@ loadmodule "modules/saslserv/plain";
#loadmodule "modules/saslserv/scram";
serverinfo {{
name = "My.Little.Services";
name = "services.example.org";
desc = "Atheme IRC Services";
numeric = "00A";
netname = "testnet";
@ -74,7 +75,7 @@ class AthemeController(BaseServicesController, DirectoryBasedController):
)
assert self.directory
self.proc = self.execute(
self.proc = subprocess.Popen(
[
"atheme-services",
"-n", # don't fork
@ -87,6 +88,8 @@ class AthemeController(BaseServicesController, DirectoryBasedController):
"-D",
self.directory,
],
# stdout=subprocess.DEVNULL,
# stderr=subprocess.DEVNULL,
)
def registerUser(

View File

@ -1,5 +1,6 @@
from pathlib import Path
import shutil
import subprocess
from typing import Optional, Set, Type
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
@ -14,7 +15,7 @@ options {{
network_name unconfigured;
allow_split_ops; # Give ops in empty channels
services_name My.Little.Services;
services_name services.example.org;
// if you need to link more than 1 server, uncomment the following line
servtype hub;
@ -44,7 +45,7 @@ class {{
/* for services */
super {{
"My.Little.Services";
"services.example.org";
}};
@ -57,7 +58,7 @@ class {{
/* our services */
connect {{
name My.Little.Services;
name services.example.org;
host *@127.0.0.1; # unfortunately, masks aren't allowed here
apasswd password;
cpasswd password;
@ -91,7 +92,7 @@ class BahamutController(BaseServerController, DirectoryBasedController):
software_name = "Bahamut"
supported_sasl_mechanisms: Set[str] = set()
supports_sts = False
nickserv = "NickServ@My.Little.Services"
nickserv = "NickServ@services.example.org"
def create_config(self) -> None:
super().create_config()
@ -149,7 +150,7 @@ class BahamutController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"ircd",

View File

@ -1,5 +1,6 @@
from pathlib import Path
import shutil
import subprocess
from typing import Optional
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
@ -73,7 +74,7 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
self.binary_name,
@ -83,6 +84,7 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
"-pidfile",
self.directory / "server.pid",
],
# stderr=subprocess.DEVNULL,
)
if run_services:

View File

@ -44,7 +44,7 @@ channel {{
displayed_usercount = 0;
}};
connect "My.Little.Services" {{
connect "services.example.org" {{
host = "localhost"; # Used to validate incoming connection
port = 0; # We don't need servers to connect to services
send_password = "password";
@ -53,7 +53,7 @@ connect "My.Little.Services" {{
flags = topicburst;
}};
service {{
name = "My.Little.Services";
name = "services.example.org";
}};
privset "omnioper" {{

View File

@ -13,7 +13,7 @@ TEMPLATE_DLK_CONFIG = """\
info {{
SID "00A";
network-name "testnetwork";
services-name "My.Little.Services";
services-name "services.example.org";
admin-email "admin@example.org";
}}
@ -200,7 +200,7 @@ class DlkController(BaseServicesController, DirectoryBasedController):
fd.write(TEMPLATE_DLK_WP_CONFIG.format(**template_vars))
(dlk_conf_dir / "modules.conf").symlink_to(self.dlk_path / "conf/modules.conf")
self.proc = self.execute(
self.proc = subprocess.Popen(
[
"php",
"src/dalek",

View File

@ -213,7 +213,7 @@ class ErgoController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[*faketime_cmd, "ergo", "run", "--conf", self._config_path, "--quiet"]
)

View File

@ -1,3 +1,4 @@
import subprocess
from typing import Optional, Type
from irctest import authentication, tls
@ -30,7 +31,7 @@ class GircController(BaseClientController, DirectoryBasedController):
args += ["--sasl-fail-is-ok"]
# Runs a client with the config given as arguments
self.proc = self.execute(["girc_test", "connect"] + args)
self.proc = subprocess.Popen(["girc_test", "connect"] + args)
def get_irctest_controller_class() -> Type[GircController]:

View File

@ -42,7 +42,7 @@ class {{
connectfreq = 5 minutes;
}};
connect {{
name = "My.Little.Services";
name = "services.example.org";
host = "127.0.0.1"; # Used to validate incoming connection
port = 0; # We don't need servers to connect to services
send_password = "password";
@ -50,7 +50,7 @@ connect {{
class = "server";
}};
service {{
name = "My.Little.Services";
name = "services.example.org";
}};
auth {{

View File

@ -33,15 +33,14 @@ TEMPLATE_CONFIG = """
class="ServerOperators"
>
<options casemapping="ascii"
extbanformat="any">
<options casemapping="ascii">
# Disable 'NOTICE #chan :*** foo invited bar into the channel-
<security announceinvites="none">
# Services:
<bind address="{services_hostname}" port="{services_port}" type="servers">
<link name="My.Little.Services"
<link name="services.example.org"
ipaddr="{services_hostname}"
port="{services_port}"
allowmask="*"
@ -51,7 +50,7 @@ TEMPLATE_CONFIG = """
<module name="spanningtree">
<module name="hidechans"> # Anope errors when missing
<sasl requiressl="no"
target="My.Little.Services">
target="services.example.org">
# Protocol:
<module name="banexception">
@ -183,22 +182,15 @@ class InspircdController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
extra_args = []
if self.debug_mode:
if installed_version() >= 4:
extra_args.append("--protocoldebug")
else:
extra_args.append("--debug")
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"inspircd",
"--nofork",
"--config",
self.directory / "server.conf",
*extra_args,
],
stdout=subprocess.DEVNULL,
)
if run_services:

View File

@ -1,4 +1,5 @@
import shutil
import subprocess
from typing import Optional, Type
from irctest.basecontrollers import (
@ -77,7 +78,7 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"ircd",
@ -87,6 +88,7 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
"-f",
self.directory / "server.conf",
],
# stderr=subprocess.DEVNULL,
)

View File

@ -1,4 +1,5 @@
import shutil
import subprocess
from typing import Optional, Type
from irctest.basecontrollers import (
@ -96,7 +97,7 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"ircd",
@ -106,6 +107,7 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
"-x",
"DEBUG",
],
# stderr=subprocess.DEVNULL,
)

View File

@ -1,3 +1,4 @@
import subprocess
from typing import Optional, Type
from irctest import authentication, tls
@ -83,7 +84,7 @@ class LimnoriaController(BaseClientController, DirectoryBasedController):
)
)
assert self.directory
self.proc = self.execute(["supybot", self.directory / "bot.conf"])
self.proc = subprocess.Popen(["supybot", self.directory / "bot.conf"])
def get_irctest_controller_class() -> Type[LimnoriaController]:

View File

@ -1,4 +1,5 @@
import shutil
import subprocess
from typing import Optional, Set, Type
from irctest.basecontrollers import (
@ -115,7 +116,7 @@ class MammonController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"mammond",

View File

@ -1,4 +1,5 @@
import shutil
import subprocess
from typing import Optional, Set, Type
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
@ -14,7 +15,7 @@ TEMPLATE_CONFIG = """
{password_field}
[Server]
Name = My.Little.Services
Name = services.example.org
MyPassword = password
PeerPassword = password
Passive = yes # don't connect to it
@ -27,9 +28,6 @@ TEMPLATE_CONFIG = """
[Operator]
Name = operuser
Password = operpassword
[Limits]
MaxNickLength = 32 # defaults to 9
"""
@ -94,7 +92,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"ngircd",
@ -102,6 +100,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
"--config",
self.directory / "server.conf",
],
# stdout=subprocess.DEVNULL,
)
if run_services:

View File

@ -44,7 +44,7 @@ class {{
connectfreq = 5 minutes;
}};
connect {{
name = "My.Little.Services";
name = "services.example.org";
host = "127.0.0.1"; # Used to validate incoming connection
port = 0; # We don't need servers to connect to services
send_password = "password";
@ -52,7 +52,7 @@ connect {{
class = "server";
}};
service {{
name = "My.Little.Services";
name = "services.example.org";
}};
auth {{

View File

@ -107,8 +107,6 @@ NETWORK_CONFIG = """
NETWORK_CONFIG_CONFIG = """
{
"object_expiry": 300,
"opers": [
{
"name": "operuser",
@ -396,7 +394,7 @@ class SableController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"sable_ircd",
@ -477,7 +475,7 @@ class SableServicesController(BaseServicesController):
with self.server_controller.open_file("configs/services.conf") as fd:
fd.write(SERVICES_CONFIG % self.server_controller.template_vars)
self.proc = self.execute(
self.proc = subprocess.Popen(
[
"sable_services",
"--foreground",

View File

@ -1,4 +1,5 @@
import shutil
import subprocess
from typing import Optional, Type
from irctest.basecontrollers import (
@ -95,7 +96,7 @@ class SnircdController(BaseServerController, DirectoryBasedController):
else:
faketime_cmd = []
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"ircd",
@ -105,6 +106,7 @@ class SnircdController(BaseServerController, DirectoryBasedController):
"-x",
"DEBUG",
],
# stderr=subprocess.DEVNULL,
)

View File

@ -1,4 +1,5 @@
from pathlib import Path
import subprocess
import tempfile
from typing import Optional, TextIO, Type, cast
@ -72,7 +73,7 @@ class SopelController(BaseClientController):
auth_method="auth_method = sasl" if auth else "",
)
)
self.proc = self.execute(["sopel", "-c", self.filename])
self.proc = subprocess.Popen(["sopel", "-c", self.filename])
def get_irctest_controller_class() -> Type[SopelController]:

View File

@ -1,5 +1,6 @@
import json
import os
import subprocess
from typing import Optional, Type
from irctest import authentication, tls
@ -95,7 +96,7 @@ class TheLoungeController(BaseClientController, DirectoryBasedController):
)
with self.open_file("users/testuser.json", "r") as fd:
print("config", json.load(fd)["networks"][0]["saslPassword"])
self.proc = self.execute(
self.proc = subprocess.Popen(
[os.environ.get("THELOUNGE_BIN", "thelounge"), "start"],
env={**os.environ, "THELOUNGE_HOME": str(self.directory)},
)

View File

@ -64,7 +64,7 @@ listen {{
options {{ serversonly; }}
}}
link My.Little.Services {{
link services.example.org {{
incoming {{
mask *;
}}
@ -72,11 +72,11 @@ link My.Little.Services {{
class servers;
}}
ulines {{
My.Little.Services;
services.example.org;
}}
set {{
sasl-server My.Little.Services;
sasl-server services.example.org;
kline-address "example@example.org";
network-name "ExampleNET";
default-server "irc.example.org";
@ -261,7 +261,7 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
faketime_cmd = []
with _STARTSTOP_LOCK():
self.proc = self.execute(
self.proc = subprocess.Popen(
[
*faketime_cmd,
"unrealircd",
@ -270,6 +270,7 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
"-f",
self.directory / "unrealircd.conf",
],
# stdout=subprocess.DEVNULL,
)
self.wait_for_port()

View File

@ -1,67 +0,0 @@
from irctest import cases
from irctest.numerics import RPL_CHANNELCREATED, RPL_CHANNELMODEIS
from irctest.patma import ANYSTR, ListRemainder, StrRe
class RplChannelModeIsTestCase(cases.BaseServerTestCase):
@cases.mark_specifications("Modern")
def testChannelModeIs(self):
"""Test RPL_CHANNELMODEIS and RPL_CHANNELCREATED as responses to
`MODE #channel`:
<https://modern.ircdocs.horse/#rplcreationtime-329>
<https://modern.ircdocs.horse/#rplchannelmodeis-324>
"""
expected_numerics = {RPL_CHANNELMODEIS, RPL_CHANNELCREATED}
if self.controller.software_name in ("irc2", "Sable"):
# irc2 and Sable don't use timestamps for conflict resolution,
# consequently they don't store the channel creation timestamp
# and don't send RPL_CHANNELCREATED
expected_numerics = {RPL_CHANNELMODEIS}
self.connectClient("chanop", name="chanop")
self.joinChannel("chanop", "#chan")
# i, n, and t are specified by RFC1459; some of them may be on by default,
# but after this, at least those three should be enabled:
self.sendLine("chanop", "MODE #chan +int")
self.getMessages("chanop")
self.sendLine("chanop", "MODE #chan")
messages = self.getMessages("chanop")
self.assertEqual(expected_numerics, {msg.command for msg in messages})
for message in messages:
if message.command == RPL_CHANNELMODEIS:
# the final parameters are the mode string (e.g. `+int`),
# and then optionally any mode parameters (in case the ircd
# lists a mode that takes a parameter)
self.assertMessageMatch(
message,
command=RPL_CHANNELMODEIS,
params=["chanop", "#chan", ListRemainder(ANYSTR, min_length=1)],
)
final_param = message.params[2]
self.assertEqual(final_param[0], "+")
enabled_modes = list(final_param[1:])
break
self.assertLessEqual({"i", "n", "t"}, set(enabled_modes))
# remove all the modes listed by RPL_CHANNELMODEIS
self.sendLine("chanop", f"MODE #chan -{''.join(enabled_modes)}")
response = self.getMessage("chanop")
# we should get something like: MODE #chan -int
self.assertMessageMatch(
response, command="MODE", params=["#chan", StrRe("^-.*")]
)
self.assertEqual(set(response.params[1][1:]), set(enabled_modes))
self.sendLine("chanop", "MODE #chan")
messages = self.getMessages("chanop")
self.assertEqual(expected_numerics, {msg.command for msg in messages})
# all modes have been disabled; the correct representation of this is `+`
for message in messages:
if message.command == RPL_CHANNELMODEIS:
self.assertMessageMatch(
message,
command=RPL_CHANNELMODEIS,
params=["chanop", "#chan", "+"],
)

View File

@ -1,159 +0,0 @@
from irctest import cases
from irctest.numerics import (
ERR_CHANOPRIVSNEEDED,
ERR_NOSUCHCHANNEL,
ERR_NOSUCHNICK,
ERR_NOTONCHANNEL,
ERR_USERNOTINCHANNEL,
)
class ChannelOperatorModeTestCase(cases.BaseServerTestCase):
"""Test various error and success cases around the channel operator mode:
<https://modern.ircdocs.horse/#channel-operators>
<https://modern.ircdocs.horse/#mode-message>
"""
def setupNicks(self):
"""Set up a standard set of three nicknames and two channels
for testing channel-user MODE interactions."""
# first nick to join the channel is privileged:
self.connectClient("chanop", name="chanop")
self.joinChannel("chanop", "#chan")
self.connectClient("unprivileged", name="unprivileged")
self.joinChannel("unprivileged", "#chan")
self.getMessages("chanop")
self.connectClient("unrelated", name="unrelated")
self.joinChannel("unrelated", "#unrelated")
self.joinChannel("unprivileged", "#unrelated")
self.getMessages("unrelated")
@cases.mark_specifications("Modern")
@cases.xfailIfSoftware(["irc2"], "broken in irc2")
def testChannelOperatorModeSenderPrivsNeeded(self):
"""Test that +o from a channel member without the necessary privileges
fails as expected."""
self.setupNicks()
# sender is a channel member but without the necessary privileges:
self.sendLine("unprivileged", "MODE #chan +o unprivileged")
messages = self.getMessages("unprivileged")
self.assertEqual(len(messages), 1)
self.assertMessageMatch(messages[0], command=ERR_CHANOPRIVSNEEDED)
@cases.mark_specifications("Modern")
def testChannelOperatorModeTargetNotInChannel(self):
"""Test that +o targeting a user not present in the channel fails
as expected."""
self.setupNicks()
# sender is a chanop, but target nick is not in the channel:
self.sendLine("chanop", "MODE #chan +o unrelated")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertMessageMatch(messages[0], command=ERR_USERNOTINCHANNEL)
@cases.mark_specifications("Modern")
def testChannelOperatorModeTargetDoesNotExist(self):
"""Test that +o targeting a nonexistent nick fails as expected."""
self.setupNicks()
# sender is a chanop, but target nick does not exist:
self.sendLine("chanop", "MODE #chan +o nobody")
messages = self.getMessages("chanop")
# ERR_NOSUCHNICK is typical, Bahamut additionally sends ERR_USERNOTINCHANNEL
if self.controller.software_name != "Bahamut":
self.assertEqual(len(messages), 1)
self.assertMessageMatch(messages[0], command=ERR_NOSUCHNICK)
else:
self.assertLessEqual(len(messages), 2)
commands = {message.command for message in messages}
self.assertLessEqual({ERR_NOSUCHNICK}, commands)
self.assertLessEqual(commands, {ERR_NOSUCHNICK, ERR_USERNOTINCHANNEL})
@cases.mark_specifications("Modern")
@cases.xfailIf(
lambda self: bool(
self.controller.software_name == "UnrealIRCd"
and self.controller.software_version == 5
),
"UnrealIRCd <6.1.7 returns ERR_NOSUCHNICK on non-existent channel",
)
def testChannelOperatorModeChannelDoesNotExist(self):
"""Test that +o targeting a nonexistent channel fails as expected.
"If <target> is a channel that does not exist on the network,
# the ERR_NOSUCHCHANNEL (403) numeric is returned."
"""
self.setupNicks()
# target channel does not exist, but target nick does:
self.sendLine("chanop", "MODE #nonexistentchan +o chanop")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertMessageMatch(messages[0], command=ERR_NOSUCHCHANNEL)
@cases.mark_specifications("Modern")
@cases.xfailIf(
lambda self: bool(
self.controller.software_name == "UnrealIRCd"
and self.controller.software_version == 5
),
"UnrealIRCd <6.1.7 returns ERR_NOSUCHNICK on non-existent channel",
)
def testChannelOperatorModeChannelAndTargetDoNotExist(self):
"""Test that +o targeting a nonexistent channel and nickname
fails as expected."""
self.setupNicks()
# neither target channel nor target nick exist:
self.sendLine("chanop", "MODE #nonexistentchan +o nobody")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertIn(
messages[0].command,
[ERR_NOSUCHCHANNEL, ERR_NOTONCHANNEL, ERR_USERNOTINCHANNEL],
)
@cases.mark_specifications("Modern")
def testChannelOperatorModeSenderNonMember(self):
"""Test that +o where the sender is not a channel member
fails as expected."""
self.setupNicks()
# sender is not a channel member, target nick exists and is a channel member:
self.sendLine("chanop", "MODE #unrelated +o unprivileged")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertIn(messages[0].command, [ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED])
@cases.mark_specifications("Modern")
def testChannelOperatorModeSenderAndTargetNonMembers(self):
"""Test that +o where neither the sender nor the target is a channel
member fails as expected."""
self.setupNicks()
# sender is not a channel member, target nick exists but is not a channel member:
self.sendLine("chanop", "MODE #unrelated +o chanop")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertIn(
messages[0].command,
[ERR_NOTONCHANNEL, ERR_CHANOPRIVSNEEDED, ERR_USERNOTINCHANNEL],
)
@cases.mark_specifications("Modern")
def testChannelOperatorModeSuccess(self):
"""Tests a successful grant of +o in a channel."""
self.setupNicks()
self.sendLine("chanop", "MODE #chan +o unprivileged")
messages = self.getMessages("chanop")
self.assertEqual(len(messages), 1)
self.assertMessageMatch(
messages[0],
command="MODE",
params=["#chan", "+o", "unprivileged"],
)
messages = self.getMessages("unprivileged")
self.assertEqual(len(messages), 1)
self.assertMessageMatch(
messages[0],
command="MODE",
params=["#chan", "+o", "unprivileged"],
)

View File

@ -3,13 +3,6 @@ from irctest.numerics import ERR_UNKNOWNCOMMAND, RPL_ENDOFLINKS, RPL_LINKS
from irctest.patma import ANYSTR, StrRe
def _server_info_regexp(case: cases.BaseServerTestCase) -> str:
if case.controller.software_name == "Sable":
return ".+"
else:
return "test server"
class LinksTestCase(cases.BaseServerTestCase):
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
def testLinksSingleServer(self):
@ -63,7 +56,7 @@ class LinksTestCase(cases.BaseServerTestCase):
"nick",
"My.Little.Server",
"My.Little.Server",
StrRe(f"0 (0042 )?{_server_info_regexp(self)}"),
StrRe("0 (0042 )?test server"),
],
)
@ -126,7 +119,7 @@ class ServicesLinksTestCase(cases.BaseServerTestCase):
"nick",
"My.Little.Server",
"My.Little.Server",
StrRe(f"0 (0042 )?{_server_info_regexp(self)}"),
StrRe("0 (0042 )?test server"),
],
)
self.assertMessageMatch(
@ -134,7 +127,7 @@ class ServicesLinksTestCase(cases.BaseServerTestCase):
command=RPL_LINKS,
params=[
"nick",
"My.Little.Services",
"services.example.org",
"My.Little.Server",
StrRe("1 .+"), # SID instead of description for Anope...
],

View File

@ -140,9 +140,9 @@ class TagsTestCase(cases.BaseServerTestCase):
self.joinChannel(1, "#xyz")
monsterMessage = "@+clientOnlyTagExample=" + "a" * 4096 + " PRIVMSG #xyz hi!"
self.sendLine(1, monsterMessage)
self.assertEqual(self.getMessages(2), [], "overflowing message was relayed")
replies = self.getMessages(1)
self.assertIn(ERR_INPUTTOOLONG, set(reply.command for reply in replies))
self.assertEqual(self.getMessages(2), [], "overflowing message was relayed")
class LengthLimitTestCase(cases.BaseServerTestCase):

View File

@ -1,4 +1,5 @@
import base64
from typing import List
from irctest import cases, runner, scram
from irctest.numerics import ERR_SASLFAIL, RPL_LOGGEDIN, RPL_SASLMECHS
@ -11,8 +12,34 @@ class RegistrationTestCase(cases.BaseServerTestCase):
self.controller.registerUser(self, "testuser", "mypassword")
@cases.mark_services
class SaslTestCase(cases.BaseServerTestCase):
class _BaseSasl(cases.BaseServerTestCase):
sasl_ir: bool
capabilities: List[str]
def _doInitialExchange(self, client, mechanism: str, chunk: str):
"""Does the initial C->S, S->C, C->S exchange.
With ``sasl_ir=False``, this is done with the usual three messages exchange
(``AUTHENTICATE <mechanism>``, ``AUTHENTICATE +``, ``AUTHENTICATE <chunk>``)
with ``sasl_ir=True``, this is done in a single C->S message
(``AUTHENTICATE <mechanism> <chunk>``)
See the [sasl-ir spec](https://github.com/ircv3/ircv3-specifications/pull/520)
"""
if self.sasl_ir:
self.sendLine(client, f"AUTHENTICATE {mechanism} {chunk}")
else:
self.sendLine(client, f"AUTHENTICATE {mechanism}")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg=f"Sent “AUTHENTICATE {mechanism}”, server should have "
f"replied with “AUTHENTICATE +”, but instead sent: {{msg}}",
)
self.sendLine(client, f"AUTHENTICATE {chunk}")
@cases.mark_specifications("IRCv3")
@cases.skipUnlessHasMechanism("PLAIN")
def testPlain(self):
@ -34,17 +61,8 @@ class SaslTestCase(cases.BaseServerTestCase):
capabilities["sasl"],
fail_msg="Does not have PLAIN mechanism as the controller " "claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE PLAIN")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg="Sent “AUTHENTICATE PLAIN”, server should have "
"replied with “AUTHENTICATE +”, but instead sent: {msg}",
)
self.sendLine(1, "AUTHENTICATE amlsbGVzAGppbGxlcwBzZXNhbWU=")
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self._doInitialExchange(1, "PLAIN", "amlsbGVzAGppbGxlcwBzZXNhbWU=")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
@ -88,17 +106,8 @@ class SaslTestCase(cases.BaseServerTestCase):
).decode()
self.controller.registerUser(self, "foo", password)
self.addClient()
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE PLAIN")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg="Sent “AUTHENTICATE PLAIN”, server should have "
"replied with “AUTHENTICATE +”, but instead sent: {msg}",
)
self.sendLine(1, "AUTHENTICATE " + authstring)
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self._doInitialExchange(1, "PLAIN", authstring)
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
@ -148,17 +157,8 @@ class SaslTestCase(cases.BaseServerTestCase):
capabilities["sasl"],
fail_msg="Does not have PLAIN mechanism as the controller " "claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE PLAIN")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg="Sent “AUTHENTICATE PLAIN”, server should have "
"replied with “AUTHENTICATE +”, but instead sent: {msg}",
)
self.sendLine(1, "AUTHENTICATE AGppbGxlcwBzZXNhbWU=")
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self._doInitialExchange(1, "PLAIN", "AGppbGxlcwBzZXNhbWU=")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
@ -184,8 +184,11 @@ class SaslTestCase(cases.BaseServerTestCase):
capabilities,
fail_msg="Does not have SASL as the controller claims.",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE FOO")
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
if self.sasl_ir:
self.sendLine(1, "AUTHENTICATE FOO AGppbGxlcwBzZXNhbWU=")
else:
self.sendLine(1, "AUTHENTICATE FOO")
m = self.getRegistrationMessage(1)
while m.command == RPL_SASLMECHS:
m = self.getRegistrationMessage(1)
@ -235,17 +238,8 @@ class SaslTestCase(cases.BaseServerTestCase):
capabilities["sasl"],
fail_msg="Does not have PLAIN mechanism as the controller " "claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE PLAIN")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg="Sent “AUTHENTICATE PLAIN”, expected "
"“AUTHENTICATE +” as a response, but got: {msg}",
)
self.sendLine(1, "AUTHENTICATE {}".format(authstring[0:400]))
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self._doInitialExchange(1, "PLAIN", authstring[0:400])
self.sendLine(1, "AUTHENTICATE {}".format(authstring[400:]))
self.confirmSuccessfulAuth()
@ -305,17 +299,8 @@ class SaslTestCase(cases.BaseServerTestCase):
capabilities["sasl"],
fail_msg="Does not have PLAIN mechanism as the controller " "claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE PLAIN")
m = self.getRegistrationMessage(1)
self.assertMessageMatch(
m,
command="AUTHENTICATE",
params=["+"],
fail_msg="Sent “AUTHENTICATE PLAIN”, expected "
"“AUTHENTICATE +” as a response, but got: {msg}",
)
self.sendLine(1, "AUTHENTICATE {}".format(authstring))
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self._doInitialExchange(1, "PLAIN", authstring)
self.sendLine(1, "AUTHENTICATE +")
self.confirmSuccessfulAuth()
@ -324,6 +309,12 @@ class SaslTestCase(cases.BaseServerTestCase):
# I don't know how to do it, because it would make the registration
# message's length too big for it to be valid.
@cases.mark_services
class SaslTestCase(_BaseSasl):
sasl_ir = False
capabilities = ["sasl"]
@cases.mark_specifications("IRCv3")
@cases.skipUnlessHasMechanism("SCRAM-SHA-256")
def testScramSha256Success(self):
@ -344,7 +335,7 @@ class SaslTestCase(cases.BaseServerTestCase):
fail_msg="Does not have SCRAM-SHA-256 mechanism as the "
"controller claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE SCRAM-SHA-256")
m = self.getRegistrationMessage(1)
@ -400,7 +391,7 @@ class SaslTestCase(cases.BaseServerTestCase):
fail_msg="Does not have SCRAM-SHA-256 mechanism as the "
"controller claims",
)
self.requestCapabilities(1, ["sasl"], skip_if_cap_nak=False)
self.requestCapabilities(1, self.capabilities, skip_if_cap_nak=False)
self.sendLine(1, "AUTHENTICATE SCRAM-SHA-256")
m = self.getRegistrationMessage(1)
@ -430,3 +421,36 @@ class SaslTestCase(cases.BaseServerTestCase):
)
m = self.getRegistrationMessage(1)
self.assertMessageMatch(m, command=ERR_SASLFAIL)
@cases.mark_services
class SaslIrTestCase(_BaseSasl):
"""Tests SASL with clients requesting the
[sasl-ir](https://github.com/ircv3/ircv3-specifications/pull/520) cap and using it.
"""
sasl_ir = True
capabilities = ["sasl", "draft/sasl-ir"]
def setUp(self):
super().setUp()
self.connectClient(
"capgetter", capabilities=["draft/sasl-ir"], skip_if_cap_nak=True
)
@cases.mark_services
class ImplicitSaslIrTestCase(_BaseSasl):
"""Tests SASL with clients using the
[sasl-ir](https://github.com/ircv3/ircv3-specifications/pull/520) CAP without
requesting it.
"""
sasl_ir = True
capabilities = ["sasl"]
def setUp(self):
super().setUp()
self.connectClient(
"capgetter", capabilities=["draft/sasl-ir"], skip_if_cap_nak=True
)

View File

@ -221,6 +221,7 @@ class WhoisTestCase(_WhoisTestMixin, cases.BaseServerTestCase):
)
@cases.mark_specifications("RFC2812")
@cases.xfailIfSoftware(["Sable"], "https://github.com/Libera-Chat/sable/issues/101")
def testWhoisMissingUser(self):
"""Test WHOIS on a nonexistent nickname."""
self.connectClient("qux", name="qux")

View File

@ -223,9 +223,6 @@ def get_test_job(*, config, test_config, test_id, version_flavor, jobs):
{
"name": "Test with pytest",
"timeout-minutes": 30,
"env": {
"IRCTEST_DEBUG_LOGS": "${{ runner.debug }}",
},
"run": (
f"PYTEST_ARGS='--junit-xml pytest.xml --timeout 300' "
f"PATH=$HOME/.local/bin:$PATH "

View File

@ -8,13 +8,13 @@ index 317b00e..adfcfcf 100644
dots = 1;
}
- if (!dots)
- if (!dots)
- {
- sendto_realops("Invalid hostname for %s, dumping user %s",
- sptr->hostip, sptr->name);
- return exit_client(cptr, sptr, &me, "Invalid hostname");
- }
-
if (bad_dns)
-
if (bad_dns)
{
sendto_one(sptr, ":%s NOTICE %s :*** Notice -- You have a bad "

View File

@ -97,7 +97,7 @@ software:
name: Bahamut
repository: DALnet/Bahamut
refs:
stable: "v2.2.4"
stable: "v2.2.1"
release: null
devel: "master"
devel_release: null
@ -136,7 +136,7 @@ software:
pre_deps:
- uses: actions/setup-go@v3
with:
go-version: '^1.23.0'
go-version: '^1.22.0'
- run: go version
separate_build_job: false
build_script: |
@ -148,7 +148,7 @@ software:
name: InspIRCd
repository: inspircd/inspircd
refs: &inspircd_refs
stable: v3.17.1
stable: v3.17.0
release: null
devel: master
devel_release: insp3
@ -230,7 +230,7 @@ software:
name: ngircd
repository: ngircd/ngircd
refs:
stable: acf8409c60ccc96beed0a1f990c4f9374823c0ce # three months ahead of v27
stable: 3e3f6cbeceefd9357b53b27c2386bb39306ab353 # three years ahead of rel-26.1
release: null
devel: master
devel_release: null
@ -249,7 +249,7 @@ software:
name: Sable
repository: Libera-Chat/sable
refs:
stable: baed3ef9ac4550dc36a45b758436769e82e8ec58
stable: e9701e5e8d0c4f278ddd61ce7285f4918ecf99e9
release: null
devel: master
devel_release: null
@ -300,8 +300,8 @@ software:
name: UnrealIRCd 6
repository: unrealircd/unrealircd
refs:
stable: a68625454078641ce984eeb197f7e02b1857ab6c # 6.1.7.1
release: a68625454078641ce984eeb197f7e02b1857ab6c # 6.1.7.1
stable: da3c1c654481a33035b9c703957e1c25d0158259 # 6.0.7
release: da3c1c654481a33035b9c703957e1c25d0158259 # 6.0.7
devel: unreal60_dev
devel_release: null
path: unrealircd