aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/sharefs
diff options
context:
space:
mode:
Diffstat (limited to 'test/sharefs')
-rw-r--r--test/sharefs/configuration.nix44
-rw-r--r--test/sharefs/default.nix44
-rw-r--r--test/sharefs/main.go126
-rw-r--r--test/sharefs/test.py60
4 files changed, 126 insertions, 148 deletions
diff --git a/test/sharefs/configuration.nix b/test/sharefs/configuration.nix
deleted file mode 100644
index 05d67dcb..00000000
--- a/test/sharefs/configuration.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{ pkgs, ... }:
-{
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- # Automatically login on tty1 as a normal user:
- services.getty.autologinUser = "alice";
-
- environment = {
- # For benchmarking sharefs:
- systemPackages = [ pkgs.fsmark ];
- };
-
- virtualisation = {
- # Hopefully reduces spurious test failures:
- memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192;
-
- diskSize = 6 * 1024;
-
- qemu.options = [
- # Increase test performance:
- "-smp 16"
- ];
- };
-
- environment.hakurei = rec {
- enable = true;
- stateDir = "/var/lib/hakurei";
- sharefs.source = "${stateDir}/sdcard";
- users.alice = 0;
-
- extraHomeConfig = {
- home.stateVersion = "23.05";
- };
- };
-}
diff --git a/test/sharefs/default.nix b/test/sharefs/default.nix
deleted file mode 100644
index e963eaa6..00000000
--- a/test/sharefs/default.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- testers,
-
- system,
- self,
-}:
-testers.nixosTest {
- name = "sharefs";
- nodes.machine =
- { options, pkgs, ... }:
- let
- fhs =
- let
- hakurei = options.environment.hakurei.package.default;
- in
- pkgs.buildFHSEnv {
- pname = "hakurei-fhs";
- inherit (hakurei) version;
- targetPkgs = _: hakurei.targetPkgs;
- extraOutputsToInstall = [ "dev" ];
- profile = ''
- export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH"
- '';
- };
- in
- {
- environment.systemPackages = [
- # For go tests:
- (pkgs.writeShellScriptBin "sharefs-workload-hakurei-tests" ''
- cp -r "${self.packages.${system}.hakurei.src}" "/sdcard/hakurei" && cd "/sdcard/hakurei"
- ${fhs}/bin/hakurei-fhs -c 'ROSA_SKIP_BINFMT=1 CC="clang -O3 -Werror" go test ./...'
- '')
- ];
-
- imports = [
- ./configuration.nix
-
- self.nixosModules.hakurei
- self.inputs.home-manager.nixosModules.home-manager
- ];
- };
-
- testScript = builtins.readFile ./test.py;
-}
diff --git a/test/sharefs/main.go b/test/sharefs/main.go
new file mode 100644
index 00000000..536a61b3
--- /dev/null
+++ b/test/sharefs/main.go
@@ -0,0 +1,126 @@
+//go:build testsuite
+
+// The sharefs test program checks cli behaviour and exercises the filesystem
+// implemented by cmd/sharefs using fs_mark.
+package main
+
+import (
+ "errors"
+ "log"
+ "os"
+ "os/exec"
+ "slices"
+ "strings"
+
+ "hakurei.app/test/internal/testsuite"
+)
+
+// checkBadOpts invokes cmd/sharefs with the specified options and compares
+// the resulting error message.
+func checkBadOpts(username, opts, want string) {
+ var buf strings.Builder
+ buf.Grow(len(want))
+
+ sudo := []string{"sudo", "-u", username, "-i", "--"}
+ if username == "root" {
+ sudo = nil
+ }
+
+ a := slices.Concat(sudo, []string{
+ "sharefs",
+ "-f",
+ "-o", "source=/etc," + opts,
+ "/mnt",
+ })
+ cmd := exec.Command(a[0], a[1:]...)
+ cmd.Stderr = &buf
+ err := cmd.Run()
+ if err == nil {
+ log.Fatalf("opts=%q, unexpected success", opts)
+ }
+ if e, ok := errors.AsType[*exec.ExitError](err); !ok {
+ log.Fatal(err)
+ } else if !e.Exited() {
+ log.Fatal(e)
+ }
+
+ if got := buf.String(); got != want {
+ log.Fatalf("opts=%q\n\t got:%q\n\twant:%q", opts, got, want)
+ }
+}
+
+func main() {
+ go testsuite.ReceiveSignals()
+
+ if err := os.Mkdir("result", 0755); err != nil {
+ log.Fatal(err)
+ }
+
+ if len(os.Args) != 2 {
+ log.Fatal("expecting 1 argument")
+ }
+ username := os.Args[1]
+
+ done := make(chan struct{})
+ go func() {
+ defer close(done)
+
+ testsuite.MustRun(
+ "fs_mark",
+ "-v",
+ "-d", "/sdcard/fs_mark",
+ "-l", "result/fs_mark.log",
+ )
+ }()
+
+ log.Println("checking malformed setuid/setgid representation")
+ checkBadOpts(username, "setuid=ff", "sharefs: invalid value for option setuid\n")
+ checkBadOpts(username, "setgid=ff", "sharefs: invalid value for option setgid\n")
+
+ log.Println("checking bounds check for setuid/setgid")
+ checkBadOpts(username, "setuid=0", "sharefs: invalid value for option setuid\n")
+ checkBadOpts(username, "setgid=0", "sharefs: invalid value for option setgid\n")
+ checkBadOpts(username, "setuid=-1", "sharefs: invalid value for option setuid\n")
+ checkBadOpts(username, "setgid=-1", "sharefs: invalid value for option setgid\n")
+
+ log.Println("checking non-root setuid/setgid")
+ checkBadOpts(username, "setuid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
+ checkBadOpts(username, "setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
+ checkBadOpts(username, "setuid=1023,setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
+ checkBadOpts(username, "mkdir", "sharefs: mkdir has no effect when not starting as root\n")
+
+ log.Println("checking root without setuid/setgid")
+ checkBadOpts("root", "allow_other", "sharefs: setuid and setgid must not be 0\n")
+ checkBadOpts("root", "setuid=1023", "sharefs: setuid and setgid must not be 0\n")
+ checkBadOpts("root", "setgid=1023", "sharefs: setuid and setgid must not be 0\n")
+
+ log.Println("verifying mount point")
+ if err := os.Remove("/mnt"); err != nil {
+ log.Fatal(err)
+ }
+
+ log.Println("checking unprivileged mount/unmount")
+ testsuite.MustRunAs(username, "-i", "mkdir", "/tmp/sdcard", "/tmp/persistent")
+ testsuite.MustRunAs(username, "-i", "sharefs", "-o", "source=/tmp/persistent", "/tmp/sdcard")
+ testsuite.MustRunAs(username, "-i", "touch", "/tmp/sdcard/check")
+ testsuite.MustRunAs(username, "-i", "umount", "/tmp/sdcard")
+ testsuite.MustRunAs(username, "-i", "rm", "/tmp/persistent/check")
+ testsuite.MustRunAs(username, "-i", "rmdir", "/tmp/sdcard", "/tmp/persistent")
+
+ log.Println("waiting for fs_mark to complete")
+ <-done
+
+ const (
+ backingDir = "/var/lib/sdcard"
+ sharefsUser = "media_rw"
+ )
+ log.Println("checking permissions")
+ testsuite.MustRunAs(sharefsUser, "touch", backingDir+"/fs_mark/.check")
+ testsuite.MustRunAs(sharefsUser, "rm", backingDir+"/fs_mark/.check")
+ testsuite.MustRunAs(username, "-i", "rm", "-rf", "/sdcard/fs_mark")
+ if _, err := os.ReadDir(backingDir + "/fs_mark"); err == nil {
+ log.Fatal("fs_mark directory was not removed")
+ } else if !errors.Is(err, os.ErrNotExist) {
+ log.Fatal(err)
+ }
+}
diff --git a/test/sharefs/test.py b/test/sharefs/test.py
deleted file mode 100644
index 4b925c9c..00000000
--- a/test/sharefs/test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-start_all()
-machine.wait_for_unit("multi-user.target")
-
-# To check sharefs version:
-print(machine.succeed("sharefs -V"))
-
-# Make sure sharefs started:
-machine.wait_for_unit("sdcard.mount")
-
-machine.succeed("mkdir /mnt")
-def check_bad_opts_output(opts, want, source="/etc", privileged=False):
- output = machine.fail(("" if privileged else "sudo -u alice -i ") + f"sharefs -f -o source={source},{opts} /mnt 2>&1")
- if output != want:
- raise Exception(f"unexpected output: {output}")
-
-# Malformed setuid/setgid representation:
-check_bad_opts_output("setuid=ff", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=ff", "sharefs: invalid value for option setgid\n")
-
-# Bounds check for setuid/setgid:
-check_bad_opts_output("setuid=0", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=0", "sharefs: invalid value for option setgid\n")
-check_bad_opts_output("setuid=-1", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=-1", "sharefs: invalid value for option setgid\n")
-
-# Non-root setuid/setgid:
-check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("setuid=1023,setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("mkdir", "sharefs: mkdir has no effect when not starting as root\n")
-
-# Starting as root without setuid/setgid:
-check_bad_opts_output("allow_other", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-
-# Make sure nothing actually got mounted:
-machine.fail("umount /mnt")
-machine.succeed("rmdir /mnt")
-
-# Unprivileged mount/unmount:
-machine.succeed("sudo -u alice -i mkdir /home/alice/{sdcard,persistent}")
-machine.succeed("sudo -u alice -i sharefs -o source=/home/alice/persistent /home/alice/sdcard")
-machine.succeed("sudo -u alice -i touch /home/alice/sdcard/check")
-machine.succeed("sudo -u alice -i umount /home/alice/sdcard")
-machine.succeed("sudo -u alice -i rm /home/alice/persistent/check")
-machine.succeed("sudo -u alice -i rmdir /home/alice/{sdcard,persistent}")
-
-# Benchmark sharefs:
-machine.succeed("fs_mark -v -d /sdcard/fs_mark -l /tmp/fs_log.txt")
-machine.copy_from_vm("/tmp/fs_log.txt", "")
-
-# Check permissions:
-machine.succeed("sudo -u sharefs touch /var/lib/hakurei/sdcard/fs_mark/.check")
-machine.succeed("sudo -u sharefs rm /var/lib/hakurei/sdcard/fs_mark/.check")
-machine.succeed("sudo -u alice rm -rf /sdcard/fs_mark")
-machine.fail("ls /var/lib/hakurei/sdcard/fs_mark")
-
-# Run hakurei tests on sharefs:
-machine.succeed("sudo -u alice -i sharefs-workload-hakurei-tests")