mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-19 19:01:42 +00:00
98fc01764b
* feat(ecs): thread resourceRequirements GPU count through conv, ContainerDef, AssignContainer and RunSpec * feat(ecs): add GPU placement dimension — InstanceRecord capacity, fits/reserve/release, STRINGSET resource reporting * feat(ecs): agent GPU discovery via nvidia-smi, pinning ledger, device-UUID report-back and DescribeTasks gpuIds * feat(ecs): inject assigned GPU devices into containerd OCI spec via CDI (oci.WithCDIDevices) * test(ecs): add GPU task e2e (nvidia-smi container, gpuIds assertion) to gpu e2e suite * test(gpu): decouple base-AMI requirement from GPU fixture so ECS e2e runs without the ubuntu EC2 image * test(gpu): pick smallest advertised GPU instance type to fit a single host * fix(ecs): preserve pinned GPU UUIDs across STOPPED state change so DescribeTasks reports gpuIds for one-shot tasks
48 lines
1.6 KiB
Go
48 lines
1.6 KiB
Go
package runtime
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// cdiDeviceNames maps a container's pinned GPU UUIDs to CDI device names
|
|
// (nvidia.com/gpu=<uuid>); Run wires the result into oci.WithCDIDevices when
|
|
// non-empty, so this is the injection logic's unit-testable core.
|
|
func TestCDIDeviceNames(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
uuids []string
|
|
want []string
|
|
}{
|
|
{name: "empty", uuids: nil, want: nil},
|
|
{name: "single", uuids: []string{"GPU-aaaaaaaa-1111-2222-3333-444444444444"},
|
|
want: []string{"nvidia.com/gpu=GPU-aaaaaaaa-1111-2222-3333-444444444444"}},
|
|
{name: "multiple preserves order", uuids: []string{"GPU-aaa", "GPU-bbb"},
|
|
want: []string{"nvidia.com/gpu=GPU-aaa", "nvidia.com/gpu=GPU-bbb"}},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := cdiDeviceNames(tc.uuids)
|
|
if !reflect.DeepEqual(got, tc.want) {
|
|
t.Errorf("cdiDeviceNames(%v) = %v, want %v", tc.uuids, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCDISpecOpts_Wiring confirms Run's specOpts list picks up exactly one CDI
|
|
// opt when GPUIDs is non-empty, and none for a non-GPU container — the wiring
|
|
// Run relies on (a live oci.Spec is needed to unit test the opt's effect).
|
|
func TestCDISpecOpts_Wiring(t *testing.T) {
|
|
if opts := cdiSpecOpts(nil); len(opts) != 0 {
|
|
t.Errorf("non-GPU container: want no spec opts, got %d", len(opts))
|
|
}
|
|
opts := cdiSpecOpts([]string{"GPU-aaa", "GPU-bbb"})
|
|
if len(opts) != 1 {
|
|
t.Fatalf("GPU container: want exactly one CDI spec opt, got %d", len(opts))
|
|
}
|
|
if opts[0] == nil {
|
|
t.Error("GPU container: spec opt is nil")
|
|
}
|
|
}
|