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