15 Commits

Author SHA1 Message Date
0d93503ac7 Load third/redact on Unreal 2023-11-17 13:07:16 +01:00
08a434851c Unreal stuff? 2023-07-09 20:28:26 +02:00
34046d34ca Add tests for PMs 2023-05-29 18:31:54 +02:00
f538b4ae6a Add testOpRedactNonExistant 2023-05-26 18:50:00 +02:00
f0969d1fe8 Add test with chathistory 2023-05-26 18:11:24 +02:00
daee74ed07 Add tests for draft/message-redaction 2023-05-26 17:05:47 +02:00
bb8a6b6c3d add a test for channel +n / -n (#201)
* add a test for channel +n / -n

* Update irctest/server_tests/chmodes/nooutside.py

Co-authored-by: Val Lorentz <progval+github@progval.net>

* Update irctest/server_tests/chmodes/nooutside.py

Co-authored-by: Val Lorentz <progval+github@progval.net>

* consistently rename to "no external messages"

---------

Co-authored-by: Val Lorentz <progval+github@progval.net>
2023-05-23 01:18:40 -04:00
297bf2c554 inspircd: Use upstream mainloop hack when available (#200) 2023-05-20 20:06:59 +02:00
05e9b3746e ci: Bump versions of actions we use (#199)
So Github stops complaining about the deprecated Nodejs version
2023-05-20 13:32:42 +02:00
3b7f81e22c strip whitespace from Ergo hashed password output (#198)
Removes the need for some special-casing in `ergo genpasswd`
2023-04-19 02:52:21 -04:00
6edf4e27f1 Remove xfail in WHOWAS as linked PRs have been merged (#197)
* Bump inspircd stable version.

* Remove xfail in WHOWAS as linked PRs have been merged
2023-04-17 18:45:50 +02:00
11dc5b046e unrealircd: Move SSL and port generation out of the critical section (#196) 2023-04-16 09:19:05 +02:00
ddb37d6c3f Use real metadata keys (#194) 2023-04-15 23:04:24 +02:00
aed6478a2c Bump UnrealIRCd to v6.0.7 (#192) 2023-04-05 08:24:34 +02:00
418b526033 Prevent random port collisions between controllers (#191)
This happens from time to time on the CI and is pretty annoying
2023-04-04 22:01:20 +02:00
27 changed files with 1061 additions and 679 deletions

View File

@ -8,7 +8,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-anope-devel
path: '~/.cache
@ -16,13 +16,13 @@ jobs:
${ github.workspace }/anope
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Anope
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: anope
ref: 2.0.9
@ -37,7 +37,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-anope.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-anope
path: ~/artefacts-*.tar.gz
@ -48,7 +48,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-bahamut-devel
path: '~/.cache
@ -56,13 +56,13 @@ jobs:
${ github.workspace }/Bahamut
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Bahamut
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: Bahamut
ref: master
@ -86,7 +86,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-bahamut.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-bahamut
path: ~/artefacts-*.tar.gz
@ -97,7 +97,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-hybrid-devel
path: '~/.cache
@ -105,13 +105,13 @@ jobs:
${ github.workspace }/ircd-hybrid
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Hybrid
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ircd-hybrid
ref: 8.2.x
@ -125,7 +125,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-hybrid.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-hybrid
path: ~/artefacts-*.tar.gz
@ -135,13 +135,13 @@ jobs:
steps:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout InspIRCd
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: inspircd
ref: master
@ -149,14 +149,18 @@ jobs:
- name: Build InspIRCd
run: |
cd $GITHUB_WORKSPACE/inspircd/
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch
# Insp3 <= 3.16.0 and Insp4 <= 4.0.0a21 don't support -DINSPIRCD_UNLIMITED_MAINLOOP
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch || true
./configure --prefix=$HOME/.local/inspircd --development
make -j 4
CXXFLAGS=-DINSPIRCD_UNLIMITED_MAINLOOP make -j 4
make install
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-inspircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-inspircd
path: ~/artefacts-*.tar.gz
@ -167,7 +171,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-ngircd-devel
path: '~/.cache
@ -175,13 +179,13 @@ jobs:
${ github.workspace }/ngircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout ngircd
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ngircd
ref: master
@ -197,7 +201,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-ngircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-ngircd
path: ~/artefacts-*.tar.gz
@ -208,7 +212,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-plexus4-devel
path: '~/.cache
@ -216,9 +220,9 @@ jobs:
${ github.workspace }/placeholder
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: clone
@ -239,7 +243,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-plexus4.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-plexus4
path: ~/artefacts-*.tar.gz
@ -250,7 +254,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-solanum-devel
path: '~/.cache
@ -258,13 +262,13 @@ jobs:
${ github.workspace }/solanum
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Solanum
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: solanum
ref: main
@ -279,7 +283,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-solanum.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-solanum
path: ~/artefacts-*.tar.gz
@ -290,7 +294,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-unrealircd-devel
path: '~/.cache
@ -298,13 +302,13 @@ jobs:
${ github.workspace }/unrealircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout UnrealIRCd 6
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: unrealircd
ref: unreal60_dev
@ -320,12 +324,13 @@ jobs:
CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick
make -j 4
make install
~/.local/unrealircd/unrealircd module install third/react
# Prevent download of geoIP database on first startup
sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-unrealircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-unrealircd
path: ~/artefacts-*.tar.gz
@ -336,7 +341,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-unrealircd-5-devel
path: '~/.cache
@ -344,13 +349,13 @@ jobs:
${ github.workspace }/unrealircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout UnrealIRCd 5
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: unrealircd
ref: unreal52
@ -366,12 +371,13 @@ jobs:
CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick
make -j 4
make install
~/.local/unrealircd/unrealircd module install third/react
# Prevent download of geoIP database on first startup
sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-unrealircd-5.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-unrealircd-5
path: ~/artefacts-*.tar.gz
@ -403,9 +409,9 @@ jobs:
- test-unrealircd-dlk
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Download Artifacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Install dashboard dependencies
@ -430,13 +436,13 @@ jobs:
- build-bahamut
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
@ -454,7 +460,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut_devel
path: pytest.xml
@ -464,18 +470,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -493,7 +499,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut-anope_devel
path: pytest.xml
@ -502,13 +508,13 @@ jobs:
- build-bahamut
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
@ -526,7 +532,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut-atheme_devel
path: pytest.xml
@ -534,13 +540,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Ergo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ergo
ref: master
@ -566,7 +572,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ergo_devel
path: pytest.xml
@ -576,18 +582,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-hybrid
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -605,7 +611,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_hybrid_devel
path: pytest.xml
@ -614,13 +620,13 @@ jobs:
- build-inspircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
@ -638,7 +644,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd_devel
path: pytest.xml
@ -648,18 +654,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -677,7 +683,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd-anope_devel
path: pytest.xml
@ -685,13 +691,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout ircu2
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ircu2
ref: u2_10_12_branch
@ -716,7 +722,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ircu2_devel
path: pytest.xml
@ -724,9 +730,9 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Install dependencies
@ -744,7 +750,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_limnoria_devel
path: pytest.xml
@ -752,13 +758,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout nefarious
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: nefarious
ref: master
@ -782,7 +788,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_nefarious_devel
path: pytest.xml
@ -791,13 +797,13 @@ jobs:
- build-ngircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
@ -815,7 +821,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd_devel
path: pytest.xml
@ -825,18 +831,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -854,7 +860,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd-anope_devel
path: pytest.xml
@ -863,13 +869,13 @@ jobs:
- build-ngircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
@ -887,7 +893,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd-atheme_devel
path: pytest.xml
@ -897,18 +903,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-plexus4
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -926,7 +932,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_plexus4_devel
path: pytest.xml
@ -935,13 +941,13 @@ jobs:
- build-solanum
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-solanum
path: '~'
@ -959,7 +965,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_solanum_devel
path: pytest.xml
@ -967,9 +973,9 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Install dependencies
@ -986,7 +992,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_sopel_devel
path: pytest.xml
@ -995,13 +1001,13 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
@ -1019,7 +1025,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd_devel
path: pytest.xml
@ -1028,13 +1034,13 @@ jobs:
- build-unrealircd-5
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd-5
path: '~'
@ -1052,7 +1058,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-5_devel
path: pytest.xml
@ -1062,18 +1068,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -1091,7 +1097,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-anope_devel
path: pytest.xml
@ -1100,13 +1106,13 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
@ -1124,7 +1130,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-atheme_devel
path: pytest.xml
@ -1133,20 +1139,20 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
- name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Checkout Dlk
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: Dlk-Services
ref: main
@ -1170,7 +1176,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-dlk_devel
path: pytest.xml

View File

@ -8,7 +8,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-anope-devel_release
path: '~/.cache
@ -16,13 +16,13 @@ jobs:
${ github.workspace }/anope
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Anope
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: anope
ref: 2.0.9
@ -37,7 +37,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-anope.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-anope
path: ~/artefacts-*.tar.gz
@ -47,13 +47,13 @@ jobs:
steps:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout InspIRCd
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: inspircd
ref: insp3
@ -61,14 +61,18 @@ jobs:
- name: Build InspIRCd
run: |
cd $GITHUB_WORKSPACE/inspircd/
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch
# Insp3 <= 3.16.0 and Insp4 <= 4.0.0a21 don't support -DINSPIRCD_UNLIMITED_MAINLOOP
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch || true
./configure --prefix=$HOME/.local/inspircd --development
make -j 4
CXXFLAGS=-DINSPIRCD_UNLIMITED_MAINLOOP make -j 4
make install
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-inspircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-inspircd
path: ~/artefacts-*.tar.gz
@ -82,9 +86,9 @@ jobs:
- test-inspircd-atheme
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Download Artifacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Install dashboard dependencies
@ -109,13 +113,13 @@ jobs:
- build-inspircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
@ -133,7 +137,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd_devel_release
path: pytest.xml
@ -143,18 +147,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -172,7 +176,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd-anope_devel_release
path: pytest.xml
@ -181,13 +185,13 @@ jobs:
- build-inspircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
@ -205,7 +209,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd-atheme_devel_release
path: pytest.xml

View File

@ -8,7 +8,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-anope-stable
path: '~/.cache
@ -16,13 +16,13 @@ jobs:
${ github.workspace }/anope
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Anope
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: anope
ref: 2.0.9
@ -37,7 +37,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-anope.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-anope
path: ~/artefacts-*.tar.gz
@ -48,7 +48,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-bahamut-stable
path: '~/.cache
@ -56,13 +56,13 @@ jobs:
${ github.workspace }/Bahamut
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Bahamut
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: Bahamut
ref: v2.2.1
@ -86,7 +86,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-bahamut.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-bahamut
path: ~/artefacts-*.tar.gz
@ -97,7 +97,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-charybdis-stable
path: '~/.cache
@ -105,13 +105,13 @@ jobs:
${ github.workspace }/charybdis
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Charybdis
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: charybdis
ref: charybdis-4.1.2
@ -126,7 +126,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-charybdis.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-charybdis
path: ~/artefacts-*.tar.gz
@ -137,7 +137,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-hybrid-stable
path: '~/.cache
@ -145,13 +145,13 @@ jobs:
${ github.workspace }/ircd-hybrid
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Hybrid
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ircd-hybrid
ref: 8.2.39
@ -165,7 +165,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-hybrid.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-hybrid
path: ~/artefacts-*.tar.gz
@ -175,28 +175,32 @@ jobs:
steps:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout InspIRCd
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: inspircd
ref: v3.12.0
ref: v3.15.0
repository: inspircd/inspircd
- name: Build InspIRCd
run: |
cd $GITHUB_WORKSPACE/inspircd/
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch
# Insp3 <= 3.16.0 and Insp4 <= 4.0.0a21 don't support -DINSPIRCD_UNLIMITED_MAINLOOP
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch || true
./configure --prefix=$HOME/.local/inspircd --development
make -j 4
CXXFLAGS=-DINSPIRCD_UNLIMITED_MAINLOOP make -j 4
make install
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-inspircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-inspircd
path: ~/artefacts-*.tar.gz
@ -207,7 +211,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-ngircd-stable
path: '~/.cache
@ -215,13 +219,13 @@ jobs:
${ github.workspace }/ngircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout ngircd
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ngircd
ref: rel-26.1
@ -237,7 +241,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-ngircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-ngircd
path: ~/artefacts-*.tar.gz
@ -248,7 +252,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-plexus4-stable
path: '~/.cache
@ -256,9 +260,9 @@ jobs:
${ github.workspace }/placeholder
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: clone
@ -279,7 +283,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-plexus4.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-plexus4
path: ~/artefacts-*.tar.gz
@ -290,7 +294,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-solanum-stable
path: '~/.cache
@ -298,13 +302,13 @@ jobs:
${ github.workspace }/solanum
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Solanum
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: solanum
ref: 492d560ee13e71dc35403fd676e58c2d5bdcf2a9
@ -319,7 +323,7 @@ jobs:
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-solanum.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-solanum
path: ~/artefacts-*.tar.gz
@ -330,7 +334,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-unrealircd-stable
path: '~/.cache
@ -338,16 +342,16 @@ jobs:
${ github.workspace }/unrealircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout UnrealIRCd 6
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: unrealircd
ref: cedd23ae9cdd5985ce16e9869cbdb808479c3fc4
ref: da3c1c654481a33035b9c703957e1c25d0158259
repository: unrealircd/unrealircd
- name: Build UnrealIRCd 6
run: |
@ -360,12 +364,13 @@ jobs:
CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick
make -j 4
make install
~/.local/unrealircd/unrealircd module install third/react
# Prevent download of geoIP database on first startup
sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-unrealircd.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-unrealircd
path: ~/artefacts-*.tar.gz
@ -376,7 +381,7 @@ jobs:
- name: Create directories
run: cd ~/; mkdir -p .local/ go/
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
key: 3-${{ runner.os }}-unrealircd-5-stable
path: '~/.cache
@ -384,13 +389,13 @@ jobs:
${ github.workspace }/unrealircd
'
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout UnrealIRCd 5
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: unrealircd
ref: 6604856973f713a494f83d38992d7d61ce6b9db4
@ -406,12 +411,13 @@ jobs:
CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick
make -j 4
make install
~/.local/unrealircd/unrealircd module install third/react
# Prevent download of geoIP database on first startup
sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf
- name: Make artefact tarball
run: cd ~; tar -czf artefacts-unrealircd-5.tar.gz .local/ go/
- name: Upload build artefacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: installed-unrealircd-5
path: ~/artefacts-*.tar.gz
@ -446,9 +452,9 @@ jobs:
- test-unrealircd-dlk
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Download Artifacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Install dashboard dependencies
@ -473,13 +479,13 @@ jobs:
- build-bahamut
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
@ -497,7 +503,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut_stable
path: pytest.xml
@ -507,18 +513,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -536,7 +542,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut-anope_stable
path: pytest.xml
@ -545,13 +551,13 @@ jobs:
- build-bahamut
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-bahamut
path: '~'
@ -569,7 +575,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_bahamut-atheme_stable
path: pytest.xml
@ -578,13 +584,13 @@ jobs:
- build-charybdis
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-charybdis
path: '~'
@ -602,7 +608,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_charybdis_stable
path: pytest.xml
@ -610,13 +616,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout Ergo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ergo
ref: irctest_stable
@ -642,7 +648,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ergo_stable
path: pytest.xml
@ -652,18 +658,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-hybrid
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -681,7 +687,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_hybrid_stable
path: pytest.xml
@ -690,13 +696,13 @@ jobs:
- build-inspircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
@ -714,7 +720,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd_stable
path: pytest.xml
@ -724,18 +730,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -753,7 +759,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd-anope_stable
path: pytest.xml
@ -762,13 +768,13 @@ jobs:
- build-inspircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-inspircd
path: '~'
@ -786,7 +792,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_inspircd-atheme_stable
path: pytest.xml
@ -794,13 +800,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout irc2
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: irc2.11.2p3
ref: 59649f24c3a5c27bad5648b48774f27475bccfd3
@ -836,7 +842,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_irc2_stable
path: pytest.xml
@ -844,13 +850,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout ircu2
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: ircu2
ref: u2.10.12.19
@ -875,7 +881,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ircu2_stable
path: pytest.xml
@ -883,9 +889,9 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Install dependencies
@ -902,7 +908,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_limnoria_stable
path: pytest.xml
@ -910,13 +916,13 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Checkout nefarious
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: nefarious
ref: 985704168ecada12d9e53b46df6087ef9d9fb40b
@ -940,7 +946,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_nefarious_stable
path: pytest.xml
@ -949,13 +955,13 @@ jobs:
- build-ngircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
@ -973,7 +979,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd_stable
path: pytest.xml
@ -983,18 +989,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -1012,7 +1018,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd-anope_stable
path: pytest.xml
@ -1021,13 +1027,13 @@ jobs:
- build-ngircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-ngircd
path: '~'
@ -1045,7 +1051,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_ngircd-atheme_stable
path: pytest.xml
@ -1055,18 +1061,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-plexus4
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -1084,7 +1090,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_plexus4_stable
path: pytest.xml
@ -1093,13 +1099,13 @@ jobs:
- build-solanum
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-solanum
path: '~'
@ -1117,7 +1123,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_solanum_stable
path: pytest.xml
@ -1125,9 +1131,9 @@ jobs:
needs: []
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Install dependencies
@ -1144,7 +1150,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_sopel_stable
path: pytest.xml
@ -1153,13 +1159,13 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
@ -1177,7 +1183,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd_stable
path: pytest.xml
@ -1186,13 +1192,13 @@ jobs:
- build-unrealircd-5
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd-5
path: '~'
@ -1210,7 +1216,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-5_stable
path: pytest.xml
@ -1220,18 +1226,18 @@ jobs:
- build-anope
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-anope
path: '~'
@ -1249,7 +1255,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-anope_stable
path: pytest.xml
@ -1258,13 +1264,13 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
@ -1282,7 +1288,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-atheme_stable
path: pytest.xml
@ -1291,20 +1297,20 @@ jobs:
- build-unrealircd
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Download build artefacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: installed-unrealircd
path: '~'
- name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Checkout Dlk
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: Dlk-Services
ref: effd18652fc1c847d1959089d9cca9ff9837a8c0
@ -1328,7 +1334,7 @@ jobs:
timeout-minutes: 30
- if: always()
name: Publish results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results_unrealircd-dlk_stable
path: pytest.xml

View File

@ -110,8 +110,11 @@ cd /tmp/
git clone https://github.com/inspircd/inspircd.git
cd inspircd
# optional, makes tests run considerably faster
# Optional, makes tests run considerably faster. Pick one depending on the InspIRCd version:
# on Insp3 <= 3.16.0 and Insp4 <= 4.0.0a21:
patch src/inspircd.cpp < ~/irctest/patches/inspircd_mainloop.patch
# on Insp3 >= 3.17.0 and Insp4 >= 4.0.0a22:
export CXXFLAGS=-DINSPIRCD_UNLIMITED_MAINLOOP
./configure --prefix=$HOME/.local/ --development
make -j 4

View File

@ -1,6 +1,7 @@
from __future__ import annotations
import dataclasses
import multiprocessing
import os
from pathlib import Path
import shutil
@ -9,7 +10,18 @@ import subprocess
import tempfile
import textwrap
import time
from typing import IO, Any, Callable, Dict, List, Optional, Set, Tuple, Type
from typing import (
IO,
Any,
Callable,
Dict,
List,
MutableMapping,
Optional,
Set,
Tuple,
Type,
)
import irctest
@ -58,9 +70,43 @@ class _BaseController:
supported_sasl_mechanisms: Set[str]
proc: Optional[subprocess.Popen]
_used_ports: Set[Tuple[str, int]]
"""``(hostname, port))`` used by this controller."""
# the following need to be shared between processes in case we are running in
# parallel (with pytest-xdist)
# The dicts are used as a set of (hostname, port), because _manager.set() doesn't
# exist.
_manager = multiprocessing.Manager()
_port_lock = _manager.Lock()
"""Lock for access to ``_all_used_ports`` and ``_available_ports``."""
_all_used_ports: MutableMapping[Tuple[str, int], None] = _manager.dict()
"""``(hostname, port)`` used by all controllers."""
_available_ports: MutableMapping[Tuple[str, int], None] = _manager.dict()
"""``(hostname, port)`` available to any controller."""
def __init__(self, test_config: TestCaseControllerConfig):
self.test_config = test_config
self.proc = None
self._used_ports = set()
def get_hostname_and_port(self) -> Tuple[str, int]:
with self._port_lock:
try:
# try to get a known available port
((hostname, port), _) = self._available_ports.popitem()
except KeyError:
# if there aren't any, iterate while we get a fresh one.
while True:
(hostname, port) = find_hostname_and_port()
if (hostname, port) not in self._all_used_ports:
# double-checking in self._used_ports to prevent collisions
# between controllers starting at the same time.
break
# Make this port unavailable to other processes
self._all_used_ports[(hostname, port)] = None
return (hostname, port)
def check_is_alive(self) -> None:
assert self.proc
@ -84,6 +130,11 @@ class _BaseController:
if self.proc:
self.kill_proc()
# move this controller's ports from _all_used_ports to _available_ports
for hostname, port in self._used_ports:
del self._all_used_ports[(hostname, port)]
self._available_ports[(hostname, port)] = None
class DirectoryBasedController(_BaseController):
"""Helper for controllers whose software configuration is based on an
@ -202,9 +253,6 @@ class BaseServerController(_BaseController):
super().__init__(*args, **kwargs)
self.faketime_enabled = False
def get_hostname_and_port(self) -> Tuple[str, int]:
return find_hostname_and_port()
def run(
self,
hostname: str,
@ -213,8 +261,6 @@ class BaseServerController(_BaseController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]],
invalid_metadata_keys: Optional[Set[str]],
faketime: Optional[str],
) -> None:
raise NotImplementedError()

View File

@ -529,8 +529,6 @@ class BaseServerTestCase(
password: Optional[str] = None
ssl = False
valid_metadata_keys: Set[str] = set()
invalid_metadata_keys: Set[str] = set()
server_support: Optional[Dict[str, Optional[str]]]
run_services = False
@ -550,8 +548,6 @@ class BaseServerTestCase(
self.hostname,
self.port,
password=self.password,
valid_metadata_keys=self.valid_metadata_keys,
invalid_metadata_keys=self.invalid_metadata_keys,
ssl=self.ssl,
run_services=self.run_services,
faketime=self.faketime,
@ -710,7 +706,7 @@ class BaseServerTestCase(
self.requestCapabilities(client, capabilities, skip_if_cap_nak)
if password is not None:
if "sasl" not in (capabilities or ()):
raise ValueError("Used 'password' option without sasl capbilitiy")
raise ValueError("Used 'password' option without sasl capbility")
self.authenticateClient(client, account or nick, password)
self.sendLine(client, "NICK {}".format(nick))

View File

@ -3,12 +3,7 @@ import shutil
import subprocess
from typing import Optional, Set, Type
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.irc_utils.junkdrawer import find_hostname_and_port
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
TEMPLATE_CONFIG = """
global {{
@ -112,21 +107,14 @@ class BahamutController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
assert self.proc is None
self.port = port
self.hostname = hostname
self.create_config()
(unused_hostname, unused_port) = find_hostname_and_port()
(services_hostname, services_port) = find_hostname_and_port()
(unused_hostname, unused_port) = self.get_hostname_and_port()
(services_hostname, services_port) = self.get_hostname_and_port()
password_field = "passwd {};".format(password) if password else ""

View File

@ -1,13 +1,8 @@
import shutil
import subprocess
from typing import Optional, Set
from typing import Optional
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.irc_utils.junkdrawer import find_hostname_and_port
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
TEMPLATE_SSL_CONFIG = """
ssl_private_key = "{key_path}";
@ -41,19 +36,13 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
assert self.proc is None
self.port = port
self.hostname = hostname
self.create_config()
(services_hostname, services_port) = find_hostname_and_port()
(services_hostname, services_port) = self.get_hostname_and_port()
password_field = 'password = "{}";'.format(password) if password else ""
if ssl:
self.gen_ssl()

View File

@ -3,13 +3,9 @@ import json
import os
import shutil
import subprocess
from typing import Any, Dict, Optional, Set, Type, Union
from typing import Any, Dict, Optional, Type, Union
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
from irctest.cases import BaseServerTestCase
BASE_CONFIG = {
@ -81,6 +77,9 @@ BASE_CONFIG = {
"channel-length": 128,
"client-length": 128,
"chathistory-maxmessages": 100,
"retention": {
"allow-individual-delete": True,
},
"tagmsg-storage": {
"default": False,
"whitelist": ["+draft/persist", "+persist"],
@ -130,7 +129,7 @@ def hash_password(password: Union[str, bytes]) -> str:
["ergo", "genpasswd"], stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
out, _ = p.communicate(input_)
return out.decode("utf-8")
return out.decode("utf-8").strip()
class ErgoController(BaseServerController, DirectoryBasedController):
@ -153,17 +152,9 @@ class ErgoController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
config: Optional[Any] = None,
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
self.create_config()
if config is None:
config = copy.deepcopy(BASE_CONFIG)

View File

@ -1,5 +1,5 @@
import os
from typing import Optional, Set, Tuple, Type
from typing import Optional, Tuple, Type
from irctest.basecontrollers import BaseServerController
@ -39,9 +39,6 @@ class ExternalServerController(BaseServerController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
pass

View File

@ -1,14 +1,9 @@
import functools
import shutil
import subprocess
from typing import Optional, Set, Type
from typing import Optional, Type
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.irc_utils.junkdrawer import find_hostname_and_port
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
TEMPLATE_CONFIG = """
# Clients:
@ -125,20 +120,13 @@ class InspircdController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str] = None,
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
assert self.proc is None
self.port = port
self.hostname = hostname
self.create_config()
(services_hostname, services_port) = find_hostname_and_port()
(services_hostname, services_port) = self.get_hostname_and_port()
password_field = 'password="{}"'.format(password) if password else ""

View File

@ -1,6 +1,6 @@
import shutil
import subprocess
from typing import Optional, Set, Type
from typing import Optional, Type
from irctest.basecontrollers import (
BaseServerController,
@ -49,14 +49,8 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
if ssl:
raise NotImplementedByController("TLS")
if run_services:

View File

@ -1,6 +1,6 @@
import shutil
import subprocess
from typing import Optional, Set, Type
from typing import Optional, Type
from irctest.basecontrollers import (
BaseServerController,
@ -68,14 +68,8 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
if ssl:
raise NotImplementedByController("TLS")
if run_services:

View File

@ -33,10 +33,10 @@ extensions:
- mammon.ext.ircv3.sasl
- mammon.ext.misc.nopost
metadata:
restricted_keys:
{restricted_keys}
restricted_keys: []
whitelist:
{authorized_keys}
- display-name
- avatar
monitor:
limit: 20
motd:
@ -89,9 +89,6 @@ class MammonController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if password is not None:
@ -107,8 +104,6 @@ class MammonController(BaseServerController, DirectoryBasedController):
directory=self.directory,
hostname=hostname,
port=port,
authorized_keys=make_list(valid_metadata_keys or set()),
restricted_keys=make_list(restricted_metadata_keys or set()),
)
)
# with self.open_file('server.yml', 'r') as fd:

View File

@ -2,12 +2,7 @@ import shutil
import subprocess
from typing import Optional, Set, Type
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.irc_utils.junkdrawer import find_hostname_and_port
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
TEMPLATE_CONFIG = """
[Global]
@ -53,20 +48,13 @@ class NgircdController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
assert self.proc is None
self.port = port
self.hostname = hostname
self.create_config()
(unused_hostname, unused_port) = find_hostname_and_port()
(unused_hostname, unused_port) = self.get_hostname_and_port()
password_field = "Password = {}".format(password) if password else ""

View File

@ -1,6 +1,6 @@
import shutil
import subprocess
from typing import Optional, Set, Type
from typing import Optional, Type
from irctest.basecontrollers import (
BaseServerController,
@ -67,14 +67,8 @@ class SnircdController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
if ssl:
raise NotImplementedByController("TLS")
if run_services:

View File

@ -5,19 +5,15 @@ from pathlib import Path
import shutil
import subprocess
import textwrap
from typing import Callable, ContextManager, Iterator, Optional, Set, Type
from typing import Callable, ContextManager, Iterator, Optional, Type
from irctest.basecontrollers import (
BaseServerController,
DirectoryBasedController,
NotImplementedByController,
)
from irctest.irc_utils.junkdrawer import find_hostname_and_port
from irctest.basecontrollers import BaseServerController, DirectoryBasedController
TEMPLATE_CONFIG = """
include "modules.default.conf";
include "operclass.default.conf";
{extras}
loadmodule "third/redact";
include "help/help.conf";
me {{
@ -101,7 +97,12 @@ set {{
}}
modes-on-join "+H 100:1d"; // Enables CHATHISTORY
{set_extras}
redacters {{
op;
sender;
}}
{set_v6only}
}}
@ -124,6 +125,24 @@ oper "operuser" {{
}}
"""
SET_V6ONLY = """
// Remove RPL_WHOISSPECIAL used to advertise security groups
whois-details {
security-groups { everyone none; self none; oper none; }
}
plaintext-policy {
server warn; // https://www.unrealircd.org/docs/FAQ#server-requires-tls
oper warn; // https://www.unrealircd.org/docs/FAQ#oper-requires-tls
}
anti-flood {
everyone {
connect-flood 255:10;
}
}
"""
def _filelock(path: Path) -> Callable[[], ContextManager]:
"""Alternative to :cls:`multiprocessing.Lock` that works with pytest-xdist"""
@ -186,15 +205,8 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
password: Optional[str],
ssl: bool,
run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None:
if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController(
"Defining valid and invalid METADATA keys."
)
assert self.proc is None
self.port = port
self.hostname = hostname
@ -207,64 +219,54 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
loadmodule "cloak_md5";
"""
)
set_extras = textwrap.indent(
textwrap.dedent(
"""
// Remove RPL_WHOISSPECIAL used to advertise security groups
whois-details {
security-groups { everyone none; self none; oper none; }
}
"""
),
" ",
)
set_v6only = SET_V6ONLY
else:
extras = ""
set_extras = ""
set_v6only = ""
with self.open_file("empty.txt") as fd:
fd.write("\n")
password_field = 'password "{}";'.format(password) if password else ""
with _STARTSTOP_LOCK():
(services_hostname, services_port) = find_hostname_and_port()
(unused_hostname, unused_port) = find_hostname_and_port()
(services_hostname, services_port) = self.get_hostname_and_port()
(unused_hostname, unused_port) = self.get_hostname_and_port()
self.gen_ssl()
if ssl:
(tls_hostname, tls_port) = (hostname, port)
(hostname, port) = (unused_hostname, unused_port)
else:
# Unreal refuses to start without TLS enabled
(tls_hostname, tls_port) = (unused_hostname, unused_port)
self.gen_ssl()
if ssl:
(tls_hostname, tls_port) = (hostname, port)
(hostname, port) = (unused_hostname, unused_port)
else:
# Unreal refuses to start without TLS enabled
(tls_hostname, tls_port) = (unused_hostname, unused_port)
assert self.directory
assert self.directory
with self.open_file("unrealircd.conf") as fd:
fd.write(
TEMPLATE_CONFIG.format(
hostname=hostname,
port=port,
services_hostname=services_hostname,
services_port=services_port,
tls_hostname=tls_hostname,
tls_port=tls_port,
password_field=password_field,
key_path=self.key_path,
pem_path=self.pem_path,
empty_file=self.directory / "empty.txt",
extras=extras,
set_extras=set_extras,
)
with self.open_file("unrealircd.conf") as fd:
fd.write(
TEMPLATE_CONFIG.format(
hostname=hostname,
port=port,
services_hostname=services_hostname,
services_port=services_port,
tls_hostname=tls_hostname,
tls_port=tls_port,
password_field=password_field,
key_path=self.key_path,
pem_path=self.pem_path,
empty_file=self.directory / "empty.txt",
set_v6only=set_v6only,
extras=extras,
)
)
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
with _STARTSTOP_LOCK():
self.proc = subprocess.Popen(
[
*faketime_cmd,

View File

@ -0,0 +1,38 @@
"""
Channel "no external messages" mode (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.3.1>`__,
`Modern <https://modern.ircdocs.horse/#no-external-messages-mode>`__)
"""
from irctest import cases
from irctest.numerics import ERR_CANNOTSENDTOCHAN
class NoExternalMessagesTestCase(cases.BaseServerTestCase):
@cases.mark_specifications("RFC1459", "Modern")
def testNoExternalMessagesMode(self):
# test the +n channel mode
self.connectClient("chanop", name="chanop")
self.joinChannel("chanop", "#chan")
self.sendLine("chanop", "MODE #chan +n")
self.getMessages("chanop")
self.connectClient("baz", name="baz")
# this message should be suppressed completely by +n
self.sendLine("baz", "PRIVMSG #chan :hi from baz")
replies = self.getMessages("baz")
reply_cmds = {reply.command for reply in replies}
self.assertIn(ERR_CANNOTSENDTOCHAN, reply_cmds)
self.assertEqual(self.getMessages("chanop"), [])
# set the channel to -n: baz should be able to send now
self.sendLine("chanop", "MODE #chan -n")
replies = self.getMessages("chanop")
modeLines = [line for line in replies if line.command == "MODE"]
self.assertMessageMatch(modeLines[0], command="MODE", params=["#chan", "-n"])
self.sendLine("baz", "PRIVMSG #chan :hi again from baz")
self.getMessages("baz")
relays = self.getMessages("chanop")
self.assertMessageMatch(
relays[0], command="PRIVMSG", params=["#chan", "hi again from baz"]
)

View File

@ -238,135 +238,6 @@ class ListTestCase(_BasedListTestCase):
self.sendLine(3, "LIST <100")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
@cases.mark_specifications("Modern")
def testListTwoChannels(self):
"""
"Parameters: [<channel>{,<channel>}] [<elistcond>{,<elistcond>}]"
-- https://modern.ircdocs.horse/#list-message
"""
self.connectClient("foo")
if "TARGMAX" in self.server_support:
for item in (self.server_support["TARGMAX"]).split(","):
(command, max_) = item.split(":", 1)
if command == "LIST" and int(max_ or "1000") < 2:
raise runner.OptionalExtensionNotSupported("TARGMAX=LIST >= 2")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.sendLine(1, "JOIN #chan3")
self.getMessages(1)
self.connectClient("bar")
self.sendLine(2, "JOIN #chan2")
self.getMessages(2)
self.connectClient("baz")
self.sendLine(3, "LIST")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2", "#chan3"})
self.sendLine(3, "LIST #chan1,#chan2")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
@cases.mark_isupport("ELIST")
def testListTwoMasks(self):
self.connectClient("foo")
if "M" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=M")
if "TARGMAX" in self.server_support:
for item in (self.server_support["TARGMAX"]).split(","):
(command, max_) = item.split(":", 1)
if command == "LIST" and int(max_ or "1000") < 2:
raise runner.OptionalExtensionNotSupported("TARGMAX=LIST >= 2")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.sendLine(1, "JOIN #chan3")
self.getMessages(1)
self.connectClient("bar")
self.sendLine(2, "JOIN #chan2")
self.getMessages(2)
self.connectClient("baz")
self.sendLine(3, "LIST")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2", "#chan3"})
self.sendLine(3, "LIST *an1,*an2")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListTwoParams(self):
"""
"Parameters: [<channel>{,<channel>}] [<elistcond>{,<elistcond>}]"
-- https://modern.ircdocs.horse/#list-message
"""
self.connectClient("foo")
if "U" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=U")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.connectClient("bar")
self.sendLine(2, "JOIN #chan2")
self.getMessages(2)
self.connectClient("baz")
self.sendLine(3, "LIST #chan1 >0")
self.assertEqual(self._parseChanList(3), {"#chan1"})
self.sendLine(3, "LIST #chan1 <1")
self.assertEqual(self._parseChanList(3), set())
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListTwoParamsTwoChannels(self):
"""
"Parameters: [<channel>{,<channel>}] [<elistcond>{,<elistcond>}]"
-- https://modern.ircdocs.horse/#list-message
"""
self.connectClient("foo")
if "U" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=U")
if "TARGMAX" in self.server_support:
for item in (self.server_support["TARGMAX"]).split(","):
(command, max_) = item.split(":", 1)
if command == "LIST" and int(max_ or "1000") < 2:
raise runner.OptionalExtensionNotSupported("TARGMAX=LIST >= 2")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.connectClient("bar")
self.sendLine(2, "JOIN #chan2")
self.getMessages(2)
self.connectClient("baz")
self.sendLine(3, "LIST #chan1,#chan2 >0")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
self.sendLine(3, "LIST #chan1,#chan2 <1")
self.assertEqual(self._parseChanList(3), set())
class FaketimeListTestCase(_BasedListTestCase):
faketime = "+1y x30" # for every wall clock second, 1 minute passed for the server

View File

@ -100,8 +100,13 @@ class NoticeTestCase(cases.BaseServerTestCase):
class TagsTestCase(cases.BaseServerTestCase):
@cases.mark_capabilities("message-tags")
@cases.xfailIfSoftware(
["UnrealIRCd"], "https://bugs.unrealircd.org/view.php?id=5947"
@cases.xfailIf(
lambda self: bool(
self.controller.software_name == "UnrealIRCd"
and self.controller.software_version == 5
),
"UnrealIRCd <6.0.7 dropped messages with excessively large tags: "
"https://bugs.unrealircd.org/view.php?id=5947",
)
def testLineTooLong(self):
self.connectClient("bar", capabilities=["message-tags"], skip_if_cap_nak=True)

View File

@ -6,8 +6,8 @@ from irctest import cases
class MetadataTestCase(cases.BaseServerTestCase):
valid_metadata_keys = {"valid_key1", "valid_key2"}
invalid_metadata_keys = {"invalid_key1", "invalid_key2"}
valid_metadata_keys = {"display-name", "avatar"}
invalid_metadata_keys = {"indisplay-name", "inavatar"}
@cases.mark_specifications("IRCv3", deprecated=True)
def testInIsupport(self):
@ -36,7 +36,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
def testGetOneUnsetValid(self):
"""<http://ircv3.net/specs/core/metadata-3.2.html#metadata-get>"""
self.connectClient("foo")
self.sendLine(1, "METADATA * GET valid_key1")
self.sendLine(1, "METADATA * GET display-name")
m = self.getMessage(1)
self.assertMessageMatch(
m,
@ -52,7 +52,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
-- <http://ircv3.net/specs/core/metadata-3.2.html#metadata-get>
"""
self.connectClient("foo")
self.sendLine(1, "METADATA * GET valid_key1 valid_key2")
self.sendLine(1, "METADATA * GET display-name avatar")
m = self.getMessage(1)
self.assertMessageMatch(
m,
@ -62,10 +62,10 @@ class MetadataTestCase(cases.BaseServerTestCase):
)
self.assertEqual(
m.params[1],
"valid_key1",
"display-name",
m,
fail_msg="Response to “METADATA * GET valid_key1 valid_key2"
"did not respond to valid_key1 first: {msg}",
fail_msg="Response to “METADATA * GET display-name avatar"
"did not respond to display-name first: {msg}",
)
m = self.getMessage(1)
self.assertMessageMatch(
@ -76,10 +76,10 @@ class MetadataTestCase(cases.BaseServerTestCase):
)
self.assertEqual(
m.params[1],
"valid_key2",
"avatar",
m,
fail_msg="Response to “METADATA * GET valid_key1 valid_key2"
"did not respond to valid_key2 as second response: {msg}",
fail_msg="Response to “METADATA * GET display-name avatar"
"did not respond to avatar as second response: {msg}",
)
@cases.mark_specifications("IRCv3", deprecated=True)
@ -135,7 +135,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
)
self.assertEqual(
m.params[1],
"valid_key1",
"display-name",
m,
fail_msg="Second param of 761 after setting “{expects}” to "
"{}” is not “{expects}”: {msg}.",
@ -190,7 +190,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
def testSetGetValid(self):
"""<http://ircv3.net/specs/core/metadata-3.2.html>"""
self.connectClient("foo")
self.assertSetGetValue("*", "valid_key1", "myvalue")
self.assertSetGetValue("*", "display-name", "myvalue")
@cases.mark_specifications("IRCv3", deprecated=True)
def testSetGetZeroCharInValue(self):
@ -198,7 +198,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
-- <http://ircv3.net/specs/core/metadata-3.2.html#metadata-restrictions>
"""
self.connectClient("foo")
self.assertSetGetValue("*", "valid_key1", "zero->\0<-zero", "zero->\\0<-zero")
self.assertSetGetValue("*", "display-name", "zero->\0<-zero", "zero->\\0<-zero")
@cases.mark_specifications("IRCv3", deprecated=True)
def testSetGetHeartInValue(self):
@ -209,7 +209,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
self.connectClient("foo")
self.assertSetGetValue(
"*",
"valid_key1",
"display-name",
"->{}<-".format(heart),
"zero->{}<-zero".format(heart.encode()),
)
@ -223,7 +223,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
# Sending directly because it is not valid UTF-8 so Python would
# not like it
self.clients[1].conn.sendall(
b"METADATA * SET valid_key1 " b":invalid UTF-8 ->\xc3<-\r\n"
b"METADATA * SET display-name " b":invalid UTF-8 ->\xc3<-\r\n"
)
commands = {m.command for m in self.getMessages(1)}
self.assertNotIn(
@ -233,7 +233,7 @@ class MetadataTestCase(cases.BaseServerTestCase):
"UTF-8 was answered with 761 (RPL_KEYVALUE)",
)
self.clients[1].conn.sendall(
b"METADATA * SET valid_key1 " b":invalid UTF-8: \xc3\r\n"
b"METADATA * SET display-name " b":invalid UTF-8: \xc3\r\n"
)
commands = {m.command for m in self.getMessages(1)}
self.assertNotIn(

View File

@ -0,0 +1,502 @@
"""
`IRCv3 draft message redaction <https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md>`_
"""
import uuid
import pytest
from irctest import cases
from irctest.patma import ANYDICT, ANYSTR, StrRe
CAPABILITIES = [
"message-tags",
"echo-message",
"batch",
"server-time",
"labeled-response",
"draft/message-redaction",
]
@cases.mark_specifications("IRCv3")
@cases.mark_capabilities(*CAPABILITIES)
class ChannelRedactTestCase(cases.BaseServerTestCase):
def _setupRedactTest(self, redacteeId, redacteeNick, chathistory=False):
capabilities = list(CAPABILITIES)
if chathistory:
capabilities.extend(["batch", "draft/chathistory"])
self.connectClient("chanop", capabilities=capabilities, skip_if_cap_nak=True)
self.sendLine(1, "JOIN #chan")
self.connectClient("user", capabilities=capabilities, skip_if_cap_nak=True)
self.sendLine(2, "JOIN #chan")
self.getMessages(2) # synchronize
self.getMessages(1)
self.sendLine(redacteeId, "@label=1234 PRIVMSG #chan :hello there")
echo = self.getMessage(redacteeId)
self.assertMessageMatch(
echo,
tags={"label": "1234", "msgid": StrRe("[^ ]+"), **ANYDICT},
prefix=StrRe(redacteeNick + "!.*"),
command="PRIVMSG",
params=["#chan", "hello there"],
)
msgid = echo.tags["msgid"]
self.assertMessageMatch(
self.getMessage(3 - redacteeId),
tags={"msgid": msgid, **ANYDICT},
prefix=StrRe(redacteeNick + "!.*"),
command="PRIVMSG",
params=["#chan", "hello there"],
)
return msgid
def testRelayOpSelfRedact(self):
"""Channel op writes a message and redacts it themselves."""
msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop")
self.sendLine(1, f"REDACT #chan {msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("chanop!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
self.assertMessageMatch(
self.getMessage(2),
prefix=StrRe("chanop!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
def testRelayOpRedact(self):
"""User writes a message and channel op redacts it."""
msgid = self._setupRedactTest(
redacteeId=2,
redacteeNick="user",
)
self.sendLine(1, f"REDACT #chan {msgid} :spam")
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("chanop!.*"),
command="REDACT",
params=["#chan", msgid, "spam"],
)
self.assertMessageMatch(
self.getMessage(2),
prefix=StrRe("chanop!.*"),
command="REDACT",
params=["#chan", msgid, "spam"],
)
def testRelayUserSelfRedact(self):
"""User writes a message and redacts it themselves.
Servers may either accept or reject this."""
msgid = self._setupRedactTest(redacteeId=2, redacteeNick="user")
self.sendLine(2, f"REDACT #chan {msgid} :oops")
msg = self.getMessage(2)
if msg.command == "REDACT":
self.assertMessageMatch(
msg,
prefix=StrRe("user!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("user!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
else:
self.assertMessageMatch(
msg,
command="FAIL",
params=["REDACT", "REDACT_FORBIDDEN", "#chan", msgid, ANYSTR],
)
self.assertEqual(self.getMessages(1), [])
def testRejectRedactOtherUser(self):
"""Channel op writes a message and a user attempts to redact it."""
msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop")
self.sendLine(2, f"REDACT #chan {msgid} :oops")
self.assertMessageMatch(
self.getMessage(2),
command="FAIL",
params=["REDACT", "REDACT_FORBIDDEN", "#chan", msgid, ANYSTR],
)
self.assertEqual(self.getMessages(1), [])
@pytest.mark.parametrize(
"chathistory_requester",
[
pytest.param(1, id="chathistory-to-chanop"),
pytest.param(2, id="chathistory-to-user"),
],
)
def testOpSelfRedactChathistory(self, chathistory_requester):
"""Channel op writes a message and redacts it themselves; both the op
and a regular user check the chathistory afterward.
https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md#chat-history
"""
msgid = self._setupRedactTest(
redacteeId=1, redacteeNick="chanop", chathistory=True
)
self.sendLine(1, f"REDACT #chan {msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("chanop!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
self.getMessages(1)
self.getMessages(2)
self.sendLine(chathistory_requester, "CHATHISTORY LATEST #chan * 10")
(start_msg, *msgs, end_msg) = self.getMessages(chathistory_requester)
self.assertMessageMatch(
start_msg,
command="BATCH",
params=[StrRe(r"\+.+"), "chathistory", "#chan"],
)
batch_tag = start_msg.params[0][1:]
# remove Ergo's event-playback fallback
msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")]
self.assertMessageMatch(end_msg, command="BATCH", params=["-" + batch_tag])
if len(msgs) == 0:
pass # Server removed the message entirely
elif len(msgs) == 1:
# Server replaced with the REDACT
self.assertMessageMatch(
msgs[0],
prefix=StrRe("sender!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
elif len(msgs) == 2:
# Server appended the REDACT
self.assertMessageMatch(
msgs[0],
tags={"msgid": msgid, **ANYDICT},
command="PRIVMSG",
params=["#chan", msgid, "hello there"],
)
self.assertMessageMatch(
msgs[1],
prefix=StrRe("sender!.*"),
command="REDACT",
params=["#chan", msgid, "oops"],
)
else:
self.assertTrue(False, fail_msg=f"Unexpectedly many messages: {msgs}")
def testOpRedactNonExistant(self):
"""Channel op writes a message and redacts a random non-existant id."""
self._setupRedactTest(redacteeId=1, redacteeNick="chanop")
nonexistent_msgid = str(uuid.uuid4())
self.sendLine(1, f"REDACT #chan {nonexistent_msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
command="FAIL",
params=["REDACT", "UNKNOWN_MSGID", "#chan", nonexistent_msgid, ANYSTR],
)
self.assertEqual(self.getMessages(2), [])
def testOpRedactWrongChan(self):
"""Channel op writes a message and redacts it, but uses the wrong channel
as target."""
msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop")
self.sendLine(1, "JOIN #otherChan")
self.getMessages(1)
self.sendLine(1, f"REDACT #otherChan {msgid} :oops")
msg = self.getMessage(1)
self.assertMessageMatch(
msg,
command="FAIL",
)
if msg.params[1] == "UNKNOWN_MSGID":
self.assertMessageMatch(
msg,
command="FAIL",
params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR],
)
else:
self.assertMessageMatch(
msg,
command="FAIL",
params=["REDACT", "REDACT_FORBIDDEN", "#otherChan", ANYSTR],
)
self.assertEqual(self.getMessages(2), [])
@cases.mark_specifications("IRCv3")
@cases.mark_capabilities(*CAPABILITIES)
@cases.mark_services
@pytest.mark.private_chathistory
class PmRedactTestCase(cases.BaseServerTestCase):
"""Tests REDACT command in private messages between authenticated accounts"""
def _setupRedactTest(self, chathistory=False):
capabilities = [*CAPABILITIES, "sasl"]
if chathistory:
capabilities.extend(["batch", "draft/chathistory"])
self.controller.registerUser(self, "sender", "senderpass")
self.controller.registerUser(self, "recipient", "recipientpass")
self.connectClient(
"sender",
password="senderpass",
capabilities=capabilities,
skip_if_cap_nak=True,
)
self.connectClient(
"recipient",
password="recipientpass",
capabilities=capabilities,
skip_if_cap_nak=True,
)
self.getMessages(2) # synchronize
self.getMessages(1)
self.sendLine(1, "@label=1234 PRIVMSG recipient :hello there")
echo = self.getMessage(1)
self.assertMessageMatch(
echo,
tags={"label": "1234", "msgid": StrRe("[^ ]+"), **ANYDICT},
prefix=StrRe("sender!.*"),
command="PRIVMSG",
params=["recipient", "hello there"],
)
msgid = echo.tags["msgid"]
self.assertMessageMatch(
self.getMessage(2),
tags={"msgid": msgid, **ANYDICT},
prefix=StrRe("sender!.*"),
command="PRIVMSG",
params=["recipient", "hello there"],
)
return msgid
def testRelaySenderRedact(self):
"""Someone writes a message in private and redacts it themselves."""
msgid = self._setupRedactTest()
self.sendLine(1, f"REDACT recipient {msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("sender!.*"),
command="REDACT",
params=["recipient", msgid, "oops"],
)
self.assertMessageMatch(
self.getMessage(2),
prefix=StrRe("sender!.*"),
command="REDACT",
params=["recipient", msgid, "oops"],
)
def testRelayRecipientRedact(self):
"""Someone writes a message in private and their recipient redacts it.
Servers may either accept or reject this."""
msgid = self._setupRedactTest()
self.sendLine(2, f"REDACT sender {msgid} :oops")
msg = self.getMessage(2)
if msg.command == "REDACT":
self.assertMessageMatch(
msg,
prefix=StrRe("recipient!.*"),
command="REDACT",
params=["sender", msgid, "oops"],
)
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("user!.*"),
command="REDACT",
params=["sender", msgid, "oops"],
)
else:
self.assertMessageMatch(
msg,
command="FAIL",
params=[
"REDACT",
StrRe("(REDACT_FORBIDDEN|UNKNOWN_MSGID)"),
"sender",
msgid,
ANYSTR,
],
)
self.assertEqual(self.getMessages(1), [])
@pytest.mark.parametrize("nick", ["sender", "recipient"])
def testRejectRedactOtherUser(self, nick):
"""Someone writes a message in private to someone else and an unrelated person
attempts to redact it."""
msgid = self._setupRedactTest()
self.controller.registerUser(self, "censor", "censorpass")
self.connectClient(
"censor",
password="censorpass",
capabilities=[*CAPABILITIES, "sasl"],
skip_if_cap_nak=True,
)
self.getMessages(3) # synchronize
self.sendLine(3, f"REDACT {nick} {msgid} :oops")
self.assertMessageMatch(
self.getMessage(3),
command="FAIL",
params=[
"REDACT",
StrRe("(REDACT_FORBIDDEN|UNKNOWN_MSGID)"),
nick,
msgid,
ANYSTR,
],
)
self.assertEqual(self.getMessages(1), [])
self.assertEqual(self.getMessages(2), [])
@pytest.mark.parametrize(
"chathistory_requester",
[
pytest.param(1, id="chathistory-to-sender"),
pytest.param(2, id="chathistory-to-recipient"),
],
)
@pytest.mark.private_chathistory
def testSenderRedactChathistory(self, chathistory_requester):
"""Channel op writes a message and redacts it themselves; both the op
and a regular user check the chathistory afterward.
https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md#chat-history
"""
msgid = self._setupRedactTest(chathistory=True)
self.sendLine(1, f"REDACT recipient {msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("sender!.*"),
command="REDACT",
params=["recipient", msgid, "oops"],
)
self.getMessages(1)
self.getMessages(2)
if chathistory_requester == 1:
others_nick = "recipient"
else:
others_nick = "sender"
self.sendLine(chathistory_requester, f"CHATHISTORY LATEST {others_nick} * 10")
(start_msg, *msgs, end_msg) = self.getMessages(chathistory_requester)
self.assertMessageMatch(
start_msg,
command="BATCH",
params=[StrRe(r"\+.+"), "chathistory", others_nick],
)
batch_tag = start_msg.params[0][1:]
# remove Ergo's event-playback fallback
msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")]
self.assertMessageMatch(end_msg, command="BATCH", params=["-" + batch_tag])
if len(msgs) == 0:
pass # Server removed the message entirely
elif len(msgs) == 1:
# Server replaced with the REDACT
self.assertMessageMatch(
msgs[0],
prefix=StrRe("sender!.*"),
command="REDACT",
params=["recipient", msgid, "oops"],
)
elif len(msgs) == 2:
# Server appended the REDACT
self.assertMessageMatch(
msgs[0],
tags={"msgid": msgid, **ANYDICT},
command="PRIVMSG",
params=["recipient", msgid, "hello there"],
)
self.assertMessageMatch(
msgs[1],
prefix=StrRe("sender!.*"),
command="REDACT",
params=["recipient", msgid, "oops"],
)
else:
self.assertTrue(False, fail_msg=f"Unexpectedly many messages: {msgs}")
def testRedactNonExistant(self):
"""Someone writes a message in private to someone else and redacts a random
non-existant id."""
self._setupRedactTest()
nonexistent_msgid = str(uuid.uuid4())
self.sendLine(1, f"REDACT recipient {nonexistent_msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
command="FAIL",
params=["REDACT", "UNKNOWN_MSGID", "recipient", nonexistent_msgid, ANYSTR],
)
self.assertEqual(self.getMessages(2), [])
def testOpRedactWrongChan(self):
"""Channel op writes a message and redacts it, but uses the wrong channel
as target."""
msgid = self._setupRedactTest()
self.sendLine(1, "JOIN #otherChan")
self.getMessages(1)
self.sendLine(1, f"REDACT #otherChan {msgid} :oops")
self.assertMessageMatch(
self.getMessage(1),
command="FAIL",
params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR],
)
self.assertEqual(self.getMessages(2), [])

View File

@ -201,10 +201,6 @@ class WhowasTestCase(cases.BaseServerTestCase):
)
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
@cases.xfailIfSoftware(
["InspIRCd"],
"Feature not released yet: https://github.com/inspircd/inspircd/pull/1967",
)
def testWhowasMultiple(self):
"""
"The history is searched backward, returning the most recent entry first."
@ -215,10 +211,6 @@ class WhowasTestCase(cases.BaseServerTestCase):
self._testWhowasMultiple(second_result=True, whowas_command="WHOWAS nick2")
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
@cases.xfailIfSoftware(
["InspIRCd"],
"Feature not released yet: https://github.com/inspircd/inspircd/pull/1968",
)
def testWhowasCount1(self):
"""
"If there are multiple entries, up to <count> replies will be returned"
@ -229,10 +221,6 @@ class WhowasTestCase(cases.BaseServerTestCase):
self._testWhowasMultiple(second_result=False, whowas_command="WHOWAS nick2 1")
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
@cases.xfailIfSoftware(
["InspIRCd"],
"Feature not released yet: https://github.com/inspircd/inspircd/pull/1968",
)
def testWhowasCount2(self):
"""
"If there are multiple entries, up to <count> replies will be returned"
@ -243,10 +231,6 @@ class WhowasTestCase(cases.BaseServerTestCase):
self._testWhowasMultiple(second_result=True, whowas_command="WHOWAS nick2 2")
@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
@cases.xfailIfSoftware(
["InspIRCd"],
"Feature not released yet: https://github.com/inspircd/inspircd/pull/1968",
)
def testWhowasCountNegative(self):
"""
"If a non-positive number is passed as being <count>, then a full search
@ -264,10 +248,6 @@ class WhowasTestCase(cases.BaseServerTestCase):
@cases.xfailIfSoftware(
["ircu2"], "Fix not released yet: https://github.com/UndernetIRC/ircu2/pull/19"
)
@cases.xfailIfSoftware(
["InspIRCd"],
"Feature not released yet: https://github.com/inspircd/inspircd/pull/1967",
)
def testWhowasCountZero(self):
"""
"If a non-positive number is passed as being <count>, then a full search

View File

@ -35,6 +35,7 @@ class Capabilities(enum.Enum):
EXTENDED_JOIN = "extended-join"
EXTENDED_MONITOR = "extended-monitor"
LABELED_RESPONSE = "labeled-response"
MESSAGE_REDACTION = "draft/message-redaction"
MESSAGE_TAGS = "message-tags"
MULTILINE = "draft/multiline"
MULTI_PREFIX = "multi-prefix"
@ -52,7 +53,6 @@ class Capabilities(enum.Enum):
@enum.unique
class IsupportTokens(enum.Enum):
ACCOUNTEXTBAN = "ACCOUNTEXTBAN"
BOT = "BOT"
ELIST = "ELIST"
INVEX = "INVEX"

View File

@ -65,7 +65,7 @@ def get_install_steps(*, software_config, software_id, version_flavor):
install_steps = [
{
"name": f"Checkout {name}",
"uses": "actions/checkout@v2",
"uses": "actions/checkout@v3",
"with": {
"repository": software_config["repository"],
"ref": ref,
@ -94,7 +94,7 @@ def get_build_job(*, software_config, software_id, version_flavor):
cache = [
{
"name": "Cache dependencies",
"uses": "actions/cache@v2",
"uses": "actions/cache@v3",
"with": {
"path": f"~/.cache\n${{ github.workspace }}/{path}\n",
"key": "3-${{ runner.os }}-"
@ -123,10 +123,10 @@ def get_build_job(*, software_config, software_id, version_flavor):
"run": "cd ~/; mkdir -p .local/ go/",
},
*cache,
{"uses": "actions/checkout@v2"},
{"uses": "actions/checkout@v3"},
{
"name": "Set up Python 3.7",
"uses": "actions/setup-python@v2",
"uses": "actions/setup-python@v4",
"with": {"python-version": 3.7},
},
*install_steps,
@ -159,7 +159,7 @@ def get_test_job(*, config, test_config, test_id, version_flavor, jobs):
downloads.append(
{
"name": "Download build artefacts",
"uses": "actions/download-artifact@v2",
"uses": "actions/download-artifact@v3",
"with": {"name": f"installed-{software_id}", "path": "~"},
}
)
@ -194,10 +194,10 @@ def get_test_job(*, config, test_config, test_id, version_flavor, jobs):
"runs-on": "ubuntu-20.04",
"needs": needs,
"steps": [
{"uses": "actions/checkout@v2"},
{"uses": "actions/checkout@v3"},
{
"name": "Set up Python 3.7",
"uses": "actions/setup-python@v2",
"uses": "actions/setup-python@v4",
"with": {"python-version": 3.7},
},
*downloads,
@ -231,7 +231,7 @@ def get_test_job(*, config, test_config, test_id, version_flavor, jobs):
{
"name": "Publish results",
"if": "always()",
"uses": "actions/upload-artifact@v2",
"uses": "actions/upload-artifact@v3",
"with": {
"name": f"pytest-results_{test_id}_{version_flavor.value}",
"path": "pytest.xml",
@ -250,7 +250,7 @@ def upload_steps(software_id):
},
{
"name": "Upload build artefacts",
"uses": "actions/upload-artifact@v2",
"uses": "actions/upload-artifact@v3",
"with": {
"name": f"installed-{software_id}",
"path": "~/artefacts-*.tar.gz",
@ -311,10 +311,10 @@ def generate_workflow(config: dict, version_flavor: VersionFlavor):
# this job then
"if": "success() || failure()",
"steps": [
{"uses": "actions/checkout@v2"},
{"uses": "actions/checkout@v3"},
{
"name": "Download Artifacts",
"uses": "actions/download-artifact@v2",
"uses": "actions/download-artifact@v3",
"with": {"path": "artifacts"},
},
{

View File

@ -26,6 +26,7 @@ markers =
extended-join
extended-monitor
labeled-response
draft/message-redaction
message-tags
draft/multiline
multi-prefix
@ -34,7 +35,6 @@ markers =
sts
# isupport tokens
ACCOUNTEXTBAN
BOT
ELIST
INVEX

View File

@ -143,7 +143,7 @@ software:
name: InspIRCd
repository: inspircd/inspircd
refs: &inspircd_refs
stable: v3.12.0
stable: v3.15.0
release: null
devel: master
devel_release: insp3
@ -153,9 +153,13 @@ software:
separate_build_job: true
build_script: &inspircd_build_script |
cd $GITHUB_WORKSPACE/inspircd/
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch
# Insp3 <= 3.16.0 and Insp4 <= 4.0.0a21 don't support -DINSPIRCD_UNLIMITED_MAINLOOP
patch src/inspircd.cpp < $GITHUB_WORKSPACE/patches/inspircd_mainloop.patch || true
./configure --prefix=$HOME/.local/inspircd --development
make -j 4
CXXFLAGS=-DINSPIRCD_UNLIMITED_MAINLOOP make -j 4
make install
irc2:
name: irc2
@ -268,8 +272,8 @@ software:
name: UnrealIRCd 6
repository: unrealircd/unrealircd
refs:
stable: cedd23ae9cdd5985ce16e9869cbdb808479c3fc4 # 6.0.3
release: cedd23ae9cdd5985ce16e9869cbdb808479c3fc4 # 6.0.3
stable: da3c1c654481a33035b9c703957e1c25d0158259 # 6.0.7
release: da3c1c654481a33035b9c703957e1c25d0158259 # 6.0.7
devel: unreal60_dev
devel_release: null
path: unrealircd
@ -285,6 +289,7 @@ software:
CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick
make -j 4
make install
~/.local/unrealircd/unrealircd module install third/react
# Prevent download of geoIP database on first startup
sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf