Merge pull request #143 from progval/elist

Add tests for ELIST
This commit is contained in:
2022-04-13 18:58:12 +02:00
committed by GitHub
23 changed files with 546 additions and 108 deletions

View File

@ -432,8 +432,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -470,8 +470,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -502,8 +502,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -541,8 +541,8 @@ jobs:
cd $GITHUB_WORKSPACE/ergo/ cd $GITHUB_WORKSPACE/ergo/
make build make build
make install make install
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -579,8 +579,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -611,8 +611,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -649,8 +649,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -687,8 +687,8 @@ jobs:
./configure --prefix=$HOME/.local/ --with-maxcon=1024 --enable-debug ./configure --prefix=$HOME/.local/ --with-maxcon=1024 --enable-debug
make -j 4 make -j 4
make install make install
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -714,8 +714,8 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: pip install git+https://github.com/ProgVal/Limnoria.git@testing cryptography run: pip install git+https://github.com/ProgVal/Limnoria.git@testing cryptography
pyxmpp2-scram pyxmpp2-scram
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -783,8 +783,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -821,8 +821,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -853,8 +853,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -891,8 +891,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -923,8 +923,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -949,8 +949,8 @@ jobs:
python-version: 3.7 python-version: 3.7
- name: Install dependencies - name: Install dependencies
run: pip install git+https://github.com/sopel-irc/sopel.git run: pip install git+https://github.com/sopel-irc/sopel.git
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -981,8 +981,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1013,8 +1013,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1051,8 +1051,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1083,8 +1083,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip

View File

@ -117,8 +117,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -155,8 +155,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -187,8 +187,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip

View File

@ -475,8 +475,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -513,8 +513,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -545,8 +545,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -577,8 +577,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -616,8 +616,8 @@ jobs:
cd $GITHUB_WORKSPACE/ergo/ cd $GITHUB_WORKSPACE/ergo/
make build make build
make install make install
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -654,8 +654,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -686,8 +686,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -724,8 +724,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -756,8 +756,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -810,8 +810,8 @@ jobs:
mkdir -p $HOME/.local/bin mkdir -p $HOME/.local/bin
cp $HOME/.local/sbin/ircd $HOME/.local/bin/ircd' cp $HOME/.local/sbin/ircd $HOME/.local/bin/ircd'
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -848,8 +848,8 @@ jobs:
./configure --prefix=$HOME/.local/ --with-maxcon=1024 --enable-debug ./configure --prefix=$HOME/.local/ --with-maxcon=1024 --enable-debug
make -j 4 make -j 4
make install make install
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -874,8 +874,8 @@ jobs:
python-version: 3.7 python-version: 3.7
- name: Install dependencies - name: Install dependencies
run: pip install limnoria==2022.03.17 cryptography pyxmpp2-scram run: pip install limnoria==2022.03.17 cryptography pyxmpp2-scram
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -943,8 +943,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -981,8 +981,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1013,8 +1013,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1051,8 +1051,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1083,8 +1083,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1109,8 +1109,8 @@ jobs:
python-version: 3.7 python-version: 3.7
- name: Install dependencies - name: Install dependencies
run: pip install sopel==7.1.8 run: pip install sopel==7.1.8
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1141,8 +1141,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1173,8 +1173,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1211,8 +1211,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -1243,8 +1243,8 @@ jobs:
path: '~' path: '~'
- name: Unpack artefacts - name: Unpack artefacts
run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \; run: cd ~; find -name 'artefacts-*.tar.gz' -exec tar -xzf '{}' \;
- name: Install Atheme - name: Install system dependencies
run: sudo apt-get install atheme-services run: sudo apt-get install atheme-services faketime
- name: Install irctest dependencies - name: Install irctest dependencies
run: |- run: |-
python -m pip install --upgrade pip python -m pip install --upgrade pip

View File

@ -101,6 +101,7 @@ SOPEL_SELECTORS := \
# Tests marked with arbitrary_client_tags can't pass because Unreal whitelists which tags it relays # Tests marked with arbitrary_client_tags can't pass because Unreal whitelists which tags it relays
# Tests marked with react_tag can't pass because Unreal blocks +draft/react https://github.com/unrealircd/unrealircd/pull/149 # Tests marked with react_tag can't pass because Unreal blocks +draft/react https://github.com/unrealircd/unrealircd/pull/149
# Tests marked with private_chathistory can't pass because Unreal does not implement CHATHISTORY for DMs # Tests marked with private_chathistory can't pass because Unreal does not implement CHATHISTORY for DMs
UNREALIRCD_SELECTORS := \ UNREALIRCD_SELECTORS := \
not Ergo \ not Ergo \
and not deprecated \ and not deprecated \

View File

@ -18,6 +18,7 @@ have no side effect.
Install irctest and dependencies: Install irctest and dependencies:
``` ```
sudo apt install faketime # Optional, but greatly speeds up irctest/server_tests/list.py
cd ~ cd ~
git clone https://github.com/ProgVal/irctest.git git clone https://github.com/ProgVal/irctest.git
cd irctest cd irctest

View File

@ -189,6 +189,10 @@ class BaseServerController(_BaseController):
"""Character used for the 'mute' extban""" """Character used for the 'mute' extban"""
nickserv = "NickServ" nickserv = "NickServ"
def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs)
self.faketime_enabled = False
def get_hostname_and_port(self) -> Tuple[str, int]: def get_hostname_and_port(self) -> Tuple[str, int]:
return find_hostname_and_port() return find_hostname_and_port()
@ -202,6 +206,7 @@ class BaseServerController(_BaseController):
run_services: bool, run_services: bool,
valid_metadata_keys: Optional[Set[str]], valid_metadata_keys: Optional[Set[str]],
invalid_metadata_keys: Optional[Set[str]], invalid_metadata_keys: Optional[Set[str]],
faketime: Optional[str],
) -> None: ) -> None:
raise NotImplementedError() raise NotImplementedError()

View File

@ -508,6 +508,12 @@ class BaseServerTestCase(
server_support: Optional[Dict[str, Optional[str]]] server_support: Optional[Dict[str, Optional[str]]]
run_services = False run_services = False
faketime: Optional[str] = None
"""If not None and the controller supports it and libfaketime is available,
runs the server using faketime and this value set as the $FAKETIME env variable.
Tests must check ``self.controller.faketime_enabled`` is True before
relying on this."""
__new__ = object.__new__ # pytest won't collect Generic[] subclasses otherwise __new__ = object.__new__ # pytest won't collect Generic[] subclasses otherwise
def setUp(self) -> None: def setUp(self) -> None:
@ -522,6 +528,7 @@ class BaseServerTestCase(
invalid_metadata_keys=self.invalid_metadata_keys, invalid_metadata_keys=self.invalid_metadata_keys,
ssl=self.ssl, ssl=self.ssl,
run_services=self.run_services, run_services=self.run_services,
faketime=self.faketime,
) )
self.clients: Dict[TClientName, client_mock.ClientMock] = {} self.clients: Dict[TClientName, client_mock.ClientMock] = {}

View File

@ -102,6 +102,7 @@ class BahamutController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_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: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -136,15 +137,21 @@ class BahamutController(BaseServerController, DirectoryBasedController):
# pem_path=self.pem_path, # pem_path=self.pem_path,
) )
) )
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
# "strace", "-f", "-e", "file", *faketime_cmd,
"ircd", "ircd",
"-t", # don't fork "-t", # don't fork
"-f", "-f",
os.path.join(self.directory, "server.conf"), os.path.join(self.directory, "server.conf"),
], ],
# stdout=subprocess.DEVNULL,
) )
if run_services: if run_services:

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set from typing import Optional, Set
@ -43,6 +44,7 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
run_services: bool, run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -73,8 +75,16 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
) )
) )
assert self.directory assert self.directory
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
self.binary_name, self.binary_name,
"-foreground", "-foreground",
"-configfile", "-configfile",

View File

@ -1,6 +1,7 @@
import copy import copy
import json import json
import os import os
import shutil
import subprocess import subprocess
from typing import Any, Dict, Optional, Set, Type, Union from typing import Any, Dict, Optional, Set, Type, Union
@ -155,6 +156,7 @@ class ErgoController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None, restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
config: Optional[Any] = None, config: Optional[Any] = None,
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
@ -202,8 +204,15 @@ class ErgoController(BaseServerController, DirectoryBasedController):
self._write_config() self._write_config()
subprocess.call(["ergo", "initdb", "--conf", self._config_path, "--quiet"]) subprocess.call(["ergo", "initdb", "--conf", self._config_path, "--quiet"])
subprocess.call(["ergo", "mkcerts", "--conf", self._config_path, "--quiet"]) subprocess.call(["ergo", "mkcerts", "--conf", self._config_path, "--quiet"])
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
["ergo", "run", "--conf", self._config_path, "--quiet"] [*faketime_cmd, "ergo", "run", "--conf", self._config_path, "--quiet"]
) )
def wait_for_services(self) -> None: def wait_for_services(self) -> None:

View File

@ -42,6 +42,7 @@ class ExternalServerController(BaseServerController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None, restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
pass pass

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -114,6 +115,7 @@ class InspircdController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None, restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str] = None,
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -147,8 +149,16 @@ class InspircdController(BaseServerController, DirectoryBasedController):
) )
) )
assert self.directory assert self.directory
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"inspircd", "inspircd",
"--nofork", "--nofork",
"--config", "--config",

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -51,6 +52,7 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
run_services: bool, run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -76,8 +78,16 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
pidfile=pidfile, pidfile=pidfile,
) )
) )
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"ircd", "ircd",
"-s", # no iauth "-s", # no iauth
"-p", "-p",

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -70,6 +71,7 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
run_services: bool, run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -95,8 +97,16 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
pidfile=pidfile, pidfile=pidfile,
) )
) )
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"ircd", "ircd",
"-n", # don't detach "-n", # don't detach
"-f", "-f",

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -92,6 +93,7 @@ class MammonController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_metadata_keys: Optional[Set[str]] = None, restricted_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
if password is not None: if password is not None:
raise NotImplementedByController("PASS command") raise NotImplementedByController("PASS command")
@ -113,8 +115,16 @@ class MammonController(BaseServerController, DirectoryBasedController):
# with self.open_file('server.yml', 'r') as fd: # with self.open_file('server.yml', 'r') as fd:
# print(fd.read()) # print(fd.read())
assert self.directory assert self.directory
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"mammond", "mammond",
"--nofork", # '--debug', "--nofork", # '--debug',
"--config", "--config",

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -56,6 +57,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_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: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -81,6 +83,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
fd.write("\n") fd.write("\n")
assert self.directory assert self.directory
with self.open_file("server.conf") as fd: with self.open_file("server.conf") as fd:
fd.write( fd.write(
TEMPLATE_CONFIG.format( TEMPLATE_CONFIG.format(
@ -94,8 +97,16 @@ class NgircdController(BaseServerController, DirectoryBasedController):
empty_file=os.path.join(self.directory, "empty.txt"), empty_file=os.path.join(self.directory, "empty.txt"),
) )
) )
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"ngircd", "ngircd",
"--nodaemon", "--nodaemon",
"--config", "--config",

View File

@ -1,4 +1,5 @@
import os import os
import shutil
import subprocess import subprocess
from typing import Optional, Set, Type from typing import Optional, Set, Type
@ -69,6 +70,7 @@ class SnircdController(BaseServerController, DirectoryBasedController):
run_services: bool, run_services: bool,
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
faketime: Optional[str],
) -> None: ) -> None:
if valid_metadata_keys or invalid_metadata_keys: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -94,8 +96,16 @@ class SnircdController(BaseServerController, DirectoryBasedController):
pidfile=pidfile, pidfile=pidfile,
) )
) )
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*faketime_cmd,
"ircd", "ircd",
"-n", # don't detach "-n", # don't detach
"-f", "-f",

View File

@ -156,6 +156,7 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
valid_metadata_keys: Optional[Set[str]] = None, valid_metadata_keys: Optional[Set[str]] = None,
invalid_metadata_keys: Optional[Set[str]] = None, invalid_metadata_keys: Optional[Set[str]] = None,
restricted_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: if valid_metadata_keys or invalid_metadata_keys:
raise NotImplementedByController( raise NotImplementedByController(
@ -192,6 +193,7 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
fd.write("\n") fd.write("\n")
assert self.directory assert self.directory
with self.open_file("unrealircd.conf") as fd: with self.open_file("unrealircd.conf") as fd:
fd.write( fd.write(
TEMPLATE_CONFIG.format( TEMPLATE_CONFIG.format(
@ -225,9 +227,16 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
proot_cmd = ["proot", "-b", f"{tmpdir}:{unrealircd_prefix}/tmp"] proot_cmd = ["proot", "-b", f"{tmpdir}:{unrealircd_prefix}/tmp"]
self.using_proot = True self.using_proot = True
if faketime and shutil.which("faketime"):
faketime_cmd = ["faketime", "-f", faketime]
self.faketime_enabled = True
else:
faketime_cmd = []
self.proc = subprocess.Popen( self.proc = subprocess.Popen(
[ [
*proot_cmd, *proot_cmd,
*faketime_cmd,
"unrealircd", "unrealircd",
"-t", "-t",
"-F", # BOOT_NOFORK "-F", # BOOT_NOFORK

View File

@ -66,6 +66,7 @@ RPL_WHOISIDLE = "317"
RPL_ENDOFWHOIS = "318" RPL_ENDOFWHOIS = "318"
RPL_WHOISCHANNELS = "319" RPL_WHOISCHANNELS = "319"
RPL_WHOISSPECIAL = "320" RPL_WHOISSPECIAL = "320"
RPL_LISTSTART = "321"
RPL_LIST = "322" RPL_LIST = "322"
RPL_LISTEND = "323" RPL_LISTEND = "323"
RPL_CHANNELMODEIS = "324" RPL_CHANNELMODEIS = "324"

View File

@ -3,39 +3,60 @@ The LIST command (`RFC 1459
<https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.6>`__, <https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.6>`__,
`RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.6>`__, `RFC 2812 <https://datatracker.ietf.org/doc/html/rfc2812#section-3.2.6>`__,
`Modern <https://modern.ircdocs.horse/#list-message>`__) `Modern <https://modern.ircdocs.horse/#list-message>`__)
TODO: check with Modern
""" """
import time
from irctest import cases from irctest import cases
from irctest import cases, runner
from irctest.numerics import RPL_LIST, RPL_LISTEND, RPL_LISTSTART
class ListTestCase(cases.BaseServerTestCase):
class _BasedListTestCase(cases.BaseServerTestCase):
def _parseChanList(self, client):
channels = set()
while True:
m = self.getMessage(client)
if m.command == RPL_LISTEND:
break
if m.command == RPL_LIST:
if m.params[1].startswith("&"):
# skip local pseudo-channels listed by ngircd and ircu
continue
channels.add(m.params[1])
return channels
class ListTestCase(_BasedListTestCase):
@cases.mark_specifications("RFC1459", "RFC2812") @cases.mark_specifications("RFC1459", "RFC2812")
@cases.xfailIfSoftware(["irc2"], "irc2 deprecated LIST") @cases.xfailIfSoftware(["irc2"], "irc2 deprecated LIST")
def testListEmpty(self): def testListEmpty(self):
"""<https://tools.ietf.org/html/rfc1459#section-4.2.6> """<https://tools.ietf.org/html/rfc1459#section-4.2.6>
<https://tools.ietf.org/html/rfc2812#section-3.2.6> <https://tools.ietf.org/html/rfc2812#section-3.2.6>
<https://modern.ircdocs.horse/#list-message>
""" """
self.connectClient("foo") self.connectClient("foo")
self.connectClient("bar") self.connectClient("bar")
self.getMessages(1) self.getMessages(1)
self.sendLine(2, "LIST") self.sendLine(2, "LIST")
m = self.getMessage(2) m = self.getMessage(2)
if m.command == "321": if m.command == RPL_LISTSTART:
# skip RPL_LISTSTART # skip
m = self.getMessage(2) m = self.getMessage(2)
# skip local pseudo-channels listed by ngircd and ircu # skip local pseudo-channels listed by ngircd and ircu
while m.command == "322" and m.params[1].startswith("&"): while m.command == RPL_LIST and m.params[1].startswith("&"):
m = self.getMessage(2) m = self.getMessage(2)
self.assertNotEqual( self.assertNotEqual(
m.command, m.command,
"322", # RPL_LIST RPL_LIST,
"LIST response gives (at least) one channel, whereas there " "is none.", "LIST response gives (at least) one channel, whereas there " "is none.",
) )
self.assertMessageMatch( self.assertMessageMatch(
m, m,
command="323", # RPL_LISTEND command=RPL_LISTEND,
fail_msg="Second reply to LIST is not 322 (RPL_LIST) " fail_msg="Second reply to LIST is not 322 (RPL_LIST) "
"or 323 (RPL_LISTEND), or but: {msg}", "or 323 (RPL_LISTEND), or but: {msg}",
) )
@ -46,6 +67,8 @@ class ListTestCase(cases.BaseServerTestCase):
"""When a channel exists, LIST should get it in a reply. """When a channel exists, LIST should get it in a reply.
<https://tools.ietf.org/html/rfc1459#section-4.2.6> <https://tools.ietf.org/html/rfc1459#section-4.2.6>
<https://tools.ietf.org/html/rfc2812#section-3.2.6> <https://tools.ietf.org/html/rfc2812#section-3.2.6>
<https://modern.ircdocs.horse/#list-message>
""" """
self.connectClient("foo") self.connectClient("foo")
self.connectClient("bar") self.connectClient("bar")
@ -53,34 +76,335 @@ class ListTestCase(cases.BaseServerTestCase):
self.getMessages(1) self.getMessages(1)
self.sendLine(2, "LIST") self.sendLine(2, "LIST")
m = self.getMessage(2) m = self.getMessage(2)
if m.command == "321": if m.command == RPL_LISTSTART:
# skip RPL_LISTSTART # skip
m = self.getMessage(2) m = self.getMessage(2)
self.assertNotEqual( self.assertNotEqual(
m.command, m.command,
"323", # RPL_LISTEND RPL_LISTEND,
fail_msg="LIST response ended (ie. 323, aka RPL_LISTEND) " fail_msg="LIST response ended (ie. 323, aka RPL_LISTEND) "
"without listing any channel, whereas there is one.", "without listing any channel, whereas there is one.",
) )
self.assertMessageMatch( self.assertMessageMatch(
m, m,
command="322", # RPL_LIST command=RPL_LIST,
fail_msg="Second reply to LIST is not 322 (RPL_LIST), " fail_msg="Second reply to LIST is not 322 (RPL_LIST), "
"nor 323 (RPL_LISTEND) but: {msg}", "nor 323 (RPL_LISTEND) but: {msg}",
) )
m = self.getMessage(2) m = self.getMessage(2)
# skip local pseudo-channels listed by ngircd and ircu # skip local pseudo-channels listed by ngircd and ircu
while m.command == "322" and m.params[1].startswith("&"): while m.command == RPL_LIST and m.params[1].startswith("&"):
m = self.getMessage(2) m = self.getMessage(2)
self.assertNotEqual( self.assertNotEqual(
m.command, m.command,
"322", # RPL_LIST RPL_LIST,
fail_msg="LIST response gives (at least) two channels, " fail_msg="LIST response gives (at least) two channels, "
"whereas there is only one.", "whereas there is only one.",
) )
self.assertMessageMatch( self.assertMessageMatch(
m, m,
command="323", # RPL_LISTEND command=RPL_LISTEND,
fail_msg="Third reply to LIST is not 322 (RPL_LIST) " fail_msg="Third reply to LIST is not 322 (RPL_LIST) "
"or 323 (RPL_LISTEND), or but: {msg}", "or 323 (RPL_LISTEND), or but: {msg}",
) )
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListMask(self):
"""
"M: Searching based on mask."
-- <https://modern.ircdocs.horse/#elist-parameter>
-- https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8
"""
self.connectClient("foo")
if "M" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=M")
self.connectClient("bar")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.sendLine(2, "LIST *an1")
self.assertEqual(self._parseChanList(2), {"#chan1"})
self.sendLine(2, "LIST *an2")
self.assertEqual(self._parseChanList(2), {"#chan2"})
self.sendLine(2, "LIST #c*n2")
self.assertEqual(self._parseChanList(2), {"#chan2"})
self.sendLine(2, "LIST *an3")
self.assertEqual(self._parseChanList(2), set())
self.sendLine(2, "LIST #ch*")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListNotMask(self):
"""
" N: Searching based on a non-matching mask. i.e., the opposite of M."
-- <https://modern.ircdocs.horse/#elist-parameter>
-- https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8
"""
self.connectClient("foo")
if "N" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=N")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.connectClient("bar")
self.sendLine(2, "LIST !*an1")
self.assertEqual(self._parseChanList(2), {"#chan2"})
self.sendLine(2, "LIST !*an2")
self.assertEqual(self._parseChanList(2), {"#chan1"})
self.sendLine(2, "LIST !#c*n2")
self.assertEqual(self._parseChanList(2), {"#chan1"})
self.sendLine(2, "LIST !*an3")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
self.sendLine(2, "LIST !#ch*")
self.assertEqual(self._parseChanList(2), set())
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListUsers(self):
"""
"U: Searching based on user count within the channel, via the "<val" and
">val" modifiers to search for a channel that has less or more than val users,
respectively."
-- <https://modern.ircdocs.horse/#elist-parameter>
-- https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8
"""
self.connectClient("foo")
if "M" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=M")
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 >0")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
self.sendLine(3, "LIST <1")
self.assertEqual(self._parseChanList(3), set())
self.sendLine(3, "LIST <100")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
self.sendLine(3, "LIST >1")
self.assertEqual(self._parseChanList(3), {"#chan2"})
self.sendLine(3, "LIST <2")
self.assertEqual(self._parseChanList(3), {"#chan1"})
self.sendLine(3, "LIST <100")
self.assertEqual(self._parseChanList(3), {"#chan1", "#chan2"})
class FaketimeListTestCase(_BasedListTestCase):
faketime = "+1y x30" # for every wall clock second, 1 minute passed for the server
def _sleep_minutes(self, n):
for _ in range(n):
if self.controller.faketime_enabled:
# From the server's point of view, 1 min will pass
time.sleep(2)
else:
time.sleep(60)
# reply to pings
self.getMessages(1)
self.getMessages(2)
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListCreationTime(self):
"""
" C: Searching based on channel creation time, via the "C<val" and "C>val"
modifiers to search for a channel creation time that is higher or lower
than val."
-- <https://modern.ircdocs.horse/#elist-parameter>
-- https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8
Unfortunately, this is ambiguous, because "val" is a time delta (in minutes),
not a timestamp.
On InspIRCd and Charybdis/Solanum, "C<val" is interpreted as "the channel was
created less than <val> minutes ago
On UnrealIRCd, Plexus, and Hybrid, it is interpreted as "the channel's creation
time is a timestamp lower than <val> minutes ago" (ie. the exact opposite)
"C: Searching based on channel creation time, via the "C<val" and "C>val"
modifiers to search for a channel that was created either less than `val`
minutes ago, or more than `val` minutes ago, respectively"
-- https://github.com/ircdocs/modern-irc/pull/171
"""
self.connectClient("foo")
if "C" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=C")
self.connectClient("bar")
self.sendLine(1, "JOIN #chan1")
self.getMessages(1)
# Helps debugging
self.sendLine(1, "TIME")
self.getMessages(1)
self._sleep_minutes(2)
# Helps debugging
self.sendLine(1, "TIME")
self.getMessages(1)
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self._sleep_minutes(1)
if self.controller.software_name in ("UnrealIRCd", "Plexus4", "Hybrid"):
self.sendLine(2, "LIST C<2")
self.assertEqual(self._parseChanList(2), {"#chan1"})
self.sendLine(2, "LIST C>2")
self.assertEqual(self._parseChanList(2), {"#chan2"})
self.sendLine(2, "LIST C>0")
self.assertEqual(self._parseChanList(2), set())
self.sendLine(2, "LIST C<0")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
self.sendLine(2, "LIST C>10")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
elif self.controller.software_name in ("Solanum", "Charybdis", "InspIRCd"):
self.sendLine(2, "LIST C>2")
self.assertEqual(self._parseChanList(2), {"#chan1"})
self.sendLine(2, "LIST C<2")
self.assertEqual(self._parseChanList(2), {"#chan2"})
self.sendLine(2, "LIST C<0")
if self.controller.software_name == "InspIRCd":
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
else:
self.assertEqual(self._parseChanList(2), set())
self.sendLine(2, "LIST C>0")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
self.sendLine(2, "LIST C<10")
self.assertEqual(self._parseChanList(2), {"#chan1", "#chan2"})
else:
assert False, f"{self.controller.software_name} not supported"
@cases.mark_isupport("ELIST")
@cases.mark_specifications("Modern")
def testListTopicTime(self):
"""
"T: Searching based on topic time, via the "T<val" and "T>val"
modifiers to search for a topic time that is lower or higher than
val respectively."
-- <https://modern.ircdocs.horse/#elist-parameter>
-- https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8
See testListCreationTime's docstring for comments on this.
"T: Searching based on topic set time, via the "T<val" and "T>val" modifiers
to search for a topic time that was set less than `val` minutes ago, or more
than `val` minutes ago, respectively."
-- https://github.com/ircdocs/modern-irc/pull/171
"""
self.connectClient("foo")
if "T" not in self.server_support.get("ELIST", ""):
raise runner.OptionalExtensionNotSupported("ELIST=T")
self.connectClient("bar")
self.sendLine(1, "JOIN #chan1")
self.sendLine(1, "JOIN #chan2")
self.getMessages(1)
self.sendLine(1, "TOPIC #chan1 :First channel")
self.getMessages(1)
# Helps debugging
self.sendLine(1, "TIME")
self.getMessages(1)
self._sleep_minutes(2)
# Helps debugging
self.sendLine(1, "TIME")
self.getMessages(1)
self.sendLine(1, "TOPIC #chan2 :Second channel")
self.getMessages(1)
self._sleep_minutes(1)
if self.controller.software_name in ("UnrealIRCd",):
self.sendLine(1, "LIST T<2")
self.assertEqual(self._parseChanList(1), {"#chan1"})
self.sendLine(1, "LIST T>2")
self.assertEqual(self._parseChanList(1), {"#chan2"})
self.sendLine(1, "LIST T>0")
self.assertEqual(self._parseChanList(1), set())
self.sendLine(1, "LIST T<0")
self.assertEqual(self._parseChanList(1), {"#chan1", "#chan2"})
self.sendLine(1, "LIST T>10")
self.assertEqual(self._parseChanList(1), {"#chan1", "#chan2"})
elif self.controller.software_name in (
"Solanum",
"Charybdis",
"InspIRCd",
"Plexus4",
"Hybrid",
):
self.sendLine(1, "LIST T>2")
self.assertEqual(self._parseChanList(1), {"#chan1"})
self.sendLine(1, "LIST T<2")
self.assertEqual(self._parseChanList(1), {"#chan2"})
self.sendLine(1, "LIST T<0")
if self.controller.software_name == "InspIRCd":
# Insp internally represents "LIST T>0" like "LIST"
self.assertEqual(self._parseChanList(1), {"#chan1", "#chan2"})
else:
self.assertEqual(self._parseChanList(1), set())
self.sendLine(1, "LIST T>0")
self.assertEqual(self._parseChanList(1), {"#chan1", "#chan2"})
self.sendLine(1, "LIST T<10")
self.assertEqual(self._parseChanList(1), {"#chan1", "#chan2"})
else:
assert False, f"{self.controller.software_name} not supported"

View File

@ -50,6 +50,7 @@ class Capabilities(enum.Enum):
@enum.unique @enum.unique
class IsupportTokens(enum.Enum): class IsupportTokens(enum.Enum):
BOT = "BOT" BOT = "BOT"
ELIST = "ELIST"
PREFIX = "PREFIX" PREFIX = "PREFIX"
MONITOR = "MONITOR" MONITOR = "MONITOR"
STATUSMSG = "STATUSMSG" STATUSMSG = "STATUSMSG"

View File

@ -208,8 +208,8 @@ def get_test_job(*, config, test_config, test_id, version_flavor, jobs):
*unpack, *unpack,
*install_steps, *install_steps,
{ {
"name": "Install Atheme", "name": "Install system dependencies",
"run": "sudo apt-get install atheme-services", "run": "sudo apt-get install atheme-services faketime",
}, },
{ {
"name": "Install irctest dependencies", "name": "Install irctest dependencies",

View File

@ -32,6 +32,7 @@ markers =
# isupport tokens # isupport tokens
BOT BOT
ELIST
MONITOR MONITOR
PREFIX PREFIX
STATUSMSG STATUSMSG