blob: cf07e80c447d761631a561404502bd3b60494789 [file]
// Package commands implements subcommands of cos_gpu_installer.
package commands
import (
"fmt"
"os"
"path/filepath"
"testing"
"cos.googlesource.com/cos/tools.git/src/cmd/cos_gpu_installer/deviceinfo"
"cos.googlesource.com/cos/tools.git/src/cmd/cos_gpu_installer/internal/installer"
"cos.googlesource.com/cos/tools.git/src/pkg/modules"
)
func TestSetCoherentGPUMemoryMode(t *testing.T) {
testCases := []struct {
name string
gpuType deviceinfo.GPUType
driverVersion string
initialParams modules.ModuleParameters
expectParamSet bool
expectedParamValue string
userParamSet bool
}{
{
name: "GB200 with R580 driver should set default",
gpuType: deviceinfo.GB200,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "GB200 with R585 driver should set default",
gpuType: deviceinfo.GB200,
driverVersion: "585.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "GB200 with pre-R580 driver should not set default",
gpuType: deviceinfo.GB200,
driverVersion: "535.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
{
name: "GB200 with user-provided value should not override",
gpuType: deviceinfo.GB200,
driverVersion: "580.01.01",
initialParams: func() modules.ModuleParameters {
p := modules.NewModuleParameters()
p.Set("nvidia.NVreg_CoherentGPUMemoryMode=user_value")
return p
}(),
expectParamSet: false,
userParamSet: false,
},
{
name: "Non-GB200 GPU with R580 driver should not set default",
gpuType: deviceinfo.H200,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
{
name: "GB300 with R580 driver should set default",
gpuType: deviceinfo.GB300,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "GB300 with R585 driver should set default",
gpuType: deviceinfo.GB300,
driverVersion: "585.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "GB300 with pre-R580 driver should not set default",
gpuType: deviceinfo.GB300,
driverVersion: "535.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
{
name: "GB300 with user-provided value should not override",
gpuType: deviceinfo.GB300,
driverVersion: "580.01.01",
initialParams: func() modules.ModuleParameters {
p := modules.NewModuleParameters()
p.Set("nvidia.NVreg_CoherentGPUMemoryMode=user_value")
return p
}(),
expectParamSet: false,
userParamSet: false,
},
{
name: "Non-GB300 GPU with R580 driver should not set default",
gpuType: deviceinfo.H200,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
{
name: "VR200 with R580 driver should set default",
gpuType: deviceinfo.VR200,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "VR200 with R585 driver should set default",
gpuType: deviceinfo.VR200,
driverVersion: "585.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: true,
expectedParamValue: "NVreg_CoherentGPUMemoryMode=driver",
userParamSet: false,
},
{
name: "VR200 with pre-R580 driver should not set default",
gpuType: deviceinfo.VR200,
driverVersion: "535.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
{
name: "VR200 with user-provided value should not override",
gpuType: deviceinfo.VR200,
driverVersion: "580.01.01",
initialParams: func() modules.ModuleParameters {
p := modules.NewModuleParameters()
p.Set("nvidia.NVreg_CoherentGPUMemoryMode=user_value")
return p
}(),
expectParamSet: false,
userParamSet: false,
},
{
name: "Non-VR200 GPU with R580 driver should not set default",
gpuType: deviceinfo.H200,
driverVersion: "580.01.01",
initialParams: modules.NewModuleParameters(),
expectParamSet: false,
userParamSet: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cmd := &InstallCommand{
driverVersion: tc.driverVersion,
kernelModuleParams: tc.initialParams,
}
if err := cmd.enableCDMM(tc.gpuType); err != nil {
t.Fatalf("enableCDMM failed: %v", err)
}
paramWasSet := false
if params, ok := cmd.kernelModuleParams["nvidia"]; ok {
for _, param := range params {
if param == "NVreg_CoherentGPUMemoryMode=driver" {
paramWasSet = true
break
}
}
}
if tc.expectParamSet != paramWasSet {
t.Errorf("Expected param set state to be %v, but got %v", tc.expectParamSet, paramWasSet)
}
// Verify user-set value is preserved
if tc.userParamSet {
foundUserValue := false
if params, ok := cmd.kernelModuleParams["nvidia"]; ok {
for _, param := range params {
if param == "NVreg_CoherentGPUMemoryMode=user_value" {
foundUserValue = true
break
}
}
}
if !foundUserValue {
t.Errorf("User-provided kernel module parameter was not preserved.")
}
}
})
}
}
const (
testBuildNumber = "19999.44.28"
testDriverVersion = "580.95.05"
testOtherDriverVersion = "570.10.01"
// testMarkerLibrary is a library every installation holds, with the driver
// version it belongs to as its content, so that a test can tell which
// installation a path in the install dir leads to.
testMarkerLibrary = "lib64/libcuda.so"
)
// writeInstallTree creates a driver installation directory holding a cache
// entry for the given build and driver version, plus the marker library.
func writeInstallTree(t *testing.T, dir, buildNumber, driverVersion string, kernelOpen bool) {
t.Helper()
if err := os.MkdirAll(filepath.Join(dir, filepath.Dir(testMarkerLibrary)), 0755); err != nil {
t.Fatalf("Failed to create %s: %v", dir, err)
}
cache := fmt.Sprintf("BUILD_ID=%s\nDRIVER_VERSION=%s\n", buildNumber, driverVersion)
if kernelOpen {
cache += "KERNEL_OPEN=Y\n"
}
if err := os.WriteFile(filepath.Join(dir, installer.CacheFile), []byte(cache), 0644); err != nil {
t.Fatalf("Failed to write the cache entry in %s: %v", dir, err)
}
if err := os.WriteFile(filepath.Join(dir, testMarkerLibrary), []byte(driverVersion), 0644); err != nil {
t.Fatalf("Failed to write %s in %s: %v", testMarkerLibrary, dir, err)
}
}
// installedVersion returns the driver version of the installation that dir
// leads to, as recorded in its marker library.
func installedVersion(t *testing.T, dir string) string {
t.Helper()
content, err := os.ReadFile(filepath.Join(dir, testMarkerLibrary))
if err != nil {
t.Fatalf("Failed to read %s in %s: %v", testMarkerLibrary, dir, err)
}
return string(content)
}
func TestActivatePreloadedInstall(t *testing.T) {
testCases := []struct {
name string
// preloadedDirs are subdirectories of the install dir to populate with
// preloaded installations of testDriverVersion.
preloadedDirs []string
// preloadedBuildNumber is the COS build recorded in those installations.
preloadedBuildNumber string
// preloadedOpen is the kernel module flavor recorded in them.
preloadedOpen bool
kernelOpen bool
wantActivated bool
}{
{
name: "activates a matching open preloaded installation",
preloadedDirs: []string{testDriverVersion + "-open"},
preloadedBuildNumber: testBuildNumber,
preloadedOpen: true,
kernelOpen: true,
wantActivated: true,
},
{
name: "activates a matching proprietary preloaded installation",
preloadedDirs: []string{testDriverVersion + "-closed"},
preloadedBuildNumber: testBuildNumber,
kernelOpen: false,
wantActivated: true,
},
{
name: "activates a preloaded installation under an arbitrary directory name",
preloadedDirs: []string{"preloaded-driver-0"},
preloadedBuildNumber: testBuildNumber,
preloadedOpen: true,
kernelOpen: true,
wantActivated: true,
},
{
name: "ignores a preloaded installation of the other kernel module flavor",
preloadedDirs: []string{testDriverVersion + "-closed"},
preloadedBuildNumber: testBuildNumber,
kernelOpen: true,
wantActivated: false,
},
{
name: "ignores a preloaded installation from another COS build",
preloadedDirs: []string{testDriverVersion + "-open"},
preloadedBuildNumber: "12345.6.7",
preloadedOpen: true,
kernelOpen: true,
wantActivated: false,
},
{
name: "does nothing without preloaded installations",
kernelOpen: true,
wantActivated: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
installDir := t.TempDir()
// The versions proto lives next to the activated installation and must
// survive activation.
protoPath := filepath.Join(installDir, "gpu_driver_versions.bin")
if err := os.WriteFile(protoPath, []byte("proto"), 0644); err != nil {
t.Fatalf("Failed to write %s: %v", protoPath, err)
}
for _, dir := range tc.preloadedDirs {
writeInstallTree(t, filepath.Join(installDir, dir), tc.preloadedBuildNumber, testDriverVersion, tc.preloadedOpen)
}
if err := activatePreloadedInstall(installDir, testBuildNumber, testDriverVersion, tc.kernelOpen); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, %t) returned error: %v", installDir, testBuildNumber, testDriverVersion, tc.kernelOpen, err)
}
isCached, isOpen, err := installer.NewCacher(installDir, testBuildNumber, testDriverVersion).IsCached()
gotActivated := isCached && err == nil
if gotActivated != tc.wantActivated {
t.Errorf("After activatePreloadedInstall, install dir cached = %t, want %t", gotActivated, tc.wantActivated)
}
if tc.wantActivated {
if isOpen != tc.kernelOpen {
t.Errorf("After activatePreloadedInstall, install dir kernel open = %t, want %t", isOpen, tc.kernelOpen)
}
if got := installedVersion(t, installDir); got != testDriverVersion {
t.Errorf("Install dir holds driver version %q, want %q", got, testDriverVersion)
}
// The payload is linked into the install dir rather than copied,
// with relative targets, as the install dir is bind mounted under
// other paths.
for _, name := range []string{filepath.Dir(testMarkerLibrary), installer.CacheFile} {
path := filepath.Join(installDir, name)
target, err := os.Readlink(path)
if err != nil {
t.Errorf("Failed to read the link %s: %v", path, err)
continue
}
if filepath.IsAbs(target) {
t.Errorf("Link %s points to %q, want a target relative to the install dir", path, target)
}
}
}
if _, err := os.Stat(protoPath); err != nil {
t.Errorf("Expected %s to be preserved: %v", protoPath, err)
}
// Preloaded installations must remain available for later activations.
for _, dir := range tc.preloadedDirs {
if _, err := os.Stat(filepath.Join(installDir, dir, installer.CacheFile)); err != nil {
t.Errorf("Expected preloaded installation %s to be preserved: %v", dir, err)
}
}
})
}
}
// TestActivatePreloadedInstallSwitchesVersion checks that activating another
// version repoints the install dir at it, and that what is written to the
// install dir afterwards reaches that version alone.
func TestActivatePreloadedInstallSwitchesVersion(t *testing.T) {
installDir := t.TempDir()
otherDir := filepath.Join(installDir, testOtherDriverVersion+"-open")
writeInstallTree(t, otherDir, testBuildNumber, testOtherDriverVersion, true)
writeInstallTree(t, filepath.Join(installDir, testDriverVersion+"-open"), testBuildNumber, testDriverVersion, true)
if err := activatePreloadedInstall(installDir, testBuildNumber, testOtherDriverVersion, true); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, true) returned error: %v", installDir, testBuildNumber, testOtherDriverVersion, err)
}
if err := activatePreloadedInstall(installDir, testBuildNumber, testDriverVersion, true); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, true) returned error: %v", installDir, testBuildNumber, testDriverVersion, err)
}
if err := installer.NewCacher(installDir, testBuildNumber, testDriverVersion).Cache(true); err != nil {
t.Fatalf("Failed to write the cache entry of %s: %v", installDir, err)
}
if got := installedVersion(t, installDir); got != testDriverVersion {
t.Errorf("Install dir holds driver version %q, want %q", got, testDriverVersion)
}
if got := installedVersion(t, otherDir); got != testOtherDriverVersion {
t.Errorf("Preloaded installation %s holds driver version %q, want %q", otherDir, got, testOtherDriverVersion)
}
if isCached, _, err := installer.NewCacher(otherDir, testBuildNumber, testOtherDriverVersion).IsCached(); err != nil || !isCached {
t.Errorf("Preloaded installation %s cached for %s = %t (err %v), want true", otherDir, testOtherDriverVersion, isCached, err)
}
}
// TestActivatePreloadedInstallDeactivates checks that a driver version without
// a preloaded installation takes down the activated one, so that it is not
// installed over a preloaded installation of another version.
func TestActivatePreloadedInstallDeactivates(t *testing.T) {
installDir := t.TempDir()
preloadedDir := filepath.Join(installDir, testDriverVersion+"-open")
writeInstallTree(t, preloadedDir, testBuildNumber, testDriverVersion, true)
if err := activatePreloadedInstall(installDir, testBuildNumber, testDriverVersion, true); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, true) returned error: %v", installDir, testBuildNumber, testDriverVersion, err)
}
if err := activatePreloadedInstall(installDir, testBuildNumber, testOtherDriverVersion, true); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, true) returned error: %v", installDir, testBuildNumber, testOtherDriverVersion, err)
}
entries, err := os.ReadDir(installDir)
if err != nil {
t.Fatalf("Failed to read %s: %v", installDir, err)
}
for _, entry := range entries {
if entry.Type()&os.ModeSymlink != 0 {
t.Errorf("Install dir holds %s, want the links of the deactivated installation to be removed", entry.Name())
}
}
// Installing the driver the regular way must now write to the install dir
// itself rather than into the preloaded installation.
writeInstallTree(t, installDir, testBuildNumber, testOtherDriverVersion, true)
if got := installedVersion(t, preloadedDir); got != testDriverVersion {
t.Errorf("Preloaded installation %s holds driver version %q, want %q", preloadedDir, got, testDriverVersion)
}
}
// TestActivatePreloadedInstallKeepsRegularInstall checks that a driver the
// install dir already holds is not replaced, since it was not put there by an
// earlier activation.
func TestActivatePreloadedInstallKeepsRegularInstall(t *testing.T) {
installDir := t.TempDir()
writeInstallTree(t, installDir, testBuildNumber, testOtherDriverVersion, true)
writeInstallTree(t, filepath.Join(installDir, testDriverVersion+"-open"), testBuildNumber, testDriverVersion, true)
if err := activatePreloadedInstall(installDir, testBuildNumber, testDriverVersion, true); err != nil {
t.Fatalf("activatePreloadedInstall(%q, %q, %q, true) returned error: %v", installDir, testBuildNumber, testDriverVersion, err)
}
if got := installedVersion(t, installDir); got != testOtherDriverVersion {
t.Errorf("Install dir holds driver version %q, want the installation %q it already held", got, testOtherDriverVersion)
}
}