110 lines
3.8 KiB
Nix
110 lines
3.8 KiB
Nix
|
import ./make-test-python.nix ({ pkgs, ... }: {
|
||
|
name = "mtp";
|
||
|
meta = with pkgs.lib.maintainers; {
|
||
|
maintainers = [ matthewcroughan nixinator ];
|
||
|
};
|
||
|
|
||
|
nodes =
|
||
|
{
|
||
|
client = { config, pkgs, ... }: {
|
||
|
# DBUS runs only once a user session is created, which means a user has to
|
||
|
# login. Here, we log in as root. Once logged in, the gvfs-daemon service runs
|
||
|
# as UID 0 in User-0.service
|
||
|
services.getty.autologinUser = "root";
|
||
|
|
||
|
# XDG_RUNTIME_DIR is needed for running systemd-user services such as
|
||
|
# gvfs-daemon as root.
|
||
|
environment.variables.XDG_RUNTIME_DIR = "/run/user/0";
|
||
|
|
||
|
environment.systemPackages = with pkgs; [ usbutils glib jmtpfs tree ];
|
||
|
services.gvfs.enable = true;
|
||
|
|
||
|
# Creates a usb-mtp device inside the VM, which is mapped to the host's
|
||
|
# /tmp folder, it is able to write files to this location, but only has
|
||
|
# permissions to read its own creations.
|
||
|
virtualisation.qemu.options = [
|
||
|
"-usb"
|
||
|
"-device usb-mtp,rootdir=/tmp,readonly=false"
|
||
|
];
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
testScript = { nodes, ... }:
|
||
|
let
|
||
|
# Creates a list of QEMU MTP devices matching USB ID (46f4:0004). This
|
||
|
# value can be sourced in a shell script. This is so we can loop over the
|
||
|
# devices we find, as this test may want to use more than one MTP device
|
||
|
# in future.
|
||
|
mtpDevices = pkgs.writeScript "mtpDevices.sh" ''
|
||
|
export mtpDevices=$(lsusb -d 46f4:0004 | awk {'print $2","$4'} | sed 's/[:-]/ /g')
|
||
|
'';
|
||
|
# Qemu is only capable of creating an MTP device with Picture Transfer
|
||
|
# Protocol. This means that gvfs must use gphoto2:// rather than mtp://
|
||
|
# when mounting.
|
||
|
# https://github.com/qemu/qemu/blob/970bc16f60937bcfd334f14c614bd4407c247961/hw/usb/dev-mtp.c#L278
|
||
|
gvfs = rec {
|
||
|
mountAllMtpDevices = pkgs.writeScript "mountAllMtpDevices.sh" ''
|
||
|
set -e
|
||
|
source ${mtpDevices}
|
||
|
for i in $mtpDevices
|
||
|
do
|
||
|
gio mount "gphoto2://[usb:$i]/"
|
||
|
done
|
||
|
'';
|
||
|
unmountAllMtpDevices = pkgs.writeScript "unmountAllMtpDevices.sh" ''
|
||
|
set -e
|
||
|
source ${mtpDevices}
|
||
|
for i in $mtpDevices
|
||
|
do
|
||
|
gio mount -u "gphoto2://[usb:$i]/"
|
||
|
done
|
||
|
'';
|
||
|
# gvfsTest:
|
||
|
# 1. Creates a 10M test file
|
||
|
# 2. Copies it to the device using GIO tools
|
||
|
# 3. Checks for corruption with `diff`
|
||
|
# 4. Removes the file, then unmounts the disks.
|
||
|
gvfsTest = pkgs.writeScript "gvfsTest.sh" ''
|
||
|
set -e
|
||
|
source ${mtpDevices}
|
||
|
${mountAllMtpDevices}
|
||
|
dd if=/dev/urandom of=testFile10M bs=1M count=10
|
||
|
for i in $mtpDevices
|
||
|
do
|
||
|
gio copy ./testFile10M gphoto2://[usb:$i]/
|
||
|
ls -lah /run/user/0/gvfs/*/testFile10M
|
||
|
gio remove gphoto2://[usb:$i]/testFile10M
|
||
|
done
|
||
|
${unmountAllMtpDevices}
|
||
|
'';
|
||
|
};
|
||
|
jmtpfs = {
|
||
|
# jmtpfsTest:
|
||
|
# 1. Mounts the device on a dir named `phone` using jmtpfs
|
||
|
# 2. Puts the current Nixpkgs libmtp version into a file
|
||
|
# 3. Checks for corruption with `diff`
|
||
|
# 4. Prints the directory tree
|
||
|
jmtpfsTest = pkgs.writeScript "jmtpfsTest.sh" ''
|
||
|
set -e
|
||
|
mkdir phone
|
||
|
jmtpfs phone
|
||
|
echo "${pkgs.libmtp.version}" > phone/tmp/testFile
|
||
|
echo "${pkgs.libmtp.version}" > testFile
|
||
|
diff phone/tmp/testFile testFile
|
||
|
tree phone
|
||
|
'';
|
||
|
};
|
||
|
in
|
||
|
# Using >&2 allows the results of the scripts to be printed to the terminal
|
||
|
# when building this test with Nix. Scripts would otherwise complete
|
||
|
# silently.
|
||
|
''
|
||
|
start_all()
|
||
|
client.wait_for_unit("multi-user.target")
|
||
|
client.wait_for_unit("dbus.service")
|
||
|
client.succeed("${gvfs.gvfsTest} >&2")
|
||
|
client.succeed("${jmtpfs.jmtpfsTest} >&2")
|
||
|
'';
|
||
|
})
|