at 24.11-pre 3.9 kB view raw
1import ./make-test-python.nix ({ pkgs, ... }: { 2 name = "mtp"; 3 meta = with pkgs.lib.maintainers; { 4 maintainers = [ matthewcroughan nixinator ]; 5 }; 6 7 nodes = 8 { 9 client = { config, pkgs, ... }: { 10 # DBUS runs only once a user session is created, which means a user has to 11 # login. Here, we log in as root. Once logged in, the gvfs-daemon service runs 12 # as UID 0 in User-0.service 13 services.getty.autologinUser = "root"; 14 15 # XDG_RUNTIME_DIR is needed for running systemd-user services such as 16 # gvfs-daemon as root. 17 environment.variables.XDG_RUNTIME_DIR = "/run/user/0"; 18 19 environment.systemPackages = with pkgs; [ usbutils glib jmtpfs tree ]; 20 services.gvfs.enable = true; 21 22 # Creates a usb-mtp device inside the VM, which is mapped to the host's 23 # /tmp folder, it is able to write files to this location, but only has 24 # permissions to read its own creations. 25 virtualisation.qemu.options = [ 26 "-usb" 27 "-device usb-mtp,rootdir=/tmp,readonly=false" 28 ]; 29 }; 30 }; 31 32 33 testScript = { nodes, ... }: 34 let 35 # Creates a list of QEMU MTP devices matching USB ID (46f4:0004). This 36 # value can be sourced in a shell script. This is so we can loop over the 37 # devices we find, as this test may want to use more than one MTP device 38 # in future. 39 mtpDevices = pkgs.writeScript "mtpDevices.sh" '' 40 export mtpDevices=$(lsusb -d 46f4:0004 | awk {'print $2","$4'} | sed 's/[:-]/ /g') 41 ''; 42 # Qemu is only capable of creating an MTP device with Picture Transfer 43 # Protocol. This means that gvfs must use gphoto2:// rather than mtp:// 44 # when mounting. 45 # https://github.com/qemu/qemu/blob/970bc16f60937bcfd334f14c614bd4407c247961/hw/usb/dev-mtp.c#L278 46 gvfs = rec { 47 mountAllMtpDevices = pkgs.writeScript "mountAllMtpDevices.sh" '' 48 set -e 49 source ${mtpDevices} 50 for i in $mtpDevices 51 do 52 gio mount "gphoto2://[usb:$i]/" 53 done 54 ''; 55 unmountAllMtpDevices = pkgs.writeScript "unmountAllMtpDevices.sh" '' 56 set -e 57 source ${mtpDevices} 58 for i in $mtpDevices 59 do 60 gio mount -u "gphoto2://[usb:$i]/" 61 done 62 ''; 63 # gvfsTest: 64 # 1. Creates a 10M test file 65 # 2. Copies it to the device using GIO tools 66 # 3. Checks for corruption with `diff` 67 # 4. Removes the file, then unmounts the disks. 68 gvfsTest = pkgs.writeScript "gvfsTest.sh" '' 69 set -e 70 source ${mtpDevices} 71 ${mountAllMtpDevices} 72 dd if=/dev/urandom of=testFile10M bs=1M count=10 73 for i in $mtpDevices 74 do 75 gio copy ./testFile10M gphoto2://[usb:$i]/ 76 ls -lah /run/user/0/gvfs/*/testFile10M 77 gio remove gphoto2://[usb:$i]/testFile10M 78 done 79 ${unmountAllMtpDevices} 80 ''; 81 }; 82 jmtpfs = { 83 # jmtpfsTest: 84 # 1. Mounts the device on a dir named `phone` using jmtpfs 85 # 2. Puts the current Nixpkgs libmtp version into a file 86 # 3. Checks for corruption with `diff` 87 # 4. Prints the directory tree 88 jmtpfsTest = pkgs.writeScript "jmtpfsTest.sh" '' 89 set -e 90 mkdir phone 91 jmtpfs phone 92 echo "${pkgs.libmtp.version}" > phone/tmp/testFile 93 echo "${pkgs.libmtp.version}" > testFile 94 diff phone/tmp/testFile testFile 95 tree phone 96 ''; 97 }; 98 in 99 # Using >&2 allows the results of the scripts to be printed to the terminal 100 # when building this test with Nix. Scripts would otherwise complete 101 # silently. 102 '' 103 start_all() 104 client.wait_for_unit("multi-user.target") 105 client.wait_for_unit("dbus.service") 106 client.succeed("${gvfs.gvfsTest} >&2") 107 client.succeed("${jmtpfs.jmtpfsTest} >&2") 108 ''; 109})