mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
/*
|
|
Copyright 2019 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 framework
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
type fakeData struct {
|
|
data string
|
|
}
|
|
|
|
func (f *fakeData) Clone() StateData {
|
|
copy := &fakeData{
|
|
data: f.data,
|
|
}
|
|
return copy
|
|
}
|
|
|
|
var key StateKey = "fakedata_key"
|
|
|
|
// createCycleStateWithFakeData creates *CycleState with fakeData.
|
|
// The given data is used in stored fakeData.
|
|
func createCycleStateWithFakeData(data string, recordPluginMetrics bool) *CycleState {
|
|
c := NewCycleState()
|
|
c.Write(key, &fakeData{
|
|
data: data,
|
|
})
|
|
c.SetRecordPluginMetrics(recordPluginMetrics)
|
|
return c
|
|
}
|
|
|
|
// isCycleStateEqual returns whether two CycleState, which has fakeData in storage, is equal or not.
|
|
// And if they are not equal, returns message which shows why not equal.
|
|
func isCycleStateEqual(a, b *CycleState) (bool, string) {
|
|
if a == nil && b == nil {
|
|
return true, ""
|
|
}
|
|
if a == nil || b == nil {
|
|
return false, fmt.Sprintf("one CycleState is nil, but another one is not nil. A: %v, B: %v", a, b)
|
|
}
|
|
|
|
if a.recordPluginMetrics != b.recordPluginMetrics {
|
|
return false, fmt.Sprintf("CycleState A and B have a different recordPluginMetrics. A: %v, B: %v", a.recordPluginMetrics, b.recordPluginMetrics)
|
|
}
|
|
|
|
var msg string
|
|
isEqual := true
|
|
countA := 0
|
|
a.storage.Range(func(k, v1 interface{}) bool {
|
|
countA++
|
|
v2, ok := b.storage.Load(k)
|
|
if !ok {
|
|
isEqual = false
|
|
msg = fmt.Sprintf("CycleState B doesn't have the data which CycleState A has. key: %v, data: %v", k, v1)
|
|
return false
|
|
}
|
|
|
|
typed1, ok1 := v1.(*fakeData)
|
|
typed2, ok2 := v2.(*fakeData)
|
|
if !ok1 || !ok2 {
|
|
isEqual = false
|
|
msg = fmt.Sprintf("CycleState has the data which is not type *fakeData.")
|
|
return false
|
|
}
|
|
|
|
if typed1.data != typed2.data {
|
|
isEqual = false
|
|
msg = fmt.Sprintf("CycleState B has a different data on key %v. A: %v, B: %v", k, typed1.data, typed2.data)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
})
|
|
|
|
if !isEqual {
|
|
return false, msg
|
|
}
|
|
|
|
countB := 0
|
|
b.storage.Range(func(k, _ interface{}) bool {
|
|
countB++
|
|
return true
|
|
})
|
|
|
|
if countA != countB {
|
|
return false, fmt.Sprintf("two Cyclestates have different numbers of data. A: %v, B: %v", countA, countB)
|
|
}
|
|
|
|
return true, ""
|
|
}
|
|
|
|
func TestCycleStateClone(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
state *CycleState
|
|
wantClonedState *CycleState
|
|
}{
|
|
{
|
|
name: "clone with recordPluginMetrics true",
|
|
state: createCycleStateWithFakeData("data", true),
|
|
wantClonedState: createCycleStateWithFakeData("data", true),
|
|
},
|
|
{
|
|
name: "clone with recordPluginMetrics false",
|
|
state: createCycleStateWithFakeData("data", false),
|
|
wantClonedState: createCycleStateWithFakeData("data", false),
|
|
},
|
|
{
|
|
name: "clone with nil CycleState",
|
|
state: nil,
|
|
wantClonedState: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
state := tt.state
|
|
stateCopy := state.Clone()
|
|
|
|
if isEqual, msg := isCycleStateEqual(stateCopy, tt.wantClonedState); !isEqual {
|
|
t.Errorf("unexpected cloned state: %v", msg)
|
|
}
|
|
|
|
if state == nil || stateCopy == nil {
|
|
// not need to run the rest check in this case.
|
|
return
|
|
}
|
|
|
|
stateCopy.Write(key, &fakeData{data: "modified"})
|
|
if isEqual, _ := isCycleStateEqual(state, stateCopy); isEqual {
|
|
t.Errorf("the change for a cloned state should not affect the original state.")
|
|
}
|
|
})
|
|
}
|
|
}
|