Skip to content

Commit

Permalink
Add test script that tries to import all drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
fk3 committed Oct 19, 2023
1 parent 24a913f commit c34ced4
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/Test-Importability.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$ErrorActionPreference = "Stop"

[Ref]$Imports = 0
[Ref]$SuccessfulImports = 0

function Import-Driver {
Param(
[Parameter(Mandatory)]
[string]$DriverName
)
$Imports.Value++
python ./tests/importability/import_driver.py $DriverName
if ($?) {
$SuccessfulImports.Value++
}
}

Get-ChildItem -Path src -Attributes Directory | % { Import-Driver -DriverName $_.name }

if ($SuccessfulImports.Value -ne $Imports.Value)
{
Throw "Only $($SuccessfulImports.Value) out of $($Imports.Value) imports were successful."
}

if ($SuccessfulImports.Value -eq 0)
{
Throw "Could not import any drivers."
}
98 changes: 98 additions & 0 deletions tests/importability/import_driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""Test if an instrument driver can be imported.
Usage:
From the root of the repository, call
`python ./tests/importability/import_driver.py <driver-name>`
"""

import json
import logging
import sys
import traceback
from configparser import ConfigParser
from pathlib import Path

import pysweepme

logging.basicConfig(level=logging.DEBUG, format="%(levelname)s: %(message)s")


def is_compatible(driver_name: str) -> bool:
"""Check if the driver compatibility information matches the currently running python version.
Args:
driver_name: Name (folder) of the driver to import.
"""
limit_for_32_bit = 0x100000000
version = sys.version_info
python_version = f"{version.major}.{version.minor}"
bitness = "64" if sys.maxsize > limit_for_32_bit else "32"
compatibility_flags = {
"any",
f"any-{bitness}",
f"{python_version}-any",
f"{python_version}-{bitness}",
}
config = ConfigParser()
config.read(Path("src") / driver_name / "info.ini")
# get the architecture from the run section, and if it does not exist from the info section. This is
# the same order the server checks in uploaded drivers.
# If no architecture is found at all, use the default "any" (as a quoted string)
architecture_str = json.loads(
config.get("run", "architecture", fallback=config.get("info", "architecture", fallback='"any"')),
)
architecture = {a.strip() for a in architecture_str.split(",")}
# compatibility is given if the two sets have non-empty intersection
if architecture & compatibility_flags:
return True
return False


def import_driver(driver_name: str) -> None:
"""Let pysweepme import a driver from the src directory.
Args:
driver_name: Name (folder) of the driver to import.
"""
# some devices already get an initialized (not opened) port from the PortManager and require a port string.
# There is no universal port string that works for all devices, so we try a couple until we got something
# that works.
# We are using "" (no port), "USB" (gets initialized without any side-effects), and "0" (for Indexes, e.g. Webcam)
port_strings = ["", "USB", "0"]
exceptions = []
for port_string in port_strings:
try:
driver_instance = pysweepme.get_driver(
driver_name,
folder="src",
port_string=port_string,
)
break
except Exception:
exceptions.append((port_string, sys.exc_info()))
else:
for port_string, exc in exceptions:
msg = f'Failed to import {driver_name} with port string "{port_string}".'
logging.error(msg)
traceback.print_exception(*exc)
msg = f"Driver {driver_name} could not be imported with any of the tested port_strings."
raise Exception(msg)

assert driver_name == driver_instance._latest_parameters["Device"]

logging.debug(f"Imported {driver_name}.")


try:
driver_name = sys.argv[1]
except IndexError as e:
msg = "This script must be called with the driver name as first argument."
raise IndexError(msg) from e

if is_compatible(driver_name):
import_driver(driver_name)
else:
logging.debug(
f"Skipped importing {driver_name} because it is not meant to be compatible with this python version.",
)
17 changes: 17 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[tox]
no_package = true
env_list = py39-32, py39-64
skip_missing_interpreters = false

[testenv]
description = check if drivers can be imported
basepython =
py39-32: python3.9-32
py39-64: python3.9-64
allowlist_externals = pwsh
deps =
py39-{32,64}: -r requirements.txt
passenv =
LOCALAPPDATA #required for win32 certifi
commands =
pwsh -NoProfile -Command .\.github\Test-Importability.ps1

0 comments on commit c34ced4

Please sign in to comment.