at 23.05-pre 3.9 kB view raw
1import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: 2let firefoxPackage' = firefoxPackage.override (args: { 3 extraPrefsFiles = (args.extraPrefsFiles or []) ++ [ 4 # make sure that autoplay is enabled by default for the audio test 5 (builtins.toString (builtins.toFile "autoplay-pref.js" ''defaultPref("media.autoplay.default",0);'')) 6 ]; 7 }); 8 9in 10{ 11 name = firefoxPackage'.unwrapped.pname; 12 meta = with pkgs.lib.maintainers; { 13 maintainers = [ eelco shlevy ]; 14 }; 15 16 nodes.machine = 17 { pkgs, ... }: 18 19 { imports = [ ./common/x11.nix ]; 20 environment.systemPackages = [ 21 firefoxPackage' 22 pkgs.xdotool 23 ]; 24 25 # Create a virtual sound device, with mixing 26 # and all, for recording audio. 27 boot.kernelModules = [ "snd-aloop" ]; 28 sound.enable = true; 29 sound.extraConfig = '' 30 pcm.!default { 31 type plug 32 slave.pcm pcm.dmixer 33 } 34 pcm.dmixer { 35 type dmix 36 ipc_key 1 37 slave { 38 pcm "hw:Loopback,0,0" 39 rate 48000 40 periods 128 41 period_time 0 42 period_size 1024 43 buffer_size 8192 44 } 45 } 46 pcm.recorder { 47 type hw 48 card "Loopback" 49 device 1 50 subdevice 0 51 } 52 ''; 53 54 systemd.services.audio-recorder = { 55 description = "Record NixOS test audio to /tmp/record.wav"; 56 script = "${pkgs.alsa-utils}/bin/arecord -D recorder -f S16_LE -r48000 /tmp/record.wav"; 57 }; 58 59 }; 60 61 testScript = '' 62 from contextlib import contextmanager 63 64 65 @contextmanager 66 def record_audio(machine: Machine): 67 """ 68 Perform actions while recording the 69 machine audio output. 70 """ 71 machine.systemctl("start audio-recorder") 72 yield 73 machine.systemctl("stop audio-recorder") 74 75 76 def wait_for_sound(machine: Machine): 77 """ 78 Wait until any sound has been emitted. 79 """ 80 machine.wait_for_file("/tmp/record.wav") 81 while True: 82 # Get at most 2M of the recording 83 machine.execute("tail -c 2M /tmp/record.wav > /tmp/last") 84 # Get the exact size 85 size = int(machine.succeed("stat -c '%s' /tmp/last").strip()) 86 # Compare it against /dev/zero using `cmp` (skipping 50B of WAVE header). 87 # If some non-NULL bytes are found it returns 1. 88 status, output = machine.execute( 89 f"cmp -i 50 -n {size - 50} /tmp/last /dev/zero 2>&1" 90 ) 91 if status == 1: 92 break 93 machine.sleep(2) 94 95 96 machine.wait_for_x() 97 98 with subtest("Wait until Firefox has finished loading the Valgrind docs page"): 99 machine.execute( 100 "xterm -e '${firefoxPackage'.unwrapped.binaryName} file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' >&2 &" 101 ) 102 machine.wait_for_window("Valgrind") 103 machine.sleep(40) 104 105 with subtest("Check whether Firefox can play sound"): 106 with record_audio(machine): 107 machine.succeed( 108 "${firefoxPackage'.unwrapped.binaryName} file://${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/phone-incoming-call.oga >&2 &" 109 ) 110 wait_for_sound(machine) 111 machine.copy_from_vm("/tmp/record.wav") 112 113 with subtest("Close sound test tab"): 114 machine.execute("xdotool key ctrl+w") 115 116 with subtest("Close default browser prompt"): 117 machine.execute("xdotool key space") 118 119 with subtest("Wait until Firefox draws the developer tool panel"): 120 machine.sleep(10) 121 machine.succeed("xwininfo -root -tree | grep Valgrind") 122 machine.screenshot("screen") 123 ''; 124 125})