Change:
} } } <ins> func TestResourceDeviceInstanceFilter(t *testing.T) { var expected string var cond map[string]sets.String var resp ResourceDeviceInstances devs := ResourceDeviceInstances{ "foo": DeviceInstances{ "dev-foo1": pluginapi.Device{ ID: "foo1", }, "dev-foo2": pluginapi.Device{ ID: "foo2", }, "dev-foo3": pluginapi.Device{ ID: "foo3", }, }, "bar": DeviceInstances{ "dev-bar1": pluginapi.Device{ ID: "bar1", }, "dev-bar2": pluginapi.Device{ ID: "bar2", }, "dev-bar3": pluginapi.Device{ ID: "bar3", }, }, "baz": DeviceInstances{ "dev-baz1": pluginapi.Device{ ID: "baz1", }, "dev-baz2": pluginapi.Device{ ID: "baz2", }, "dev-baz3": pluginapi.Device{ ID: "baz3", }, }, } resp = devs.Filter(map[string]sets.String{}) expected = `{}` expectResourceDeviceInstances(t, resp, expected) cond = map[string]sets.String{ "foo": sets.NewString("dev-foo1", "dev-foo2"), "bar": sets.NewString("dev-bar1"), } resp = devs.Filter(cond) expected = `{"bar":{"dev-bar1":{"ID":"bar1"}},"foo":{"dev-foo1":{"ID":"foo1"},"dev-foo2":{"ID":"foo2"}}}` expectResourceDeviceInstances(t, resp, expected) cond = map[string]sets.String{ "foo": sets.NewString("dev-foo1", "dev-foo2", "dev-foo3"), "bar": sets.NewString("dev-bar1", "dev-bar2", "dev-bar3"), "baz": sets.NewString("dev-baz1", "dev-baz2", "dev-baz3"), } resp = devs.Filter(cond) expected = `{"bar":{"dev-bar1":{"ID":"bar1"},"dev-bar2":{"ID":"bar2"},"dev-bar3":{"ID":"bar3"}},"baz":{"dev-baz1":{"ID":"baz1"},"dev-baz2":{"ID":"baz2"},"dev-baz3":{"ID":"baz3"}},"foo":{"dev-foo1":{"ID":"foo1"},"dev-foo2":{"ID":"foo2"},"dev-foo3":{"ID":"foo3"}}}` expectResourceDeviceInstances(t, resp, expected) cond = map[string]sets.String{ "foo": sets.NewString("dev-foo1", "dev-foo2", "dev-foo3", "dev-foo4"), "bar": sets.NewString("dev-bar1", "dev-bar2", "dev-bar3", "dev-bar4"), "baz": sets.NewString("dev-baz1", "dev-baz2", "dev-baz3", "dev-bar4"), } resp = devs.Filter(cond) expected = `{"bar":{"dev-bar1":{"ID":"bar1"},"dev-bar2":{"ID":"bar2"},"dev-bar3":{"ID":"bar3"}},"baz":{"dev-baz1":{"ID":"baz1"},"dev-baz2":{"ID":"baz2"},"dev-baz3":{"ID":"baz3"}},"foo":{"dev-foo1":{"ID":"foo1"},"dev-foo2":{"ID":"foo2"},"dev-foo3":{"ID":"foo3"}}}` expectResourceDeviceInstances(t, resp, expected) cond = map[string]sets.String{ "foo": sets.NewString("dev-foo1", "dev-foo4", "dev-foo7"), "bar": sets.NewString("dev-bar1", "dev-bar4", "dev-bar7"), "baz": sets.NewString("dev-baz1", "dev-baz4", "dev-baz7"), } resp = devs.Filter(cond) expected = `{"bar":{"dev-bar1":{"ID":"bar1"}},"baz":{"dev-baz1":{"ID":"baz1"}},"foo":{"dev-foo1":{"ID":"foo1"}}}` expectResourceDeviceInstances(t, resp, expected) } func expectResourceDeviceInstances(t *testing.T, resp ResourceDeviceInstances, expected string) { // per docs in https://pkg.go.dev/encoding/json#Marshal // "Map values encode as JSON objects. The map's key type must either be a string, an integer type, or // implement encoding.TextMarshaler. The map keys are sorted [...]" // so this check is expected to be stable and not flaky data, err := json.Marshal(resp) if err != nil { t.Fatalf("unexpected JSON marshalling error: %v", err) } got := string(data) if got != expected { t.Errorf("expected %q got %q", expected, got) } } </ins>

Discussion:
When calling GetAllocatableDevices, the API returns all the registered devices, regardless of their health status. Thing is, the - and in general doesn't make much sense to report as allocatable Unhealthy devices, as is also documented in the (see last paragraph) The API should not report unhealthy device. This means the reported device set can potentially change across multiple invocations of the API, as . a kube = 1.21 environment, enable the feature gate any device plugin - including sample device plugin sure 1+ devices are reported unhealthy the podresources GetAllocatableResources API, observe the unhealthy device is reported in the return value. N/A Kubernetes version (use ): 1.21 and beyond Cloud provider or hardware configuration: not relevant OS (e.g: ): any Kernel (e.g. ): not relevant Install tools: not relevant Network plugin and version (if this is a network-related bug): not relevant Others: not relevant
/sig node
/triage accepted