Merge pull request #278131 from symphorien/sane_test
nixos/sane: add nixos test
This commit is contained in:
commit
996d064488
@ -763,6 +763,7 @@ in {
|
|||||||
sabnzbd = handleTest ./sabnzbd.nix {};
|
sabnzbd = handleTest ./sabnzbd.nix {};
|
||||||
samba = handleTest ./samba.nix {};
|
samba = handleTest ./samba.nix {};
|
||||||
samba-wsdd = handleTest ./samba-wsdd.nix {};
|
samba-wsdd = handleTest ./samba-wsdd.nix {};
|
||||||
|
sane = handleTest ./sane.nix {};
|
||||||
sanoid = handleTest ./sanoid.nix {};
|
sanoid = handleTest ./sanoid.nix {};
|
||||||
scaphandre = handleTest ./scaphandre.nix {};
|
scaphandre = handleTest ./scaphandre.nix {};
|
||||||
schleuder = handleTest ./schleuder.nix {};
|
schleuder = handleTest ./schleuder.nix {};
|
||||||
|
85
nixos/tests/sane.nix
Normal file
85
nixos/tests/sane.nix
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import ./make-test-python.nix ({ pkgs, ... }:
|
||||||
|
/*
|
||||||
|
SANE NixOS test
|
||||||
|
===============
|
||||||
|
SANE is intrisically tied to hardware, so testing it is not straightforward.
|
||||||
|
However:
|
||||||
|
- a fake webcam can be created with v4l2loopback
|
||||||
|
- sane has a backend (v4l) to use a webcam as a scanner
|
||||||
|
This test creates a webcam /dev/video0, streams a still image with some text
|
||||||
|
through this webcam, uses SANE to scan from the webcam, and uses OCR to check
|
||||||
|
that the expected text was scanned.
|
||||||
|
*/
|
||||||
|
let
|
||||||
|
text = "66263666188646651519653683416";
|
||||||
|
fontsConf = pkgs.makeFontsConf {
|
||||||
|
fontDirectories = [
|
||||||
|
pkgs.dejavu_fonts.minimal
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# an image with black on white text spelling "${text}"
|
||||||
|
# for some reason, the test fails if it's jpg instead of png
|
||||||
|
# the font is quite large to make OCR easier
|
||||||
|
image = pkgs.runCommand "image.png"
|
||||||
|
{
|
||||||
|
# only imagemagickBig can render text
|
||||||
|
nativeBuildInputs = [ pkgs.imagemagickBig ];
|
||||||
|
FONTCONFIG_FILE = fontsConf;
|
||||||
|
} ''
|
||||||
|
magick -pointsize 100 label:${text} $out
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
name = "sane";
|
||||||
|
nodes.machine = { pkgs, config, ... }: {
|
||||||
|
boot = {
|
||||||
|
# create /dev/video0 as a fake webcam whose content is filled by ffmpeg
|
||||||
|
extraModprobeConfig = ''
|
||||||
|
options v4l2loopback devices=1 max_buffers=2 exclusive_caps=1 card_label=VirtualCam
|
||||||
|
'';
|
||||||
|
kernelModules = [ "v4l2loopback" ];
|
||||||
|
extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ];
|
||||||
|
};
|
||||||
|
systemd.services.fake-webcam = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
description = "fill /dev/video0 with ${image}";
|
||||||
|
/* HACK: /dev/video0 is a v4l2 only device, it misses one single v4l1
|
||||||
|
ioctl, VIDIOCSPICT. But sane only supports v4l1, so it will log that this
|
||||||
|
ioctl failed, and assume that the pixel format is Y8 (gray). So we tell
|
||||||
|
ffmpeg to produce this pixel format.
|
||||||
|
*/
|
||||||
|
serviceConfig.ExecStart = [ "${pkgs.ffmpeg}/bin/ffmpeg -framerate 30 -re -stream_loop -1 -i ${image} -f v4l2 -pix_fmt gray /dev/video0" ];
|
||||||
|
};
|
||||||
|
hardware.sane.enable = true;
|
||||||
|
system.extraDependencies = [ image ];
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.fswebcam
|
||||||
|
pkgs.tesseract
|
||||||
|
pkgs.v4l-utils
|
||||||
|
];
|
||||||
|
environment.variables.SANE_DEBUG_V4L = "128";
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
machine.wait_for_unit("fake-webcam.service")
|
||||||
|
|
||||||
|
# the device only appears when ffmpeg starts producing frames
|
||||||
|
machine.wait_until_succeeds("scanimage -L | grep /dev/video0")
|
||||||
|
|
||||||
|
machine.succeed("scanimage -L >&2")
|
||||||
|
|
||||||
|
with subtest("debugging: /dev/video0 works"):
|
||||||
|
machine.succeed("v4l2-ctl --all >&2")
|
||||||
|
machine.succeed("fswebcam --no-banner /tmp/webcam.jpg")
|
||||||
|
machine.copy_from_vm("/tmp/webcam.jpg", "webcam")
|
||||||
|
|
||||||
|
# scan with the webcam
|
||||||
|
machine.succeed("scanimage -o /tmp/scan.png >&2")
|
||||||
|
machine.copy_from_vm("/tmp/scan.png", "scan")
|
||||||
|
|
||||||
|
# the image should contain "${text}"
|
||||||
|
output = machine.succeed("tesseract /tmp/scan.png -")
|
||||||
|
print(output)
|
||||||
|
assert "${text}" in output, f"expected text ${text} was not found, OCR found {output!r}"
|
||||||
|
'';
|
||||||
|
})
|
@ -3,6 +3,7 @@
|
|||||||
, avahi, libgphoto2, libieee1284, libjpeg, libpng, libtiff, libusb1, libv4l, net-snmp
|
, avahi, libgphoto2, libieee1284, libjpeg, libpng, libtiff, libusb1, libv4l, net-snmp
|
||||||
, curl, systemd, libxml2, poppler, gawk
|
, curl, systemd, libxml2, poppler, gawk
|
||||||
, sane-drivers
|
, sane-drivers
|
||||||
|
, nixosTests
|
||||||
|
|
||||||
# List of { src name backend } attibute sets - see installFirmware below:
|
# List of { src name backend } attibute sets - see installFirmware below:
|
||||||
, extraFirmware ? []
|
, extraFirmware ? []
|
||||||
@ -132,6 +133,10 @@ stdenv.mkDerivation {
|
|||||||
# https://github.com/NixOS/nixpkgs/issues/224569
|
# https://github.com/NixOS/nixpkgs/issues/224569
|
||||||
enableParallelInstalling = false;
|
enableParallelInstalling = false;
|
||||||
|
|
||||||
|
passthru.tests = {
|
||||||
|
inherit (nixosTests) sane;
|
||||||
|
};
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
description = "SANE (Scanner Access Now Easy) backends";
|
description = "SANE (Scanner Access Now Easy) backends";
|
||||||
longDescription = ''
|
longDescription = ''
|
||||||
|
Loading…
Reference in New Issue
Block a user