Unverified Commit 83c19c79 authored by Jörg Thalheim's avatar Jörg Thalheim Committed by GitHub
Browse files

Merge pull request #200757 from Flakebi/rocm-test

nixos/tests: add ROCm and amdvlk tests
parents 639d8523 3ac01325
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
/* Create tests that run in the nix sandbox with additional access to selected host paths

  This is for example useful for testing hardware where a tests needs access to
  /sys and optionally more.

  The following example shows a test that accesses the GPU:

  Example:
    makeImpureTest {
      name = "opencl";
      testedPackage = "mypackage"; # Or testPath = "mypackage.impureTests.opencl.testDerivation"

      sandboxPaths = [ "/sys" "/dev/dri" ]; # Defaults to ["/sys"]
      prepareRunCommands = ""; # (Optional) Setup for the runScript
      nixFlags = []; # (Optional) nix-build options for the runScript

      testScript = "...";
    }

  Save as `test.nix` next to a package and reference it from the package:
    passthru.impureTests = { opencl = callPackage ./test.nix {}; };

  `makeImpureTest` will return here a script that contains the actual nix-build command including all necessary sandbox flags.

  It can be executed like this:
    $(nix-build -A mypackage.impureTests)

  Rerun an already cached test:
    $(nix-build -A mypackage.impureTests) --check
*/
{ lib
, stdenv
, writeShellScript

, name
, testedPackage ? null
, testPath ? "${testedPackage}.impureTests.${name}.testDerivation"
, sandboxPaths ? [ "/sys" ]
, prepareRunCommands ? ""
, nixFlags ? [ ]
, testScript
, ...
} @ args:

let
  sandboxPathsTests = builtins.map (path: "[[ ! -e '${path}' ]]") sandboxPaths;
  sandboxPathsTest = lib.concatStringsSep " || " sandboxPathsTests;
  sandboxPathsList = lib.concatStringsSep " " sandboxPaths;

  testDerivation = stdenv.mkDerivation (lib.recursiveUpdate
    {
      name = "test-run-${name}";

      requiredSystemFeatures = [ "nixos-test" ];

      buildCommand = ''
        mkdir -p $out

        if ${sandboxPathsTest}; then
          echo 'Run this test as *root* with `--option extra-sandbox-paths '"'${sandboxPathsList}'"'`'
          exit 1
        fi

        # Run test
        ${testScript}
      '';

      passthru.runScript = runScript;
    }
    (builtins.removeAttrs args [
      "lib"
      "stdenv"
      "writeShellScript"

      "name"
      "testedPackage"
      "testPath"
      "sandboxPaths"
      "prepareRunCommands"
      "nixFlags"
      "testScript"
    ])
  );

  runScript = writeShellScript "run-script-${name}" ''
    set -euo pipefail

    ${prepareRunCommands}

    sudo nix-build --option extra-sandbox-paths '${sandboxPathsList}' ${lib.escapeShellArgs nixFlags} -A ${testPath} "$@"
  '';
in
# The main output is the run script, inject the derivation for the actual test
runScript.overrideAttrs (old: {
  passthru = { inherit testDerivation; };
})
+3 −0
Original line number Diff line number Diff line
{ stdenv
, callPackage
, lib
, fetchRepoProject
, writeScript
@@ -102,6 +103,8 @@ in stdenv.mkDerivation rec {
    setHash "$hash"
  '';

  passthru.impureTests = { amdvlk = callPackage ./test.nix {}; };

  meta = with lib; {
    description = "AMD Open Source Driver For Vulkan";
    homepage = "https://github.com/GPUOpen-Drivers/AMDVLK";
+49 −0
Original line number Diff line number Diff line
{ lib, makeImpureTest, coreutils, amdvlk, vulkan-tools }:
makeImpureTest {
  name = "amdvlk";
  testedPackage = "amdvlk";

  sandboxPaths = [ "/sys" "/dev/dri" ];

  nativeBuildInputs = [ vulkan-tools ];

  VK_ICD_FILENAMES = "${amdvlk}/share/vulkan/icd.d/amd_icd64.json";
  XDG_RUNTIME_DIR = "/tmp";

  # AMDVLK needs access to /dev/dri/card0 (or another card), but normally it is rw-rw----
  # Change the permissions to be rw for everyone
  prepareRunCommands = ''
    function reset_perms()
    {
      # Reset permissions to previous state
      for card in /dev/dri/card*; do
        sudo ${coreutils}/bin/chmod "0''${cardPerms[$card]}" $card
      done
    }

    # Save permissions on /dev/dri/card*
    declare -A cardPerms
    for card in /dev/dri/card*; do
      cardPerms[$card]=$(stat -c "%a" $card)
    done

    sudo ${coreutils}/bin/chmod o+rw /dev/dri/card*
    trap reset_perms EXIT
  '';

  testScript = ''
    # Check that there is at least one card with write-access
    if ! ls -l /dev/dri/card* | cut -b8-9 | grep -q rw; then
      echo 'AMDVLK needs rw access to /dev/dri/card0 or a fitting card, please run `sudo chmod o+rw /dev/dri/card*`'
      exit 1
    fi

    vulkaninfo --summary
    echo "Checking version"
    vulkaninfo --summary | grep '= ${amdvlk.version}'
  '';

  meta = with lib.maintainers; {
    maintainers = [ Flakebi ];
  };
}
+3 −1
Original line number Diff line number Diff line
{ lib, stdenv, rocm-opencl-runtime }:
{ lib, callPackage, stdenv, rocm-opencl-runtime }:

stdenv.mkDerivation rec {
  pname = "rocm-opencl-icd";
@@ -11,6 +11,8 @@ stdenv.mkDerivation rec {
    echo "${rocm-opencl-runtime}/lib/libamdocl64.so" > $out/etc/OpenCL/vendors/amdocl64.icd
  '';

  passthru.impureTests = { rocm-opencl = callPackage ./test.nix {}; };

  meta = with lib; {
    description = "OpenCL ICD definition for AMD GPUs using the ROCm stack";
    license = licenses.mit;
+19 −0
Original line number Diff line number Diff line
{ lib, makeImpureTest, clinfo, rocm-opencl-icd, rocm-smi }:
makeImpureTest {
  name = "rocm-opencl";
  testedPackage = "rocm-opencl-icd";

  nativeBuildInputs = [ clinfo rocm-smi ];

  OCL_ICD_VENDORS = "${rocm-opencl-icd}/etc/OpenCL/vendors/";

  testScript = ''
    # Test fails if the number of platforms is 0
    clinfo | grep -E 'Number of platforms * [1-9]'
    rocm-smi | grep -A1 GPU
  '';

  meta = with lib; {
    maintainers = teams.rocm.members;
  };
}
Loading