2017-08-15 21:46:30 +00:00
|
|
|
/*
|
|
|
|
Copyright 2017 The Kubernetes 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.
|
|
|
|
*/
|
|
|
|
|
2017-12-05 18:28:23 +00:00
|
|
|
package devicemanager
|
2017-08-15 21:46:30 +00:00
|
|
|
|
|
|
|
import (
|
2017-08-18 22:17:43 +00:00
|
|
|
"path"
|
2017-08-15 21:46:30 +00:00
|
|
|
"testing"
|
2018-01-29 07:39:57 +00:00
|
|
|
"time"
|
2017-08-15 21:46:30 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2018-02-16 02:12:03 +00:00
|
|
|
pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1"
|
2017-08-15 21:46:30 +00:00
|
|
|
)
|
|
|
|
|
2017-08-18 22:17:43 +00:00
|
|
|
var (
|
|
|
|
esocketName = "mock.sock"
|
2017-08-15 21:46:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestNewEndpoint(t *testing.T) {
|
2017-08-22 22:03:47 +00:00
|
|
|
socket := path.Join("/tmp", esocketName)
|
2017-08-18 22:17:43 +00:00
|
|
|
|
2017-08-15 21:46:30 +00:00
|
|
|
devs := []*pluginapi.Device{
|
|
|
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
|
|
|
}
|
|
|
|
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
p, e := esetup(t, devs, socket, "mock", func(n string, d []pluginapi.Device) {})
|
2017-08-15 21:46:30 +00:00
|
|
|
defer ecleanup(t, p, e)
|
|
|
|
}
|
|
|
|
|
2017-10-26 08:36:16 +00:00
|
|
|
func TestRun(t *testing.T) {
|
2017-08-22 22:03:47 +00:00
|
|
|
socket := path.Join("/tmp", esocketName)
|
2017-08-18 22:17:43 +00:00
|
|
|
|
2017-08-15 21:46:30 +00:00
|
|
|
devs := []*pluginapi.Device{
|
|
|
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
|
|
|
{ID: "AnotherDeviceId", Health: pluginapi.Healthy},
|
2018-02-06 14:05:48 +00:00
|
|
|
{ID: "AThirdDeviceId", Health: pluginapi.Unhealthy},
|
2017-08-15 21:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updated := []*pluginapi.Device{
|
|
|
|
{ID: "ADeviceId", Health: pluginapi.Unhealthy},
|
|
|
|
{ID: "AThirdDeviceId", Health: pluginapi.Healthy},
|
2018-02-06 14:05:48 +00:00
|
|
|
{ID: "AFourthDeviceId", Health: pluginapi.Healthy},
|
2017-08-15 21:46:30 +00:00
|
|
|
}
|
|
|
|
|
2018-01-12 12:09:07 +00:00
|
|
|
callbackCount := 0
|
|
|
|
callbackChan := make(chan int)
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
callback := func(n string, devices []pluginapi.Device) {
|
2018-01-12 12:09:07 +00:00
|
|
|
// Should be called twice:
|
|
|
|
// one for plugin registration, one for plugin update.
|
|
|
|
if callbackCount > 2 {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check plugin registration
|
|
|
|
if callbackCount == 0 {
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
require.Len(t, devices, 3)
|
|
|
|
require.Equal(t, devices[0].ID, devs[0].ID)
|
|
|
|
require.Equal(t, devices[1].ID, devs[1].ID)
|
|
|
|
require.Equal(t, devices[2].ID, devs[2].ID)
|
|
|
|
require.Equal(t, devices[0].Health, devs[0].Health)
|
|
|
|
require.Equal(t, devices[1].Health, devs[1].Health)
|
|
|
|
require.Equal(t, devices[2].Health, devs[2].Health)
|
2018-01-12 12:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check plugin update
|
|
|
|
if callbackCount == 1 {
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
require.Len(t, devices, 3)
|
|
|
|
require.Equal(t, devices[0].ID, updated[0].ID)
|
|
|
|
require.Equal(t, devices[1].ID, updated[1].ID)
|
|
|
|
require.Equal(t, devices[2].ID, updated[2].ID)
|
|
|
|
require.Equal(t, devices[0].Health, updated[0].Health)
|
|
|
|
require.Equal(t, devices[1].Health, updated[1].Health)
|
|
|
|
require.Equal(t, devices[2].Health, updated[2].Health)
|
2018-01-12 12:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
callbackCount++
|
|
|
|
callbackChan <- callbackCount
|
|
|
|
}
|
2017-08-15 21:46:30 +00:00
|
|
|
|
2018-01-12 12:09:07 +00:00
|
|
|
p, e := esetup(t, devs, socket, "mock", callback)
|
2017-08-15 21:46:30 +00:00
|
|
|
defer ecleanup(t, p, e)
|
|
|
|
|
2017-10-26 08:36:16 +00:00
|
|
|
go e.run()
|
2018-01-12 12:09:07 +00:00
|
|
|
// Wait for the first callback to be issued.
|
2018-01-12 21:47:49 +00:00
|
|
|
<-callbackChan
|
2018-01-12 12:09:07 +00:00
|
|
|
|
2017-08-15 21:46:30 +00:00
|
|
|
p.Update(updated)
|
2018-01-12 12:09:07 +00:00
|
|
|
|
|
|
|
// Wait for the second callback to be issued.
|
2018-01-12 21:47:49 +00:00
|
|
|
<-callbackChan
|
2017-08-15 21:46:30 +00:00
|
|
|
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
require.Equal(t, callbackCount, 2)
|
2017-08-15 21:46:30 +00:00
|
|
|
}
|
|
|
|
|
2018-01-29 07:39:57 +00:00
|
|
|
func TestAllocate(t *testing.T) {
|
|
|
|
socket := path.Join("/tmp", esocketName)
|
|
|
|
devs := []*pluginapi.Device{
|
|
|
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
|
|
|
}
|
|
|
|
callbackCount := 0
|
|
|
|
callbackChan := make(chan int)
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
p, e := esetup(t, devs, socket, "mock", func(n string, d []pluginapi.Device) {
|
2018-01-29 07:39:57 +00:00
|
|
|
callbackCount++
|
|
|
|
callbackChan <- callbackCount
|
|
|
|
})
|
|
|
|
defer ecleanup(t, p, e)
|
|
|
|
|
|
|
|
resp := new(pluginapi.AllocateResponse)
|
2018-02-23 18:54:43 +00:00
|
|
|
contResp := new(pluginapi.ContainerAllocateResponse)
|
|
|
|
contResp.Devices = append(contResp.Devices, &pluginapi.DeviceSpec{
|
2018-01-29 07:39:57 +00:00
|
|
|
ContainerPath: "/dev/aaa",
|
|
|
|
HostPath: "/dev/aaa",
|
|
|
|
Permissions: "mrw",
|
|
|
|
})
|
|
|
|
|
2018-02-23 18:54:43 +00:00
|
|
|
contResp.Devices = append(contResp.Devices, &pluginapi.DeviceSpec{
|
2018-01-29 07:39:57 +00:00
|
|
|
ContainerPath: "/dev/bbb",
|
|
|
|
HostPath: "/dev/bbb",
|
|
|
|
Permissions: "mrw",
|
|
|
|
})
|
|
|
|
|
2018-02-23 18:54:43 +00:00
|
|
|
contResp.Mounts = append(contResp.Mounts, &pluginapi.Mount{
|
2018-01-29 07:39:57 +00:00
|
|
|
ContainerPath: "/container_dir1/file1",
|
|
|
|
HostPath: "host_dir1/file1",
|
|
|
|
ReadOnly: true,
|
|
|
|
})
|
|
|
|
|
2018-02-23 18:54:43 +00:00
|
|
|
resp.ContainerResponses = append(resp.ContainerResponses, contResp)
|
|
|
|
|
2018-01-29 07:39:57 +00:00
|
|
|
p.SetAllocFunc(func(r *pluginapi.AllocateRequest, devs map[string]pluginapi.Device) (*pluginapi.AllocateResponse, error) {
|
|
|
|
return resp, nil
|
|
|
|
})
|
|
|
|
|
|
|
|
go e.run()
|
|
|
|
// Wait for the callback to be issued.
|
|
|
|
select {
|
|
|
|
case <-callbackChan:
|
|
|
|
break
|
|
|
|
case <-time.After(time.Second):
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
respOut, err := e.allocate([]string{"ADeviceId"})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, resp, respOut)
|
|
|
|
}
|
|
|
|
|
2017-11-14 21:06:07 +00:00
|
|
|
func esetup(t *testing.T, devs []*pluginapi.Device, socket, resourceName string, callback monitorCallback) (*Stub, *endpointImpl) {
|
2018-01-24 17:06:07 +00:00
|
|
|
p := NewDevicePluginStub(devs, socket, resourceName, false)
|
2017-08-15 21:46:30 +00:00
|
|
|
|
|
|
|
err := p.Start()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
While reviewing devicemanager code, found
the caching layer on endpoint is redundant.
Here are the 3 related objects in picture:
devicemanager <-> endpoint <-> plugin
Plugin is the source of truth for devices
and device health status.
devicemanager maintain healthyDevices,
unhealthyDevices, allocatedDevices based on updates
from plugin.
So there is no point for endpoint caching devices,
this patch is removing this caching layer on endpoint,
Also removing the Manager.Devices() since i didn't
find any caller of this other than test, i am adding a
notification channel to facilitate testing,
If we need to get all devices from manager in future,
it just need to return healthyDevices + unhealthyDevices,
we don't have to call endpoint after all.
This patch makes code more readable, data model been simplified.
2018-07-30 00:50:18 +00:00
|
|
|
e, err := newEndpointImpl(socket, resourceName, callback)
|
2017-08-15 21:46:30 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
return p, e
|
|
|
|
}
|
|
|
|
|
2017-11-14 21:06:07 +00:00
|
|
|
func ecleanup(t *testing.T, p *Stub, e *endpointImpl) {
|
2017-08-15 21:46:30 +00:00
|
|
|
p.Stop()
|
|
|
|
e.stop()
|
|
|
|
}
|