Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more flexible dim tests #273

Merged
merged 5 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ jobs:
image: oraclelinux:8
services:
mariadb:
image: mariadb:latest
image: mariadb:lts
env:
MARIADB_USER: dim
MARIADB_PASSWORD: dim
MARIADB_DATABASE: dim
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 'yes'
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
options: '--health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=4'
steps:
- name: Install dependencies
run: /bin/dnf install --assumeyes gcc python39-devel mariadb-devel git python39 make tar gzip
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
LAYER3DOMAIN_WHITELIST = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
### Debugging
SQLALCHEMY_DATABASE_URI_TEST = 'mysql://dim:dim@mariadb:3306/dim'
PDNS_DATABASE_URI_TEST = 'mysql://pdns:pdns@mariadb:3306/pdns_slave'
PDNS_DATABASE_URI_TEST = 'mysql://pdns1:pdns@mariadb:3306/pdns1'
SYNC_PDNS_OUTPUT = False
DEBUG = False
SQLALCHEMY_LOG = False
Expand All @@ -69,10 +69,10 @@ jobs:
run: make db-clear
working-directory: dim-testsuite
env:
PDNS1_SERVER: mariadb
PDNS1_PORT: 3306
PDNS2_SERVER: mariadb
PDNS2_PORT: 3306
PDNS1_DB_SERVER: mariadb
PDNS1_DB_PORT: 3306
PDNS2_DB_SERVER: mariadb
PDNS2_DB_PORT: 3306
- name: Run pytests
run: make pytest
working-directory: dim-testsuite
48 changes: 24 additions & 24 deletions dim-testsuite/Makefile
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
PYTHON ?= python3
VDIR ?= virtual_env
ODIR ?= out
VPIP ?= ${VDIR}/bin/pip3
VPYTHON ?= ${VDIR}/bin/python3
VPYTEST ?= ${VDIR}/bin/pytest
PYTESTS ?= .
LDIR ?= log
SRVLOG ?= ${LDIR}/server.log
NDCLI_USERNAME ?= admin
NDCLI_SERVER ?= http://localhost:5000
NDCLI_CONFIG ?= /dev/null
VFLASK ?= ${VDIR}/bin/flask
FLASK_APP ?= 'dim:create_app(db_mode="TEST")'
PDNS1_SERVER ?= 127.0.0.1
PDNS1_PORT ?= 3307
PDNS1_DB ?= pdns1
PDNS1_USER ?= pdns1
PDNS1_PW ?= pdns
PDNS2_SERVER ?= 127.0.0.1
PDNS2_PORT ?= 3307
PDNS2_DB ?= pdns2
PDNS2_USER ?= pdns2
PDNS2_PW ?= pdns
PYTHON ?= python3
VDIR ?= virtual_env
ODIR ?= out
VPIP ?= ${VDIR}/bin/pip3
VPYTHON ?= ${VDIR}/bin/python3
VPYTEST ?= ${VDIR}/bin/pytest
PYTESTS ?= .
LDIR ?= log
SRVLOG ?= ${LDIR}/server.log
NDCLI_USERNAME ?= admin
NDCLI_SERVER ?= http://localhost:5000
NDCLI_CONFIG ?= /dev/null
VFLASK ?= ${VDIR}/bin/flask
FLASK_APP ?= 'dim:create_app(db_mode="TEST")'
PDNS1_DB_SERVER ?= 127.0.0.1
PDNS1_DB_PORT ?= 3307
PDNS1_DB_NAME ?= pdns1
PDNS1_DB_USER ?= pdns1
PDNS1_DB_PW ?= pdns
PDNS2_DB_SERVER ?= 127.0.0.1
PDNS2_DB_PORT ?= 3307
PDNS2_DB_NAME ?= pdns2
PDNS2_DB_USER ?= pdns2
PDNS2_DB_PW ?= pdns

all: install db test
mkdir ${VDIR}
Expand Down
104 changes: 84 additions & 20 deletions dim-testsuite/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
dim-testsuite
=============
# dim-testsuite

This is the test suite to run tests over all the components of dim, including
ndcli, dimclient, dim itself, the output and some more.
Expand All @@ -10,26 +9,27 @@ As of now, make sure that your home *does not* contain a vaild `.ndclirc` and `.
If ndcli finds valid login information these might get use. In consequence the tests will be
run on the production DIM.

requirements
------------
## requirements

You need a running mysql instance listening on 127.0.0.1:3307 with the following databases:

```
```sql
create database dim;
create database pdns1;
create database pdns2;
```

and the following users:
```
grant all on pdns1.* to 'pdns'@'localhost' identified by 'pdns';
grant all on pdns2.* to 'pdns'@'localhost' identified by 'pdns';

```sql
grant all on pdns1.* to 'pdns1'@'localhost' identified by 'pdns';
grant all on pdns2.* to 'pdns2'@'localhost' identified by 'pdns';
grant all on dim.* to 'dim'@'localhost' identified by 'dim';
```

You also need to grant the user running the tests full rights on the databases:
```

```sql
create user 'janedoe'@'localhost';
grant all on pdns1.* to 'janedoe'@'localhost';
grant all on pdns2.* to 'janedoe'@'localhost';
Expand All @@ -41,8 +41,48 @@ If MariaDB does not startup please try to disable SELinux and try again.
The database files should be on a tmpfs to have a bit better performance for testing.

Then create the file `/etc/dim/dim.cfg` with a production like configuration.
It must contain the database credentials, so that the server can connect to the
database.
It must contain the database credentials, so that the server can connect to the database.

Example config:

```ini
### Database
SQLALCHEMY_DATABASE_URI = 'mysql://dim:dim@127.0.0.1:3307/dim'
DB_LOCK_TIMEOUT = 120

# Set SECRET_KEY to a random string
# The security of this application is compromised if SECRET_KEY is leaked
SECRET_KEY = 'testkey'
PERMANENT_SESSION_LIFETIME = 30 * 24 * 3600 # 1 month
TEMPORARY_SESSION_LIFETIME = 24 * 3600 # 1 day


### Logging
import logging, logging.handlers, sys
LOGGING_LEVEL = logging.DEBUG
LOGGING_HANDLER = logging.StreamHandler(sys.stderr)
#LOGGING_HANDLER = logging.handlers.SysLogHandler(address='/dev/log', facility='local0')


### DNS
DNS_DEFAULT_REFRESH = 14400 # 4 hours
DNS_DEFAULT_RETRY = 3600 # 1 hour
DNS_DEFAULT_EXPIRE = 605000 # 7 days
DNS_DEFAULT_MINIMUM = 86400 # 1 day (Min. TTL)
DNS_DEFAULT_ZONE_TTL = 86400 # 1 day (Default. TTL)

# list of ipspaces which are allowed to exist multiple times in dim (layer3domains)
# in general only rfc1918 ip should be allowed
LAYER3DOMAIN_WHITELIST = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '100.64.0.0/10']


### Debugging
SQLALCHEMY_DATABASE_URI_TEST = 'mysql://dim:dim@127.0.0.1:3307/dim'
PDNS_DATABASE_URI_TEST = 'mysql://pdns1:pdns@127.0.0.1:3307/pdns1'
SYNC_PDNS_OUTPUT = False
DEBUG = False
SQLALCHEMY_LOG = False
```

The following programs need to be installed:

Expand All @@ -53,39 +93,63 @@ The following programs need to be installed:
* openldap-devel
* gcc

how to run the test suite?
--------------------------
### ndcli test suite

To run the test suite, make sure the mysql database is up and running.
To run the ndcli test suite, make sure the mysql database is up and running.

Then call `make`.
It will proceed and build a virtual environment and install the tools needed
into it.
into it, and initialize the databases.

After that it will start the dim server and start making ndcli calls against
the server.

To control the location of the virtual environment, the output directory, or
the log directory, use the variables `VDIR`, `ODIR` and `LDIR`.

```
```shell
make VDIR=/tmp/venv ODIR=/tmp/test_output LDIR=/tmp/test_logs
```

If you want to skip the database initialization or installing of dependencies,
let *make* run the tests directly by using `make test`.

To run only specific testfiles, use the variable `TEST` for `make test` after
To run only specific testfiles, use the variable `TESTS` for `make test` after
you've created the virtual environment.

```
```shell
make test TESTS="<test1> <test2>"
```

`runtest.py` will look in the t directory for the specific testcases and run
`runtest.py` will look in the `t` directory for the specific testcases and run
only the ones specified in `TESTS`. After the case was run, your dim environment will have
exactly the state it broke in, so you can poke into it with ndcli, for example:

```
```shell
$VDIR/bin/ndcli list pools
```

### pytest test suite

To run the pytest test suite, make sure the mysql database is up and running.

Then call `make install`, or `make install-dev` (editable setup, changes to the code tree
will affect the virtual environment after creation).
It will proceed and build a virtual environment and install the tools needed
into it.

If you did not initialize the databases yet, run `make db` to do so.

To run the pytests, call `make pytest`.

To run only specific pytests, use the variable `PYTESTS` for `make pytest` after
you've created the virtual environment.

```shell
make pytest PYTESTS="<test1> <test2>"
```

This will run only the pytest(s) you specified.
For this, you'll need to pass the test *class names*, not the filenames:
e.g. `make pytest PYTESTS="AllocatorTest"` to run the tests for that class,
which is from the `tests/allocator_test.py` file.
42 changes: 33 additions & 9 deletions dim-testsuite/runtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,32 @@
T_DIR = os.path.join(topdir, 't')
OUT_DIR = os.getenv('TEST_OUTPUT_DIR', os.path.join(topdir, 'out'))
SRVLOG = os.getenv('SRVLOG', os.path.join(topdir, 'log/server.log'))
PDNS_ADDRESS = '127.1.1.1'
PDNS_DB_URI = 'mysql://pdns:pdns@127.0.0.1:3307/pdns1'
DIM_MYSQL_OPTIONS = '-h127.0.0.1 -P3307 -udim -pdim dim'

PDNS1_DB_SERVER = os.getenv('PDNS1_DB_SERVER', '127.0.0.1')
PDNS1_DB_PORT = os.getenv('PDNS1_DB_PORT', '3307')
PDNS1_DB_NAME = os.getenv('PDNS1_DB_NAME', 'pdns1')
PDNS1_DB_USER = os.getenv('PDNS1_DB_USER', 'pdns1')
PDNS1_DB_PW = os.getenv('PDNS1_DB_PW', 'pdns')
PDNS1_DB_URI = f'mysql://{PDNS1_DB_USER}:{PDNS1_DB_PW}@{PDNS1_DB_SERVER}:{PDNS1_DB_PORT}/{PDNS1_DB_NAME}'
PDNS1_ADDRESS = '127.1.1.1'

PDNS2_DB_SERVER = os.getenv('PDNS2_DB_SERVER', '127.0.0.1')
PDNS2_DB_PORT = os.getenv('PDNS2_DB_PORT', '3307')
PDNS2_DB_NAME = os.getenv('PDNS2_DB_NAME', 'pdns2')
PDNS2_DB_USER = os.getenv('PDNS2_DB_USER', 'pdns2')
PDNS2_DB_PW = os.getenv('PDNS2_DB_PW', 'pdns')
PDNS2_DB_URI = f'mysql://{PDNS2_DB_USER}:{PDNS2_DB_PW}@{PDNS2_DB_SERVER}:{PDNS2_DB_PORT}/{PDNS2_DB_NAME}'

DIM_DB_SERVER = os.getenv('DIM_DB_SERVER', '127.0.0.1')
DIM_DB_PORT = os.getenv('DIM_DB_PORT', '3307')
DIM_DB_NAME = os.getenv('DIM_DB_NAME', 'dim')
DIM_DB_USER = os.getenv('DIM_DB_USER', 'dim')
DIM_DB_PW = os.getenv('DIM_DB_PW', 'dim')


NDCLI_SERVER = os.getenv('NDCLI_SERVER', 'http://localhost:5000')

DIM_MYSQL_OPTIONS = f'-h{DIM_DB_SERVER} -P{DIM_DB_PORT} -u{DIM_DB_USER} -p{DIM_DB_PW} {DIM_DB_NAME}'
DIM_MYSQL_COMMAND = 'mysql ' + DIM_MYSQL_OPTIONS
VFLASK = os.getenv('VFLASK', 'flask')

Expand Down Expand Up @@ -94,15 +117,16 @@ def is_pdns_query(line: bytes):


def _ndcli(cmd: List[str], cmd_input=None):
proc = Popen(['ndcli' , '-s', 'http://localhost:5000/'] + cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
proc = Popen(['ndcli' , '-s', NDCLI_SERVER] + cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
out, err = proc.communicate(input=cmd_input if cmd_input != None else None)
return out


def clean_database():
commands = [
'echo "delete from domains; delete from records;" | mysql -h127.0.0.1 -P3307 -updns -ppdns pdns1',
'echo "delete from domains; delete from records;" | mysql -h127.0.0.1 -P3307 -updns -ppdns pdns2']
f'echo "delete from domains; delete from records;" | mysql -h{PDNS1_DB_SERVER} -P{PDNS1_DB_PORT} -u{PDNS1_DB_USER} -p{PDNS1_DB_PW} {PDNS1_DB_NAME}',
f'echo "delete from domains; delete from records;" | mysql -h{PDNS2_DB_SERVER} -P{PDNS2_DB_PORT} -u{PDNS2_DB_USER} -p{PDNS2_DB_PW} {PDNS2_DB_NAME}',
]
clean_sql = os.path.join(OUT_DIR, 'clean.sql')
if not hasattr(clean_database, 'dumped'):
commands.extend([
Expand Down Expand Up @@ -307,7 +331,7 @@ def check_pdns_output(line, out):
return True
zone_view_map = setup_pdns_output(server)
pdns_output_proc.wait_updates()
if not compare_dim_pdns_zones(server, PDNS_ADDRESS, zone_view_map):
if not compare_dim_pdns_zones(server, PDNS1_ADDRESS, zone_view_map):
out.write("Zone incorrectly exported\n")
return False
return True
Expand All @@ -333,7 +357,7 @@ def run_test(testfile, outfile, stop_on_error=False, auto_pdns_check=False):
if auto_pdns_check:
global server
server = DimClient(config['server'], cookie_file=os.path.expanduser('~/.ndcli.cookie'))
server.output_create('pdns_output', 'pdns-db', db_uri=PDNS_DB_URI)
server.output_create('pdns_output', 'pdns-db', db_uri=PDNS1_DB_URI)
server.zone_group_create('pdns_group')
server.output_add_group('pdns_output', 'pdns_group')

Expand Down Expand Up @@ -385,7 +409,7 @@ def run_test(testfile, outfile, stop_on_error=False, auto_pdns_check=False):

if __name__ == '__main__':
# start the server process
parsed = urlparse(os.getenv('NDCLI_SERVER', 'http://localhost:5000'))
parsed = urlparse(NDCLI_SERVER)
host = parsed.hostname
port = parsed.port

Expand Down
Loading