mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Testing
This commit is contained in:
parent
c4a1c97329
commit
f7f4515e43
@ -5,6 +5,7 @@ licenses(["notice"])
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
@ -12,6 +13,7 @@ go_library(
|
||||
srcs = [
|
||||
"endpoint.go",
|
||||
"manager.go",
|
||||
"mock_device_plugin.go",
|
||||
"types.go",
|
||||
"utils.go",
|
||||
],
|
||||
@ -36,3 +38,17 @@ filegroup(
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"endpoint_test.go",
|
||||
"manager_test.go",
|
||||
"utils_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/kubelet/apis/deviceplugin/v1alpha1:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
125
pkg/kubelet/deviceplugin/endpoint_test.go
Normal file
125
pkg/kubelet/deviceplugin/endpoint_test.go
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package deviceplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
socket = "/tmp/mock.sock"
|
||||
)
|
||||
|
||||
func TestNewEndpoint(t *testing.T) {
|
||||
devs := []*pluginapi.Device{
|
||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
p, e := esetup(t, devs, socket, "mock", func(n string, a, u, r []*pluginapi.Device) {})
|
||||
defer ecleanup(t, p, e)
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
devs := []*pluginapi.Device{
|
||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
p, e := esetup(t, devs, socket, "mock", func(n string, a, u, r []*pluginapi.Device) {})
|
||||
defer ecleanup(t, p, e)
|
||||
|
||||
_, err := e.list()
|
||||
require.NoError(t, err)
|
||||
|
||||
e.mutex.Lock()
|
||||
defer e.mutex.Unlock()
|
||||
|
||||
require.Len(t, e.devices, 1)
|
||||
|
||||
d, ok := e.devices[devs[0].ID]
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, d.ID, devs[0].ID)
|
||||
require.Equal(t, d.Health, devs[0].Health)
|
||||
}
|
||||
|
||||
func TestListAndWatch(t *testing.T) {
|
||||
devs := []*pluginapi.Device{
|
||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||
{ID: "AnotherDeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
updated := []*pluginapi.Device{
|
||||
{ID: "ADeviceId", Health: pluginapi.Unhealthy},
|
||||
{ID: "AThirdDeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
p, e := esetup(t, devs, socket, "mock", func(n string, a, u, r []*pluginapi.Device) {
|
||||
require.Len(t, a, 1)
|
||||
require.Len(t, u, 1)
|
||||
require.Len(t, r, 1)
|
||||
|
||||
require.Equal(t, a[0].ID, updated[1].ID)
|
||||
|
||||
require.Equal(t, u[0].ID, updated[0].ID)
|
||||
require.Equal(t, u[0].Health, updated[0].Health)
|
||||
|
||||
require.Equal(t, r[0].ID, devs[1].ID)
|
||||
})
|
||||
defer ecleanup(t, p, e)
|
||||
|
||||
s, err := e.list()
|
||||
require.NoError(t, err)
|
||||
|
||||
go e.listAndWatch(s)
|
||||
p.Update(updated)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
e.mutex.Lock()
|
||||
defer e.mutex.Unlock()
|
||||
|
||||
require.Len(t, e.devices, 2)
|
||||
for _, dref := range updated {
|
||||
d, ok := e.devices[dref.ID]
|
||||
|
||||
require.True(t, ok)
|
||||
require.Equal(t, d.ID, dref.ID)
|
||||
require.Equal(t, d.Health, dref.Health)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func esetup(t *testing.T, devs []*pluginapi.Device, socket, resourceName string, callback MonitorCallback) (*MockDevicePlugin, *endpoint) {
|
||||
p := NewMockDevicePlugin(devs, socket)
|
||||
|
||||
err := p.Start()
|
||||
require.NoError(t, err)
|
||||
|
||||
e, err := newEndpoint(socket, "mock", func(n string, a, u, r []*pluginapi.Device) {})
|
||||
require.NoError(t, err)
|
||||
|
||||
return p, e
|
||||
}
|
||||
|
||||
func ecleanup(t *testing.T, p *MockDevicePlugin, e *endpoint) {
|
||||
p.Stop()
|
||||
e.stop()
|
||||
}
|
58
pkg/kubelet/deviceplugin/manager_test.go
Normal file
58
pkg/kubelet/deviceplugin/manager_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package deviceplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
msocket = "/tmp/server.sock"
|
||||
)
|
||||
|
||||
func TestNewManagerImpl(t *testing.T) {
|
||||
_, err := NewManagerImpl("", func(n string, a, u, r []*pluginapi.Device) {})
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = NewManagerImpl(msocket, func(n string, a, u, r []*pluginapi.Device) {})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNewManagerImplStart(t *testing.T) {
|
||||
_, err := NewManagerImpl(msocket, func(n string, a, u, r []*pluginapi.Device) {})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func setup(t *testing.T, devs []*pluginapi.Device, pluginSocket, serverSocket string, callback MonitorCallback) (Manager, *MockDevicePlugin) {
|
||||
m, err := NewManagerImpl(serverSocket, callback)
|
||||
require.NoError(t, err)
|
||||
|
||||
p := NewMockDevicePlugin(devs, pluginSocket)
|
||||
err = p.Start()
|
||||
require.NoError(t, err)
|
||||
|
||||
return m, p
|
||||
}
|
||||
|
||||
func cleanup(t *testing.T, m Manager, p *MockDevicePlugin) {
|
||||
p.Stop()
|
||||
m.Stop()
|
||||
}
|
123
pkg/kubelet/deviceplugin/mock_device_plugin.go
Normal file
123
pkg/kubelet/deviceplugin/mock_device_plugin.go
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package deviceplugin
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
|
||||
)
|
||||
|
||||
// MockDevicePlugin is a mock device plugin
|
||||
type MockDevicePlugin struct {
|
||||
devs []*pluginapi.Device
|
||||
socket string
|
||||
|
||||
stop chan interface{}
|
||||
update chan []*pluginapi.Device
|
||||
|
||||
server *grpc.Server
|
||||
}
|
||||
|
||||
// NewMockDevicePlugin returns an initialized MockDevicePlugin
|
||||
func NewMockDevicePlugin(devs []*pluginapi.Device, socket string) *MockDevicePlugin {
|
||||
return &MockDevicePlugin{
|
||||
devs: devs,
|
||||
socket: socket,
|
||||
|
||||
stop: make(chan interface{}),
|
||||
update: make(chan []*pluginapi.Device),
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the gRPC server of the device plugin
|
||||
func (m *MockDevicePlugin) Start() error {
|
||||
err := m.cleanup()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sock, err := net.Listen("unix", m.socket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.server = grpc.NewServer([]grpc.ServerOption{}...)
|
||||
pluginapi.RegisterDevicePluginServer(m.server, m)
|
||||
|
||||
go m.server.Serve(sock)
|
||||
log.Println("Starting to serve on", m.socket)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops the gRPC server
|
||||
func (m *MockDevicePlugin) Stop() error {
|
||||
m.server.Stop()
|
||||
|
||||
return m.cleanup()
|
||||
}
|
||||
|
||||
// ListAndWatch lists devices and update that list according to the Update call
|
||||
func (m *MockDevicePlugin) ListAndWatch(e *pluginapi.Empty, s pluginapi.DevicePlugin_ListAndWatchServer) error {
|
||||
log.Println("ListAndWatch")
|
||||
var devs []*pluginapi.Device
|
||||
|
||||
for _, d := range m.devs {
|
||||
devs = append(devs, &pluginapi.Device{
|
||||
ID: d.ID,
|
||||
Health: pluginapi.Healthy,
|
||||
})
|
||||
}
|
||||
|
||||
s.Send(&pluginapi.ListAndWatchResponse{Devices: devs})
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-m.stop:
|
||||
return nil
|
||||
case updated := <-m.update:
|
||||
s.Send(&pluginapi.ListAndWatchResponse{Devices: updated})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update allows the device plugin to send new devices through ListAndWatch
|
||||
func (m *MockDevicePlugin) Update(devs []*pluginapi.Device) {
|
||||
m.update <- devs
|
||||
}
|
||||
|
||||
// Allocate does a mock allocation
|
||||
func (m *MockDevicePlugin) Allocate(ctx context.Context, r *pluginapi.AllocateRequest) (*pluginapi.AllocateResponse, error) {
|
||||
log.Printf("Allocate, %+v", r)
|
||||
|
||||
var response pluginapi.AllocateResponse
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *MockDevicePlugin) cleanup() error {
|
||||
if err := os.Remove(m.socket); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
54
pkg/kubelet/deviceplugin/utils_test.go
Normal file
54
pkg/kubelet/deviceplugin/utils_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package deviceplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
|
||||
)
|
||||
|
||||
func TestCloneDevice(t *testing.T) {
|
||||
d := CloneDevice(&pluginapi.Device{ID: "ADeviceId", Health: pluginapi.Healthy})
|
||||
|
||||
require.Equal(t, d.ID, "ADeviceId")
|
||||
require.Equal(t, d.Health, pluginapi.Healthy)
|
||||
}
|
||||
|
||||
func TestCopyDevices(t *testing.T) {
|
||||
d := map[string]*pluginapi.Device{
|
||||
"ADeviceId": {ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
devs := copyDevices(d)
|
||||
require.Len(t, devs, 1)
|
||||
}
|
||||
|
||||
func TestGetDevice(t *testing.T) {
|
||||
devs := []*pluginapi.Device{
|
||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||
}
|
||||
|
||||
_, ok := GetDevice(&pluginapi.Device{ID: "AnotherDeviceId"}, devs)
|
||||
require.False(t, ok)
|
||||
|
||||
d, ok := GetDevice(&pluginapi.Device{ID: "ADeviceId"}, devs)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, d, devs[0])
|
||||
}
|
Loading…
Reference in New Issue
Block a user