From 2a00439306652564a38587b7506da3a1defa4a72 Mon Sep 17 00:00:00 2001 From: OPNA2608 Date: Thu, 29 May 2025 01:04:38 +0200 Subject: [PATCH] nixosTests.lomiri-camera-app: Fix OCR, round 3 By splitting one long test into multiple smaller ones, OfBorg should hopefully be happy with this now... --- nixos/tests/all-tests.nix | 2 +- nixos/tests/lomiri-camera-app.nix | 415 +++++++++++------- .../lomiri-camera-app/default.nix | 8 +- 3 files changed, 272 insertions(+), 153 deletions(-) diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index b03125926e88..c0b288ea56dc 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -764,7 +764,7 @@ in lomiri = discoverTests (import ./lomiri.nix); lomiri-calculator-app = runTest ./lomiri-calculator-app.nix; lomiri-calendar-app = runTest ./lomiri-calendar-app.nix; - lomiri-camera-app = runTest ./lomiri-camera-app.nix; + lomiri-camera-app = discoverTests (import ./lomiri-camera-app.nix); lomiri-clock-app = runTest ./lomiri-clock-app.nix; lomiri-docviewer-app = runTest ./lomiri-docviewer-app.nix; lomiri-filemanager-app = runTest ./lomiri-filemanager-app.nix; diff --git a/nixos/tests/lomiri-camera-app.nix b/nixos/tests/lomiri-camera-app.nix index 811c0b53c9ac..7a1a7929bccb 100644 --- a/nixos/tests/lomiri-camera-app.nix +++ b/nixos/tests/lomiri-camera-app.nix @@ -1,173 +1,286 @@ -{ lib, ... }: -{ - name = "lomiri-camera-app-standalone"; - meta.maintainers = lib.teams.lomiri.members; - - nodes.machine = - { config, pkgs, ... }: - { - imports = [ ./common/x11.nix ]; - - services.xserver.enable = true; - - environment = { - systemPackages = - with pkgs; - [ - feh # view photo result - ffmpeg # fake webcam stream - gnome-text-editor # somewhere to paste QR result - (imagemagick.override { ghostscriptSupport = true; }) # add label for OCR - qrtool # generate QR code - xdotool # clicking on QR button - ] - ++ (with pkgs.lomiri; [ - suru-icon-theme - lomiri-camera-app - ]); - variables = { - UITK_ICON_THEME = "suru"; - }; - }; - - i18n.supportedLocales = [ "all" ]; - - fonts = { - packages = with pkgs; [ - # Intended font & helps with OCR - ubuntu-classic +let + makeTest = import ./make-test-python.nix; + feedLabel = "Image"; + feedQrContent = "Test"; + feedImageFile = "feed.png"; + makeFeedImage = + pkgs: + pkgs.runCommand feedImageFile + { + nativeBuildInputs = with pkgs; [ + (imagemagick.override { ghostscriptSupport = true; }) # add label for OCR + qrtool # generate QR code ]; - }; + } + '' + qrtool encode '${feedQrContent}' -s 20 -m 10 > qr.png - # Fake camera - boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ]; - }; + # Horizontal flip, add text, flip back. Camera displays image mirrored, so need reversed text for OCR + magick qr.png \ + -flop \ + -pointsize 30 -fill black -annotate +100+100 '${feedLabel}' \ + -flop \ + $out + ''; +in +{ + basic = makeTest ( + { lib, ... }: + { + name = "lomiri-camera-app-basic"; + meta.maintainers = lib.teams.lomiri.members; - enableOCR = true; + nodes.machine = + { config, pkgs, ... }: + { + imports = [ ./common/x11.nix ]; - testScript = - let - qrLabel = "Feed"; - qrContent = "Test"; - in - '' - machine.wait_for_x() + services.xserver.enable = true; - with subtest("lomiri camera launches"): - machine.succeed("lomiri-camera-app >&2 &") - # emitted twice - machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") - machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") + environment = { + systemPackages = with pkgs.lomiri; [ + suru-icon-theme + lomiri-camera-app + ]; + variables = { + UITK_ICON_THEME = "suru"; + }; + }; + + i18n.supportedLocales = [ "all" ]; + + fonts = { + packages = with pkgs; [ + # Intended font & helps with OCR + ubuntu-classic + ]; + }; + }; + + enableOCR = true; + + testScript = + let + qrLabel = "Feed"; + qrContent = "Test"; + in + '' + machine.wait_for_x() + + with subtest("lomiri camera launches"): + machine.succeed("lomiri-camera-app >&2 &") + # emitted twice + machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") + machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("Cannot access") + machine.screenshot("lomiri-camera_open") + + machine.succeed("pgrep -afx lomiri-camera-app >&2") + machine.succeed("pkill -efx lomiri-camera-app >&2") + machine.wait_until_fails("pgrep -afx lomiri-camera-app >&2") + + # Sometimes, GStreamer errors out on camera init with: CameraBin error: "Failed to allocate required memory." + # Adding more VM memory didn't affect this. Maybe flaky in general? + # Current assumption: Camera access gets requested in a weird/still-in-use state, so sleep abit machine.sleep(10) - machine.send_key("alt-f10") - machine.sleep(5) - machine.wait_for_text("Cannot access") - machine.screenshot("lomiri-camera_open") - machine.succeed("pkill -f lomiri-camera-app") + with subtest("lomiri camera localisation works"): + machine.succeed("env LANG=de_DE.UTF-8 lomiri-camera-app >&2 &") + # emitted twice + machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") + machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("Zugriff auf") + machine.screenshot("lomiri-camera_localised") + ''; + } + ); - # Setup fake v4l2 camera - machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1") - machine.succeed("qrtool encode '${qrContent}' -s 20 -m 10 > qr.png") - # Horizontal flip, add text, flip back. Camera displays image mirrored, so need reversed text for OCR - machine.succeed("magick qr.png -flop -pointsize 30 -fill black -annotate +100+100 '${qrLabel}' -flop output.png") - machine.succeed("ffmpeg -re -loop 1 -i output.png -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &") + v4l2-photo = makeTest ( + { lib, ... }: + { + name = "lomiri-camera-app-v4l2-photo"; + meta.maintainers = lib.teams.lomiri.members; - with subtest("lomiri camera uses camera"): - machine.succeed("lomiri-camera-app >&2 &") - # emitted twice - machine.wait_for_console_text("No flash control support") - machine.wait_for_console_text("No flash control support") - machine.sleep(10) - machine.send_key("alt-f10") - machine.sleep(5) - machine.wait_for_text("${qrLabel}") - machine.screenshot("lomiri-camera_feed") + nodes.machine = + { config, pkgs, ... }: + { + imports = [ ./common/x11.nix ]; - machine.succeed("xdotool mousemove 510 670 click 1") # take photo - machine.wait_until_succeeds("ls /root/Pictures/camera.ubports | grep '\\.jpg$'") + services.xserver.enable = true; - # Check that the image is correct - machine.send_key("ctrl-alt-right") - machine.succeed("magick /root/Pictures/camera.ubports/IMG_00000001.jpg -flop photo_flip.png") - machine.succeed("feh photo_flip.png >&2 &") - machine.sleep(10) - machine.wait_for_text("${qrLabel}") - machine.screenshot("lomiri-camera_photo") + environment = { + etc."${feedImageFile}".source = makeFeedImage pkgs; + systemPackages = + with pkgs; + [ + feh # view photo result + ffmpeg # fake webcam stream + imagemagick # unflip webcam photo + xdotool # clicking on camera button + ] + ++ (with pkgs.lomiri; [ + suru-icon-theme + lomiri-camera-app + ]); + variables = { + UITK_ICON_THEME = "suru"; + }; + }; - machine.succeed("pkill -f feh") - machine.send_key("ctrl-alt-left") - machine.succeed("pkill -f lomiri-camera-app") + i18n.supportedLocales = [ "all" ]; - # Sometimes no camera feed, GStreamer errors out with: CameraBin error: "Failed to allocate required memory." - # Adding more VM memory didn't affect this. Maybe flaky in general? - # Current assumption: Camera access gets requested in a weird/still-in-use state, so sleep abit - machine.sleep(10) + fonts = { + packages = with pkgs; [ + # Intended font & helps with OCR + ubuntu-classic + ]; + }; - with subtest("lomiri barcode scanner uses camera"): - machine.succeed("lomiri-camera-app --mode=barcode-reader >&2 &") - # emitted twice - machine.wait_for_console_text("No flash control support") - machine.wait_for_console_text("No flash control support") - machine.sleep(10) - machine.send_key("alt-f10") - machine.sleep(5) - machine.wait_for_text("${qrLabel}") - machine.succeed("xdotool mousemove 510 670 click 1") # open up QR decode result + # Fake camera + boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ]; + }; - # OCR is struggling to recognise the text. Click the clipboard button and paste the result somewhere else - machine.sleep(5) - machine.screenshot("lomiri-barcode_decode") - machine.succeed("xdotool mousemove 540 590 click 1") - machine.sleep(5) + enableOCR = true; - # Need to make a new window without closing camera app, otherwise clipboard content gets lost? - machine.send_key("ctrl-alt-right") - machine.succeed("gnome-text-editor >&2 &") - machine.sleep(10) - machine.send_key("alt-f10") - machine.sleep(5) - machine.wait_for_text("New") + testScript = '' + machine.wait_for_x() - # Font size up to help with OCR - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") - machine.send_key("ctrl-kp_add") + # Setup fake v4l2 camera + machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1") + machine.succeed("ffmpeg -re -loop 1 -i /etc/${feedImageFile} -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &") - machine.send_key("ctrl-v") - machine.wait_for_text("${qrContent}") + with subtest("lomiri camera uses camera"): + machine.succeed("lomiri-camera-app >&2 &") + # emitted twice + machine.wait_for_console_text("No flash control support") + machine.wait_for_console_text("No flash control support") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("${feedLabel}") + machine.screenshot("lomiri-camera_feed") - machine.succeed("pkill -f gnome-text-editor") - machine.send_key("ctrl-alt-left") - machine.succeed("pkill -f lomiri-camera-app") + machine.succeed("xdotool mousemove 510 670 click 1") # take photo + machine.wait_until_succeeds("ls /root/Pictures/camera.ubports | grep '\\.jpg$'") - # Sometimes no camera feed, GStreamer errors out with: CameraBin error: "Failed to allocate required memory." - # Adding more VM memory didn't affect this. Maybe flaky in general? - # Current assumption: Camera access gets requested in a weird/still-in-use state, so sleep abit - machine.sleep(10) + # Check that the image is correct + machine.send_key("ctrl-alt-right") + machine.succeed("magick /root/Pictures/camera.ubports/IMG_00000001.jpg -flop photo_flip.png") + machine.succeed("feh photo_flip.png >&2 &") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("${feedLabel}") + machine.screenshot("lomiri-camera_photo") + ''; + } + ); - with subtest("lomiri camera localisation works"): - machine.succeed("env LANG=de_DE.UTF-8 lomiri-camera-app >&2 &") - # emitted twice - machine.wait_for_console_text("No flash control support") - machine.wait_for_console_text("No flash control support") - machine.sleep(10) - machine.send_key("alt-f10") - machine.sleep(5) - machine.wait_for_text("Kamera") - machine.screenshot("lomiri-camera_localised") - ''; + v4l2-qr = makeTest ( + { lib, ... }: + { + name = "lomiri-camera-app-v4l2-qr"; + meta.maintainers = lib.teams.lomiri.members; + + nodes.machine = + { config, pkgs, ... }: + { + imports = [ ./common/x11.nix ]; + + services.xserver.enable = true; + + environment = { + etc."${feedImageFile}".source = makeFeedImage pkgs; + systemPackages = + with pkgs; + [ + ffmpeg # fake webcam stream + gnome-text-editor # somewhere to paste QR result + xdotool # clicking on QR button + ] + ++ (with pkgs.lomiri; [ + suru-icon-theme + lomiri-camera-app + ]); + variables = { + UITK_ICON_THEME = "suru"; + }; + }; + + i18n.supportedLocales = [ "all" ]; + + fonts = { + packages = with pkgs; [ + # Intended font & helps with OCR + ubuntu-classic + ]; + }; + + # Fake camera + boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ]; + }; + + enableOCR = true; + + testScript = '' + machine.wait_for_x() + + # Setup fake v4l2 camera + machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1") + machine.succeed("ffmpeg -re -loop 1 -i /etc/${feedImageFile} -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &") + + with subtest("lomiri barcode scanner uses camera"): + machine.succeed("lomiri-camera-app --mode=barcode-reader >&2 &") + # emitted twice + machine.wait_for_console_text("No flash control support") + machine.wait_for_console_text("No flash control support") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("${feedLabel}") + machine.succeed("xdotool mousemove 510 670 click 1") # open up QR decode result + + # OCR is struggling to recognise the text. Click the clipboard button and paste the result somewhere else + machine.sleep(5) + machine.screenshot("lomiri-barcode_decode") + machine.succeed("xdotool mousemove 540 590 click 1") + machine.sleep(5) + + # Need to make a new window without closing camera app, otherwise clipboard content gets lost? + machine.send_key("ctrl-alt-right") + machine.succeed("gnome-text-editor >&2 &") + machine.sleep(10) + machine.send_key("alt-f10") + machine.sleep(5) + machine.wait_for_text("New") + + # Font size up to help with OCR + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + machine.send_key("ctrl-kp_add") + + machine.send_key("ctrl-v") + machine.wait_for_text("${feedQrContent}") + ''; + } + ); } diff --git a/pkgs/desktops/lomiri/applications/lomiri-camera-app/default.nix b/pkgs/desktops/lomiri/applications/lomiri-camera-app/default.nix index 6497a0571c2f..8238f1fcbdeb 100644 --- a/pkgs/desktops/lomiri/applications/lomiri-camera-app/default.nix +++ b/pkgs/desktops/lomiri/applications/lomiri-camera-app/default.nix @@ -132,7 +132,13 @@ stdenv.mkDerivation (finalAttrs: { ''; passthru = { - tests.vm = nixosTests.lomiri-camera-app; + tests = { + inherit (nixosTests.lomiri-camera-app) + basic + v4l2-photo + v4l2-qr + ; + }; updateScript = gitUpdater { rev-prefix = "v"; }; };