Skip to content

Commit

Permalink
Merge pull request #2875 from lunkwill42/bugfix/test-scripts
Browse files Browse the repository at this point in the history
Fix broken `navclean` and `navsynctypes`  scripts
  • Loading branch information
lunkwill42 authored Mar 15, 2024
2 parents efb9fac + 005d1aa commit 142309b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 33 deletions.
6 changes: 3 additions & 3 deletions python/nav/bin/navclean.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import nav.db


def main(args):
def main():
"""Main execution function."""
parser = make_argparser()
args = parser.parse_args()
Expand Down Expand Up @@ -210,7 +210,7 @@ class RadiusAcctDeleter(RecordDeleter):
selector = """
WHERE (acctstoptime < {expiry})
OR ((acctstarttime + (acctsessiontime * interval '1 sec')) < {expiry})
OR (acctstarttime < {expiry}
OR (acctstarttime < {expiry}
AND (acctstarttime + (acctsessiontime * interval '1 sec')) IS NULL)
"""

Expand Down Expand Up @@ -245,4 +245,4 @@ def delete(self, expiry, dry_run=False):


if __name__ == '__main__':
main(sys.argv[1:])
main()
11 changes: 6 additions & 5 deletions python/nav/bin/navsynctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@


VENDOR_INSERT_SQL_TEMPLATE = """
INSERT INTO vendor
INSERT INTO vendor
(SELECT {vendorid} AS vendorid
WHERE NOT EXISTS (
SELECT vendorid FROM vendor WHERE vendorid ILIKE {vendorid}
)
);
);
"""

TYPE_UPSERT_SQL_TEMPLATE = """
Expand All @@ -43,7 +43,7 @@
{typename},
{sysobjectid},
{descr}
) ON CONFLICT (sysobjectid) DO UPDATE
) ON CONFLICT (sysobjectid) DO UPDATE
SET
vendorid=(SELECT vendorid FROM vendor WHERE vendorid ILIKE {vendorid}),
typename={typename},
Expand All @@ -52,8 +52,9 @@
"""


def main(_args):
def main():
"""Main program"""
parse_args()
types = NetboxType.objects.all().select_related("vendor")
used_vendors = {t.vendor.id for t in types}
if types:
Expand Down Expand Up @@ -109,4 +110,4 @@ def parse_args():


if __name__ == "__main__":
main(parse_args())
main()
6 changes: 3 additions & 3 deletions tests/integration/bin_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
BINDIR = './python/nav/bin'


def test_binary_runs(binary):
"""Verifies that a command runs with a zero exit code"""
proc = subprocess.Popen(binary, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
def test_script_runs(script):
"""Verifies that a script defined in pyproject.toml runs with a zero exit code"""
proc = subprocess.Popen(script, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
(done, fail) = proc.communicate()
retcode = proc.wait()

Expand Down
53 changes: 31 additions & 22 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from __future__ import print_function
import os
import importlib.util
import io
import re
import shlex
from itertools import cycle
from shutil import which
import subprocess
import time
from typing import Dict

import toml
import pytest
from django.test import Client

Expand Down Expand Up @@ -90,38 +93,44 @@ def stop_gunicorn():


def pytest_generate_tests(metafunc):
if 'binary' in metafunc.fixturenames:
binaries = _nav_binary_tests()
ids = [b[0] for b in binaries]
metafunc.parametrize("binary", _nav_binary_tests(), ids=ids)
if 'script' in metafunc.fixturenames:
scripts = _nav_script_tests()
ids = [s[0] for s in scripts]
metafunc.parametrize("script", _nav_script_tests(), ids=ids)
elif 'admin_navlet' in metafunc.fixturenames:
from nav.models.profiles import AccountNavlet

navlets = AccountNavlet.objects.filter(account__login='admin')
metafunc.parametrize("admin_navlet", navlets)


def _nav_binary_tests():
for binary in _nav_binary_list():
for args in _scan_testargs(binary):
if args:
yield args

def _nav_script_tests():
"""Generates a list of command lines to run to test all the NAV scripts defined
in pyproject.toml.
def _nav_binary_list():
files = sorted(
os.path.join(BINDIR, f) for f in os.listdir(BINDIR) if not _is_excluded(f)
)
return (f for f in files if os.path.isfile(f))
Each NAV script can define 0 to many sets of test arguments that should be used
when executing the script, using comments at the top of the file. This is because
some of the scripts are designed to require some arguments to be present in order
to run without exiting with an error.
"""
for script, module_name in _nav_scripts_map().items():
spec = importlib.util.find_spec(module_name)
for args in _scan_testargs(spec.origin):
if args:
yield [script] + args[1:]


def _is_excluded(filename):
return (
filename.endswith('~')
or filename.startswith('.')
or filename.startswith('__')
or filename.startswith('Makefile')
)
def _nav_scripts_map() -> Dict[str, str]:
"""Returns a map of installable script names to NAV module names from
pyproject.toml.
"""
data = toml.load('pyproject.toml')
scripts: dict[str, str] = data.get('project', {}).get('scripts', {})
return {
script: module.split(':', maxsplit=1)[0]
for script, module in scripts.items()
if module.startswith('nav.')
}


def _scan_testargs(filename):
Expand Down
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pytest-timeout
pytest-twisted~=1.13.0
pytidylib==0.3.2
selenium==3.141.0
toml
whisper>=0.9.9
whitenoise==4.1.4
# Our version of selenium breaks down if it is allowed to pull in the newest version of urllib3
Expand Down

0 comments on commit 142309b

Please sign in to comment.