Files
visor/test/gpu/sniffer_test.go
Etienne PerotandgVisor bot ab5ca5f42d Integrate GPU ioctl sniffer in GPU tests.
This wraps all GPU tests' command line with the nvproxy ioctl sniffer.

This has multiple functions:

- Verifying that the application does not call ioctls unsupported by
  nvproxy. This is controlled by a `AllowIncompatibleIoctl` option, which
  is initially set to `true` in all tests to mirror current behavior, but
  should be flipped as we verify that they do not call unsupported ioctls.
- Verifying that the sniffer itself works transparently for a wide range
  of applications.
- Later down the line, enforcing that the application only calls ioctls
  that are part of GPU capabilities that it has a need for. This is
  controlled by a capability string which is currently only used to set
  the `NVIDIA_DRIVER_CAPABILITIES` environment variable.

Updates issue #10856

PiperOrigin-RevId: 672714520
2024-09-09 16:34:19 -07:00

71 lines
2.2 KiB
Go

// Copyright 2024 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package sniffer_test tests the ioctl_sniffer against simple cuda workloads.
package sniffer_test
import (
"context"
"errors"
"fmt"
"strings"
"testing"
"time"
"gvisor.dev/gvisor/pkg/test/dockerutil"
)
const maxDuration = 1 * time.Minute
// runCUDATestsCommand runs the given command via the sniffer with compatibility
// enforcement enabled.
// It's run in a docker container, with the cuda-tests image.
func runCUDATestsCommand(t *testing.T, cmd ...string) (string, error) {
ctx, cancel := context.WithTimeoutCause(context.Background(), maxDuration, errors.New("overall test timed out"))
defer cancel()
container := dockerutil.MakeContainer(ctx, t)
defer container.CleanUp(ctx)
opts, err := dockerutil.GPURunOpts(dockerutil.SniffGPUOpts{
AllowIncompatibleIoctl: false,
})
if err != nil {
return "", fmt.Errorf("failed to get GPU run options: %w", err)
}
opts.Image = "gpu/cuda-tests"
return container.Run(ctx, opts, cmd...)
}
func TestSupportedCUDAProgram(t *testing.T) {
output, err := runCUDATestsCommand(t, "/run_smoke.sh")
t.Logf("%s", output)
if err != nil {
t.Logf("Error: %v", err)
if strings.Contains(output, "unsupported ioctls found") {
t.Fatalf("'unsupported ioctls found' found in output")
}
t.Fatalf("Failed to run run_smoke.sh")
}
}
func TestUnsupportedCUDAProgram(t *testing.T) {
output, err := runCUDATestsCommand(t, "/unsupported_ioctl")
t.Logf("%s", output)
if err == nil {
t.Fatalf("Expected run_sniffer to fail")
}
if !strings.Contains(output, "unsupported ioctls found") {
t.Fatalf("Expected to find 'unsupported ioctls found' in output")
}
}