package taskrunner import ( "context" "fmt" "testing" "github.com/hashicorp/nomad/ci" "github.com/hashicorp/nomad/client/allocrunner/interfaces" "github.com/hashicorp/nomad/client/devicemanager" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/device" "github.com/hashicorp/nomad/plugins/drivers" "github.com/stretchr/testify/require" ) func TestDeviceHook_CorrectDevice(t *testing.T) { ci.Parallel(t) require := require.New(t) dm := devicemanager.NoopMockManager() l := testlog.HCLogger(t) h := newDeviceHook(dm, l) reqDev := &structs.AllocatedDeviceResource{ Vendor: "foo", Type: "bar", Name: "baz", DeviceIDs: []string{"123"}, } // Build the hook request req := &interfaces.TaskPrestartRequest{ TaskResources: &structs.AllocatedTaskResources{ Devices: []*structs.AllocatedDeviceResource{ reqDev, }, }, } // Setup the device manager to return a response dm.ReserveF = func(d *structs.AllocatedDeviceResource) (*device.ContainerReservation, error) { if d.Vendor != reqDev.Vendor || d.Type != reqDev.Type || d.Name != reqDev.Name || len(d.DeviceIDs) != 1 || d.DeviceIDs[0] != reqDev.DeviceIDs[0] { return nil, fmt.Errorf("unexpected request: %+v", d) } res := &device.ContainerReservation{ Envs: map[string]string{ "123": "456", }, Mounts: []*device.Mount{ { ReadOnly: true, TaskPath: "foo", HostPath: "bar", }, }, Devices: []*device.DeviceSpec{ { TaskPath: "foo", HostPath: "bar", CgroupPerms: "123", }, }, } return res, nil } var resp interfaces.TaskPrestartResponse err := h.Prestart(context.Background(), req, &resp) require.NoError(err) require.NotNil(resp) expEnv := map[string]string{ "123": "456", } require.EqualValues(expEnv, resp.Env) expMounts := []*drivers.MountConfig{ { Readonly: true, TaskPath: "foo", HostPath: "bar", }, } require.EqualValues(expMounts, resp.Mounts) expDevices := []*drivers.DeviceConfig{ { TaskPath: "foo", HostPath: "bar", Permissions: "123", }, } require.EqualValues(expDevices, resp.Devices) } func TestDeviceHook_IncorrectDevice(t *testing.T) { ci.Parallel(t) require := require.New(t) dm := devicemanager.NoopMockManager() l := testlog.HCLogger(t) h := newDeviceHook(dm, l) reqDev := &structs.AllocatedDeviceResource{ Vendor: "foo", Type: "bar", Name: "baz", DeviceIDs: []string{"123"}, } // Build the hook request req := &interfaces.TaskPrestartRequest{ TaskResources: &structs.AllocatedTaskResources{ Devices: []*structs.AllocatedDeviceResource{ reqDev, }, }, } // Setup the device manager to return a response dm.ReserveF = func(d *structs.AllocatedDeviceResource) (*device.ContainerReservation, error) { return nil, fmt.Errorf("bad request") } var resp interfaces.TaskPrestartResponse err := h.Prestart(context.Background(), req, &resp) require.Error(err) }