| 
									
										
										
										
											2020-02-10 18:01:47 +01:00
										 |  |  | import ./make-test-python.nix ({ pkgs, esr ? false, ... }: { | 
					
						
							| 
									
										
										
										
											2014-06-28 16:04:49 +02:00
										 |  |  |   name = "firefox"; | 
					
						
							| 
									
										
										
										
											2021-01-10 20:08:30 +01:00
										 |  |  |   meta = with pkgs.lib.maintainers; { | 
					
						
							| 
									
										
										
										
											2019-02-22 16:14:13 +01:00
										 |  |  |     maintainers = [ eelco shlevy ]; | 
					
						
							| 
									
										
										
										
											2015-07-12 12:09:40 +02:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2010-01-05 14:12:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |   machine = | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |     { pkgs, ... }: | 
					
						
							| 
									
										
										
										
											2010-01-05 14:12:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 13:05:09 +02:00
										 |  |  |     { imports = [ ./common/x11.nix ]; | 
					
						
							| 
									
										
										
										
											2020-02-10 18:01:47 +01:00
										 |  |  |       environment.systemPackages = | 
					
						
							|  |  |  |         (if esr then [ pkgs.firefox-esr ] else [ pkgs.firefox ]) | 
					
						
							|  |  |  |         ++ [ pkgs.xdotool ]; | 
					
						
							| 
									
										
										
										
											2020-10-31 18:24:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Need some more memory to record audio. | 
					
						
							|  |  |  |       virtualisation.memorySize = "500"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Create a virtual sound device, with mixing | 
					
						
							|  |  |  |       # and all, for recording audio. | 
					
						
							|  |  |  |       boot.kernelModules = [ "snd-aloop" ]; | 
					
						
							|  |  |  |       sound.enable = true; | 
					
						
							|  |  |  |       sound.extraConfig = ''
 | 
					
						
							|  |  |  |         pcm.!default { | 
					
						
							|  |  |  |           type plug | 
					
						
							|  |  |  |           slave.pcm pcm.dmixer | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         pcm.dmixer { | 
					
						
							|  |  |  |           type dmix | 
					
						
							|  |  |  |           ipc_key 1 | 
					
						
							|  |  |  |           slave { | 
					
						
							|  |  |  |             pcm "hw:Loopback,0,0" | 
					
						
							|  |  |  |             rate 48000 | 
					
						
							|  |  |  |             periods 128 | 
					
						
							|  |  |  |             period_time 0 | 
					
						
							|  |  |  |             period_size 1024 | 
					
						
							|  |  |  |             buffer_size 8192 | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         pcm.recorder { | 
					
						
							|  |  |  |           type hw | 
					
						
							|  |  |  |           card "Loopback" | 
					
						
							|  |  |  |           device 1 | 
					
						
							|  |  |  |           subdevice 0 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       systemd.services.audio-recorder = { | 
					
						
							|  |  |  |         description = "Record NixOS test audio to /tmp/record.wav"; | 
					
						
							|  |  |  |         script = "${pkgs.alsaUtils}/bin/arecord -D recorder -f S16_LE -r48000 /tmp/record.wav"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-05 14:12:51 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 16:27:07 +01:00
										 |  |  |   testScript = ''
 | 
					
						
							| 
									
										
										
										
											2020-10-31 18:24:11 +01:00
										 |  |  |       from contextlib import contextmanager | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       @contextmanager | 
					
						
							|  |  |  |       def audio_recording(machine: Machine) -> None: | 
					
						
							|  |  |  |           """
 | 
					
						
							|  |  |  |           Perform actions while recording the | 
					
						
							|  |  |  |           machine audio output. | 
					
						
							|  |  |  |           """
 | 
					
						
							|  |  |  |           machine.systemctl("start audio-recorder") | 
					
						
							|  |  |  |           yield | 
					
						
							|  |  |  |           machine.systemctl("stop audio-recorder") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def wait_for_sound(machine: Machine) -> None: | 
					
						
							|  |  |  |           """
 | 
					
						
							|  |  |  |           Wait until any sound has been emitted. | 
					
						
							|  |  |  |           """
 | 
					
						
							|  |  |  |           machine.wait_for_file("/tmp/record.wav") | 
					
						
							|  |  |  |           while True: | 
					
						
							|  |  |  |               # Get at most 2M of the recording | 
					
						
							|  |  |  |               machine.execute("tail -c 2M /tmp/record.wav > /tmp/last") | 
					
						
							|  |  |  |               # Get the exact size | 
					
						
							|  |  |  |               size = int(machine.succeed("stat -c '%s' /tmp/last").strip()) | 
					
						
							|  |  |  |               # Compare it against /dev/zero using `cmp` (skipping 50B of WAVE header). | 
					
						
							|  |  |  |               # If some non-NULL bytes are found it returns 1. | 
					
						
							|  |  |  |               status, output = machine.execute( | 
					
						
							|  |  |  |                   f"cmp -i 50 -n {size - 50} /tmp/last /dev/zero 2>&1" | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |               if status == 1: | 
					
						
							|  |  |  |                   break | 
					
						
							|  |  |  |               machine.sleep(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 16:27:07 +01:00
										 |  |  |       machine.wait_for_x() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-31 18:24:11 +01:00
										 |  |  |       with subtest("Wait until Firefox has finished loading the Valgrind docs page"): | 
					
						
							| 
									
										
										
										
											2019-11-05 16:27:07 +01:00
										 |  |  |           machine.execute( | 
					
						
							|  |  |  |               "xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' &" | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |           machine.wait_for_window("Valgrind") | 
					
						
							|  |  |  |           machine.sleep(40) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-31 18:24:11 +01:00
										 |  |  |       with subtest("Check whether Firefox can play sound"): | 
					
						
							|  |  |  |           with audio_recording(machine): | 
					
						
							|  |  |  |               machine.succeed( | 
					
						
							|  |  |  |                   "firefox file://${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/phone-incoming-call.oga &" | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |               wait_for_sound(machine) | 
					
						
							|  |  |  |           machine.copy_from_vm("/tmp/record.wav") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       with subtest("Close sound test tab"): | 
					
						
							|  |  |  |           machine.execute("xdotool key ctrl+w") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 16:27:07 +01:00
										 |  |  |       with subtest("Close default browser prompt"): | 
					
						
							|  |  |  |           machine.execute("xdotool key space") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-31 18:24:11 +01:00
										 |  |  |       with subtest("Wait until Firefox draws the developer tool panel"): | 
					
						
							| 
									
										
										
										
											2019-11-05 16:27:07 +01:00
										 |  |  |           machine.sleep(10) | 
					
						
							|  |  |  |           machine.succeed("xwininfo -root -tree | grep Valgrind") | 
					
						
							|  |  |  |           machine.screenshot("screen") | 
					
						
							| 
									
										
										
										
											2010-01-05 14:12:51 +00:00
										 |  |  |     '';
 | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 14:02:44 +02:00
										 |  |  | }) |