mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-12 13:31:52 +00:00
kubelet: DRA: add unit test for ClaimInfo and claimInfoCache
This commit is contained in:
parent
6ce294558a
commit
f24134d7b2
@ -102,6 +102,10 @@ func (info *ClaimInfo) setCDIDevices(pluginName string, cdiDevices []string) err
|
||||
info.CDIDevices = make(map[string][]string)
|
||||
}
|
||||
|
||||
if info.annotations == nil {
|
||||
info.annotations = make(map[string][]kubecontainer.Annotation)
|
||||
}
|
||||
|
||||
info.CDIDevices[pluginName] = cdiDevices
|
||||
info.annotations[pluginName] = annotations
|
||||
|
||||
|
894
pkg/kubelet/cm/dra/claiminfo_test.go
Normal file
894
pkg/kubelet/cm/dra/claiminfo_test.go
Normal file
@ -0,0 +1,894 @@
|
||||
/*
|
||||
Copyright 2024 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 dra
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
resourcev1alpha2 "k8s.io/api/resource/v1alpha2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm/dra/state"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
)
|
||||
|
||||
// ClaimInfo test cases
|
||||
|
||||
func TestNewClaimInfoFromClaim(t *testing.T) {
|
||||
namespace := "test-namespace"
|
||||
className := "test-class"
|
||||
driverName := "test-plugin"
|
||||
claimUID := types.UID("claim-uid")
|
||||
claimName := "test-claim"
|
||||
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claim *resourcev1alpha2.ResourceClaim
|
||||
expectedResult *ClaimInfo
|
||||
}{
|
||||
{
|
||||
description: "successfully created object",
|
||||
claim: &resourcev1alpha2.ResourceClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
UID: claimUID,
|
||||
Name: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Status: resourcev1alpha2.ResourceClaimStatus{
|
||||
DriverName: driverName,
|
||||
Allocation: &resourcev1alpha2.AllocationResult{
|
||||
ResourceHandles: []resourcev1alpha2.ResourceHandle{},
|
||||
},
|
||||
},
|
||||
Spec: resourcev1alpha2.ResourceClaimSpec{
|
||||
ResourceClassName: className,
|
||||
},
|
||||
},
|
||||
expectedResult: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
DriverName: driverName,
|
||||
ClassName: className,
|
||||
ClaimUID: claimUID,
|
||||
ClaimName: claimName,
|
||||
Namespace: claimName,
|
||||
PodUIDs: sets.New[string](),
|
||||
ResourceHandles: []resourcev1alpha2.ResourceHandle{
|
||||
{},
|
||||
},
|
||||
CDIDevices: make(map[string][]string),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "successfully created object with empty allocation",
|
||||
claim: &resourcev1alpha2.ResourceClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
UID: claimUID,
|
||||
Name: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Status: resourcev1alpha2.ResourceClaimStatus{
|
||||
DriverName: driverName,
|
||||
Allocation: &resourcev1alpha2.AllocationResult{},
|
||||
},
|
||||
Spec: resourcev1alpha2.ResourceClaimSpec{
|
||||
ResourceClassName: className,
|
||||
},
|
||||
},
|
||||
expectedResult: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
DriverName: driverName,
|
||||
ClassName: className,
|
||||
ClaimUID: claimUID,
|
||||
ClaimName: claimName,
|
||||
Namespace: claimName,
|
||||
PodUIDs: sets.New[string](),
|
||||
ResourceHandles: []resourcev1alpha2.ResourceHandle{
|
||||
{},
|
||||
},
|
||||
CDIDevices: make(map[string][]string),
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result := newClaimInfoFromClaim(test.claim)
|
||||
if reflect.DeepEqual(result, test.expectedResult) {
|
||||
t.Errorf("Expected %v, but got %v", test.expectedResult, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewClaimInfoFromState(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
state *state.ClaimInfoState
|
||||
expectedResult *ClaimInfo
|
||||
}{
|
||||
{
|
||||
description: "successfully created object",
|
||||
state: &state.ClaimInfoState{
|
||||
DriverName: "test-driver",
|
||||
ClassName: "test-class",
|
||||
ClaimUID: "test-uid",
|
||||
ClaimName: "test-claim",
|
||||
Namespace: "test-namespace",
|
||||
PodUIDs: sets.New[string]("test-pod-uid"),
|
||||
ResourceHandles: []resourcev1alpha2.ResourceHandle{},
|
||||
CDIDevices: map[string][]string{},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result := newClaimInfoFromState(test.state)
|
||||
if reflect.DeepEqual(result, test.expectedResult) {
|
||||
t.Errorf("Expected %v, but got %v", test.expectedResult, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoSetCDIDevices(t *testing.T) {
|
||||
claimUID := types.UID("claim-uid")
|
||||
pluginName := "test-plugin"
|
||||
device := "vendor.com/device=device1"
|
||||
annotationName := fmt.Sprintf("cdi.k8s.io/%s_%s", pluginName, claimUID)
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
devices []string
|
||||
expectedCDIDevices map[string][]string
|
||||
expectedAnnotations map[string][]kubecontainer.Annotation
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "successfully add one device",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
DriverName: pluginName,
|
||||
ClaimUID: claimUID,
|
||||
},
|
||||
},
|
||||
devices: []string{device},
|
||||
expectedCDIDevices: map[string][]string{
|
||||
pluginName: {device},
|
||||
},
|
||||
expectedAnnotations: map[string][]kubecontainer.Annotation{
|
||||
pluginName: {
|
||||
{
|
||||
Name: annotationName,
|
||||
Value: device,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "empty list of devices",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
DriverName: pluginName,
|
||||
ClaimUID: claimUID,
|
||||
},
|
||||
},
|
||||
devices: []string{},
|
||||
expectedCDIDevices: map[string][]string{pluginName: {}},
|
||||
expectedAnnotations: map[string][]kubecontainer.Annotation{pluginName: nil},
|
||||
},
|
||||
{
|
||||
description: "incorrect device format",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
DriverName: pluginName,
|
||||
ClaimUID: claimUID,
|
||||
},
|
||||
},
|
||||
devices: []string{"incorrect"},
|
||||
wantErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
err := test.claimInfo.setCDIDevices(pluginName, test.devices)
|
||||
if test.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.expectedCDIDevices, test.claimInfo.CDIDevices)
|
||||
assert.Equal(t, test.expectedAnnotations, test.claimInfo.annotations)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoAnnotationsAsList(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
expectedResult []kubecontainer.Annotation
|
||||
}{
|
||||
{
|
||||
description: "empty annotations",
|
||||
claimInfo: &ClaimInfo{
|
||||
annotations: map[string][]kubecontainer.Annotation{},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "nil annotations",
|
||||
claimInfo: &ClaimInfo{},
|
||||
},
|
||||
{
|
||||
description: "valid annotations",
|
||||
claimInfo: &ClaimInfo{
|
||||
annotations: map[string][]kubecontainer.Annotation{
|
||||
"test-plugin1": {
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin1_claim-uid1",
|
||||
Value: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin1_claim-uid2",
|
||||
Value: "vendor.com/device=device2",
|
||||
},
|
||||
},
|
||||
"test-plugin2": {
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin2_claim-uid1",
|
||||
Value: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin2_claim-uid2",
|
||||
Value: "vendor.com/device=device2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: []kubecontainer.Annotation{
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin1_claim-uid1",
|
||||
Value: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin1_claim-uid2",
|
||||
Value: "vendor.com/device=device2",
|
||||
},
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin2_claim-uid1",
|
||||
Value: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "cdi.k8s.io/test-plugin2_claim-uid2",
|
||||
Value: "vendor.com/device=device2",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result := test.claimInfo.annotationsAsList()
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].Name < result[j].Name
|
||||
})
|
||||
assert.Equal(t, test.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCDIdevicesAsList(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
expectedResult []kubecontainer.CDIDevice
|
||||
}{
|
||||
{
|
||||
description: "empty CDI devices",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
CDIDevices: map[string][]string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "nil CDI devices",
|
||||
claimInfo: &ClaimInfo{},
|
||||
},
|
||||
{
|
||||
description: "valid CDI devices",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
CDIDevices: map[string][]string{
|
||||
"test-plugin1": {
|
||||
"vendor.com/device=device1",
|
||||
"vendor.com/device=device2",
|
||||
},
|
||||
"test-plugin2": {
|
||||
"vendor.com/device=device1",
|
||||
"vendor.com/device=device2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: []kubecontainer.CDIDevice{
|
||||
{
|
||||
Name: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "vendor.com/device=device1",
|
||||
},
|
||||
{
|
||||
Name: "vendor.com/device=device2",
|
||||
},
|
||||
{
|
||||
Name: "vendor.com/device=device2",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result := test.claimInfo.cdiDevicesAsList()
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].Name < result[j].Name
|
||||
})
|
||||
assert.Equal(t, test.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestClaimInfoAddPodReference(t *testing.T) {
|
||||
podUID := types.UID("pod-uid")
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
expectedLen int
|
||||
}{
|
||||
{
|
||||
description: "successfully add pod reference",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](),
|
||||
},
|
||||
},
|
||||
expectedLen: 1,
|
||||
},
|
||||
{
|
||||
description: "duplicate pod reference",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](string(podUID)),
|
||||
},
|
||||
},
|
||||
expectedLen: 1,
|
||||
},
|
||||
{
|
||||
description: "duplicate pod reference",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string]("pod-uid1"),
|
||||
},
|
||||
},
|
||||
expectedLen: 2,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
test.claimInfo.addPodReference(podUID)
|
||||
assert.True(t, test.claimInfo.hasPodReference(podUID))
|
||||
assert.Len(t, test.claimInfo.PodUIDs, test.expectedLen)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoHasPodReference(t *testing.T) {
|
||||
podUID := types.UID("pod-uid")
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
description: "claim doesn't reference pod",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "claim references pod",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](string(podUID)),
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
description: "empty claim info",
|
||||
claimInfo: &ClaimInfo{},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
assert.Equal(t, test.claimInfo.hasPodReference(podUID), test.expectedResult)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoDeletePodReference(t *testing.T) {
|
||||
podUID := types.UID("pod-uid")
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
}{
|
||||
{
|
||||
description: "claim doesn't reference pod",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "claim references pod",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
PodUIDs: sets.New[string](string(podUID)),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "empty claim info",
|
||||
claimInfo: &ClaimInfo{},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
test.claimInfo.deletePodReference(podUID)
|
||||
assert.False(t, test.claimInfo.hasPodReference(podUID))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoSetPrepared(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
}{
|
||||
{
|
||||
description: "claim info is not prepared",
|
||||
claimInfo: &ClaimInfo{
|
||||
prepared: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "claim info is prepared",
|
||||
claimInfo: &ClaimInfo{
|
||||
prepared: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "empty claim info",
|
||||
claimInfo: &ClaimInfo{},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
test.claimInfo.setPrepared()
|
||||
assert.Equal(t, test.claimInfo.isPrepared(), true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoIsPrepared(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
description: "claim info is not prepared",
|
||||
claimInfo: &ClaimInfo{
|
||||
prepared: false,
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
description: "claim info is prepared",
|
||||
claimInfo: &ClaimInfo{
|
||||
prepared: true,
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
description: "empty claim info",
|
||||
claimInfo: &ClaimInfo{},
|
||||
expectedResult: false,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
assert.Equal(t, test.claimInfo.isPrepared(), test.expectedResult)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// claimInfoCache test cases
|
||||
func TestNewClaimInfoCache(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
stateDir string
|
||||
checkpointName string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "successfully created cache",
|
||||
stateDir: t.TempDir(),
|
||||
checkpointName: "test-checkpoint",
|
||||
},
|
||||
{
|
||||
description: "empty parameters",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
description: "empty checkpoint name",
|
||||
stateDir: t.TempDir(),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
description: "incorrect checkpoint name",
|
||||
stateDir: path.Join(t.TempDir(), "incorrect checkpoint"),
|
||||
wantErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result, err := newClaimInfoCache(test.stateDir, test.checkpointName)
|
||||
if test.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheWithLock(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
funcGen func(cache *claimInfoCache) func() error
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "cache is locked inside a function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
if cache.RWMutex.TryLock() {
|
||||
return errors.New("Lock succeeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "cache is Rlocked inside a function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
if cache.RWMutex.TryRLock() {
|
||||
return errors.New("RLock succeeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "successfully called function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "erroring function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
return errors.New("test error")
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cache)
|
||||
err = cache.withLock(test.funcGen(cache))
|
||||
if test.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheWithRLock(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
funcGen func(cache *claimInfoCache) func() error
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "RLock-ed cache allows another RLock",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
if !cache.RWMutex.TryRLock() {
|
||||
return errors.New("RLock failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "cache is locked inside a function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
if cache.RWMutex.TryLock() {
|
||||
return errors.New("Lock succeeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "successfully called function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "erroring function",
|
||||
funcGen: func(cache *claimInfoCache) func() error {
|
||||
return func() error {
|
||||
return errors.New("test error")
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cache)
|
||||
err = cache.withRLock(test.funcGen(cache))
|
||||
if test.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheAdd(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
}{
|
||||
{
|
||||
description: "claimInfo successfully added",
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: "test-claim",
|
||||
Namespace: "test-namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cache)
|
||||
cache.add(test.claimInfo)
|
||||
assert.True(t, cache.contains(test.claimInfo.ClaimName, test.claimInfo.Namespace))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheContains(t *testing.T) {
|
||||
claimName := "test-claim"
|
||||
namespace := "test-namespace"
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfo *ClaimInfo
|
||||
claimInfoCache *claimInfoCache
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
description: "cache hit",
|
||||
claimInfoCache: &claimInfoCache{
|
||||
claimInfo: map[string]*ClaimInfo{
|
||||
namespace + "/" + claimName: {
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
description: "cache miss",
|
||||
claimInfoCache: &claimInfoCache{},
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "cache miss: empty cache and empty claim info",
|
||||
claimInfoCache: &claimInfoCache{},
|
||||
claimInfo: &ClaimInfo{
|
||||
ClaimInfoState: state.ClaimInfoState{},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
assert.Equal(t, test.expectedResult, test.claimInfoCache.contains(test.claimInfo.ClaimName, test.claimInfo.Namespace))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheGet(t *testing.T) {
|
||||
claimName := "test-claim"
|
||||
namespace := "test-namespace"
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfoCache *claimInfoCache
|
||||
expectedNil bool
|
||||
expectedExists bool
|
||||
}{
|
||||
{
|
||||
description: "cache hit",
|
||||
claimInfoCache: &claimInfoCache{
|
||||
claimInfo: map[string]*ClaimInfo{
|
||||
namespace + "/" + claimName: {
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedExists: true,
|
||||
},
|
||||
{
|
||||
description: "cache miss",
|
||||
claimInfoCache: &claimInfoCache{},
|
||||
expectedNil: true,
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
result, exists := test.claimInfoCache.get(claimName, namespace)
|
||||
assert.Equal(t, test.expectedExists, exists)
|
||||
assert.Equal(t, test.expectedNil, result == nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheDelete(t *testing.T) {
|
||||
claimName := "test-claim"
|
||||
namespace := "test-namespace"
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfoCache *claimInfoCache
|
||||
}{
|
||||
{
|
||||
description: "item in cache",
|
||||
claimInfoCache: &claimInfoCache{
|
||||
claimInfo: map[string]*ClaimInfo{
|
||||
claimName + namespace: {
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "item not in cache",
|
||||
claimInfoCache: &claimInfoCache{},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
test.claimInfoCache.delete(claimName, namespace)
|
||||
assert.False(t, test.claimInfoCache.contains(claimName, namespace))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimInfoCacheHasPodReference(t *testing.T) {
|
||||
claimName := "test-claim"
|
||||
namespace := "test-namespace"
|
||||
uid := types.UID("test-uid")
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
claimInfoCache *claimInfoCache
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
description: "uid is referenced",
|
||||
claimInfoCache: &claimInfoCache{
|
||||
claimInfo: map[string]*ClaimInfo{
|
||||
claimName + namespace: {
|
||||
ClaimInfoState: state.ClaimInfoState{
|
||||
ClaimName: claimName,
|
||||
Namespace: namespace,
|
||||
PodUIDs: sets.New[string](string(uid)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
description: "uid is not referenced",
|
||||
claimInfoCache: &claimInfoCache{},
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
assert.Equal(t, test.expectedResult, test.claimInfoCache.hasPodReference(uid))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncToCheckpoint(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
stateDir string
|
||||
checkpointName string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
description: "successfully checkpointed cache",
|
||||
stateDir: t.TempDir(),
|
||||
checkpointName: "test-checkpoint",
|
||||
},
|
||||
} {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
cache, err := newClaimInfoCache(test.stateDir, test.checkpointName)
|
||||
assert.NoError(t, err)
|
||||
err = cache.syncToCheckpoint()
|
||||
if test.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user