From f4dcd7d565d3baaafacf083c0fc5572c4361f274 Mon Sep 17 00:00:00 2001 From: Daniele Forsi IU5HKX Date: Wed, 30 Apr 2025 23:19:40 +0200 Subject: [PATCH] Add a pytest test copying all the contents of the old py3test.py Python tests are enabled by default when building the Python bindings if pytest is available at configuration time: ./configure --with-python-binding or ./configure --with-python-binding --enable-pytest=check To fail the configure step if the tests can't be enabled: ./configure --with-python-binding --enable-pytest or ./configure --with-python-binding --enable-pytest=yes To disable the tests: ./configure --with-python-binding --enable-pytest=no To run the tests: make -C bindings/ check --- bindings/Makefile.am | 10 ++- bindings/python/test_startup.py | 127 ++++++++++++++++++++++++++++++++ configure.ac | 28 +++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100755 bindings/python/test_startup.py diff --git a/bindings/Makefile.am b/bindings/Makefile.am index 6224997ae..cc9e35f3b 100644 --- a/bindings/Makefile.am +++ b/bindings/Makefile.am @@ -22,6 +22,7 @@ SWGDEP = \ EXTRA_DIST = $(SWGFILES) \ Makefile.PL perltest.pl tcltest.tcl.in \ + python/test_startup.py \ luatest.lua README.python exampledir = $(docdir)/examples @@ -105,7 +106,14 @@ _Hamlib_la_LTLIBRARIES = $(pyexec_ltlib) all-py: $(pyexec_ltlib) -check-py: all-py +check-py: all-py pytest-${enable_pytest} + +pytest-yes: + $(AM_V_at)PYTHONPATH=$(builddir):$(builddir)/.libs \ + $(PYTEST) --capture=no $(srcdir)/ + +pytest-no: + @echo "Skipping pytest run" Hamlib.py: hamlibpy_wrap.c diff --git a/bindings/python/test_startup.py b/bindings/python/test_startup.py new file mode 100755 index 000000000..6c6ca1549 --- /dev/null +++ b/bindings/python/test_startup.py @@ -0,0 +1,127 @@ +#! /bin/env pytest +"""Tests of the Python bindings for Hamlib + +Running this script directly will use the installed bindings. +For an in-tree run use "make check", or set PYTHONPATH to point to +the directories containing Hamlib.py and _Hamlib.so. +""" +import sys + +import Hamlib + +class TestClass: + """Container class for tests""" + + def test_startup(self): + """Simple script to test the Hamlib.py module with Python3.""" + + print("%s: Python %s; %s\n" \ + % (sys.argv[0], sys.version.split()[0], Hamlib.cvar.hamlib_version)) + + Hamlib.rig_set_debug(Hamlib.RIG_DEBUG_NONE) + + # Init RIG_MODEL_DUMMY + my_rig = Hamlib.Rig(Hamlib.RIG_MODEL_DUMMY) + my_rig.set_conf("rig_pathname", "/dev/Rig") + my_rig.set_conf("retry", "5") + + my_rig.open () + + rpath = my_rig.get_conf("rig_pathname") + retry = my_rig.get_conf("retry") + + print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status)) + print("get_conf:\t\tpath = %s, retry = %s" \ + % (rpath, retry)) + + my_rig.set_freq(Hamlib.RIG_VFO_B, 5700000000) + my_rig.set_vfo(Hamlib.RIG_VFO_B) + + print("freq:\t\t\t%s" % my_rig.get_freq()) + + my_rig.set_freq(Hamlib.RIG_VFO_A, 145550000) + (mode, width) = my_rig.get_mode(Hamlib.RIG_VFO_A) + + print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width)) + + my_rig.set_mode(Hamlib.RIG_MODE_CW) + (mode, width) = my_rig.get_mode() + + print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width)) + + print("Backend copyright:\t%s" % my_rig.caps.copyright) + print("Model:\t\t\t%s" % my_rig.caps.model_name) + print("Manufacturer:\t\t%s" % my_rig.caps.mfg_name) + print("Backend version:\t%s" % my_rig.caps.version) + print("Backend status:\t\t%s" % Hamlib.rig_strstatus(my_rig.caps.status)) + print("Rig info:\t\t%s" % my_rig.get_info()) + + my_rig.set_level("VOXDELAY", 1) + + print("VOX delay:\t\t%s" % my_rig.get_level_i("VOXDELAY")) + + my_rig.set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5) + + print("VOX delay:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_VOXDELAY)) + + af = 12.34 + + print("Setting AF to %0.2f...." % (af)) + + my_rig.set_level("AF", af) + + print("status:\t\t\t%s - %s" % (my_rig.error_status, + Hamlib.rigerror(my_rig.error_status))) + + print("AF level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_AF)) + print("Power level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_RFPOWER_METER)) + print("Power level Watts:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_RFPOWER_METER_WATTS)) + print("strength:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH)) + print("status:\t\t\t%s" % my_rig.error_status) + print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status)) + + chan = Hamlib.channel(Hamlib.RIG_VFO_B) + my_rig.get_channel(chan,1) + + print("get_channel status:\t%s" % my_rig.error_status) + print("VFO:\t\t\t%s, %s" % (Hamlib.rig_strvfo(chan.vfo), chan.freq)) + print("Attenuators:\t\t%s" % my_rig.caps.attenuator) + # Can't seem to get get_vfo_info to work + #(freq, width, mode, split) = my_rig.get_vfo_info(Hamlib.RIG_VFO_A,freq,width,mode,split) + #print("Rig vfo_info:\t\tfreq=%s, mode=%s, width=%s, split=%s" % (freq, mode, width, split)) + print("\nSending Morse, '73'") + + my_rig.send_morse(Hamlib.RIG_VFO_A, "73") + my_rig.close() + + print("\nSome static functions:") + + err, lon1, lat1 = Hamlib.locator2longlat("IN98XC") + err, lon2, lat2 = Hamlib.locator2longlat("DM33DX") + err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3) + err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3) + + print("Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s" % (lon1, lat1, loc1)) + print("Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s" % (lon2, lat2, loc2)) + + err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2) + longpath = Hamlib.distance_long_path(dist) + + print("Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km" \ + % (dist, az, longpath)) + + # dec2dms expects values from 180 to -180 + # sw is 1 when deg is negative (west or south) as 0 cannot be signed + err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1) + err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1) + + lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1) + lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2) + + print('Longitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ + % (lon1, deg1, mins1, sec1, ('W' if sw1 else 'E'), lon3)) + + print('Latitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ + % (lat1, deg2, mins2, sec2, ('S' if sw2 else 'N'), lat3)) + + my_rig.set_vfo_opt(0); diff --git a/configure.ac b/configure.ac index 3aecb6e51..0c3ec35b8 100644 --- a/configure.ac +++ b/configure.ac @@ -615,6 +615,33 @@ AS_IF([test x"${cf_with_python_binding}" = "xyes"],[ AM_CONDITIONAL([ENABLE_PYTHON], [test x"${cf_with_python_binding}" = "xyes"]) +AC_ARG_ENABLE([pytest], + [AS_HELP_STRING([--enable-pytest], + [execute Python tests @<:@default=check@:>@]) + ], + [enable_pytest=check] +) + +AS_IF([test "x$enable_pytest" != "xno"], + [AC_PATH_PROG([PYTEST], [pytest])] +) + +AS_IF([test "x$PYTEST" = "x"], + [have_pytest=no], + [have_pytest=yes] +) + +AS_IF([test "x$enable_pytest" = "xyes"], + [AS_IF([test "x$have_pytest" = "xno"], + [AC_MSG_ERROR([pytest requested but not found])] + )] +) + +# "check" is replaced by the rsult ("yes" or "no") +enable_pytest=$have_pytest + +AC_SUBST([enable_pytest]) + # Tcl binding AC_MSG_CHECKING([Whether to build Tcl bindings]) AC_ARG_WITH([tcl-binding], @@ -976,5 +1003,6 @@ echo \ Enable USB backends ${cf_with_libusb} Enable shared libs ${enable_shared} Enable static libs ${enable_static} + Enable Python tests ${enable_pytest} -----------------------------------------------------------------------"