Add compatibility tests

This commit is contained in:
Klaudiusz Dembler 2018-05-21 14:50:31 +02:00
parent 3d09101b6f
commit de1063bc7d
4 changed files with 100 additions and 20 deletions

View File

@ -44,8 +44,8 @@ type runtimeService interface {
type policyName string type policyName string
// CPUManagerStateFileName is the name file name where cpu manager stores it's state // cpuManagerStateFileName is the name file name where cpu manager stores it's state
const CPUManagerStateFileName = "cpu_manager_state" const cpuManagerStateFileName = "cpu_manager_state"
// Manager interface provides methods for Kubelet to manage pod cpus. // Manager interface provides methods for Kubelet to manage pod cpus.
type Manager interface { type Manager interface {
@ -136,7 +136,7 @@ func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo
policy = NewNonePolicy() policy = NewNonePolicy()
} }
stateImpl, err := state.NewCheckpointState(stateFileDirecory, policy.Name()) stateImpl, err := state.NewCheckpointState(stateFileDirecory, cpuManagerStateFileName, policy.Name())
if err != nil { if err != nil {
return nil, fmt.Errorf("could not initialize checkpoint manager: %v", err) return nil, fmt.Errorf("could not initialize checkpoint manager: %v", err)
} }

View File

@ -27,9 +27,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
) )
// cpuManagerCheckpointName is the name of checkpoint file
const cpuManagerCheckpointName = "cpu_manager_state"
var _ State = &stateCheckpoint{} var _ State = &stateCheckpoint{}
type stateCheckpoint struct { type stateCheckpoint struct {
@ -37,10 +34,11 @@ type stateCheckpoint struct {
policyName string policyName string
cache State cache State
checkpointManager checkpointmanager.CheckpointManager checkpointManager checkpointmanager.CheckpointManager
checkpointName string
} }
// NewCheckpointState creates new State for keeping track of cpu/pod assignment with checkpoint backend // NewCheckpointState creates new State for keeping track of cpu/pod assignment with checkpoint backend
func NewCheckpointState(stateDir string, policyName string) (State, error) { func NewCheckpointState(stateDir, checkpointName, policyName string) (State, error) {
checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir) checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize checkpoint manager: %v", err) return nil, fmt.Errorf("failed to initialize checkpoint manager: %v", err)
@ -49,12 +47,13 @@ func NewCheckpointState(stateDir string, policyName string) (State, error) {
cache: NewMemoryState(), cache: NewMemoryState(),
policyName: policyName, policyName: policyName,
checkpointManager: checkpointManager, checkpointManager: checkpointManager,
checkpointName: checkpointName,
} }
if err := stateCheckpoint.restoreState(); err != nil { if err := stateCheckpoint.restoreState(); err != nil {
return nil, fmt.Errorf("could not restore state from checkpoint: %v\n"+ return nil, fmt.Errorf("could not restore state from checkpoint: %v\n"+
"Please drain this node and delete the CPU manager checkpoint file %q before restarting Kubelet.", "Please drain this node and delete the CPU manager checkpoint file %q before restarting Kubelet.",
err, path.Join(stateDir, cpuManagerCheckpointName)) err, path.Join(stateDir, checkpointName))
} }
return stateCheckpoint, nil return stateCheckpoint, nil
@ -72,7 +71,7 @@ func (sc *stateCheckpoint) restoreState() error {
tmpContainerCPUSet := cpuset.NewCPUSet() tmpContainerCPUSet := cpuset.NewCPUSet()
checkpoint := NewCPUManagerCheckpoint() checkpoint := NewCPUManagerCheckpoint()
if err = sc.checkpointManager.GetCheckpoint(cpuManagerCheckpointName, checkpoint); err != nil { if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpoint); err != nil {
if err == errors.ErrCheckpointNotFound { if err == errors.ErrCheckpointNotFound {
sc.storeState() sc.storeState()
return nil return nil
@ -114,7 +113,7 @@ func (sc *stateCheckpoint) storeState() {
checkpoint.Entries[containerID] = cset.String() checkpoint.Entries[containerID] = cset.String()
} }
err := sc.checkpointManager.CreateCheckpoint(cpuManagerCheckpointName, checkpoint) err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint)
if err != nil { if err != nil {
panic("[cpumanager] could not save checkpoint: " + err.Error()) panic("[cpumanager] could not save checkpoint: " + err.Error())

View File

@ -17,6 +17,7 @@ limitations under the License.
package state package state
import ( import (
"os"
"strings" "strings"
"testing" "testing"
@ -25,7 +26,9 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
) )
const testingDir = "/tmp" const testingCheckpoint = "cpumanager_checkpoint_test"
var testingDir = os.TempDir()
func TestCheckpointStateRestore(t *testing.T) { func TestCheckpointStateRestore(t *testing.T) {
testCases := []struct { testCases := []struct {
@ -146,17 +149,17 @@ func TestCheckpointStateRestore(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
// ensure there is no previous checkpoint // ensure there is no previous checkpoint
cpm.RemoveCheckpoint(cpuManagerCheckpointName) cpm.RemoveCheckpoint(testingCheckpoint)
// prepare checkpoint for testing // prepare checkpoint for testing
if strings.TrimSpace(tc.checkpointContent) != "" { if strings.TrimSpace(tc.checkpointContent) != "" {
checkpoint := &testutil.MockCheckpoint{Content: tc.checkpointContent} checkpoint := &testutil.MockCheckpoint{Content: tc.checkpointContent}
if err := cpm.CreateCheckpoint(cpuManagerCheckpointName, checkpoint); err != nil { if err := cpm.CreateCheckpoint(testingCheckpoint, checkpoint); err != nil {
t.Fatalf("could not create testing checkpoint: %v", err) t.Fatalf("could not create testing checkpoint: %v", err)
} }
} }
restoredState, err := NewCheckpointState(testingDir, tc.policyName) restoredState, err := NewCheckpointState(testingDir, testingCheckpoint, tc.policyName)
if err != nil { if err != nil {
if strings.TrimSpace(tc.expectedError) != "" { if strings.TrimSpace(tc.expectedError) != "" {
tc.expectedError = "could not restore state from checkpoint: " + tc.expectedError tc.expectedError = "could not restore state from checkpoint: " + tc.expectedError
@ -201,9 +204,9 @@ func TestCheckpointStateStore(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
// ensure there is no previous checkpoint // ensure there is no previous checkpoint
cpm.RemoveCheckpoint(cpuManagerCheckpointName) cpm.RemoveCheckpoint(testingCheckpoint)
cs1, err := NewCheckpointState(testingDir, "none") cs1, err := NewCheckpointState(testingDir, testingCheckpoint, "none")
if err != nil { if err != nil {
t.Fatalf("could not create testing checkpointState instance: %v", err) t.Fatalf("could not create testing checkpointState instance: %v", err)
} }
@ -213,7 +216,7 @@ func TestCheckpointStateStore(t *testing.T) {
cs1.SetCPUAssignments(tc.expectedState.assignments) cs1.SetCPUAssignments(tc.expectedState.assignments)
// restore checkpoint with previously stored values // restore checkpoint with previously stored values
cs2, err := NewCheckpointState(testingDir, "none") cs2, err := NewCheckpointState(testingDir, testingCheckpoint, "none")
if err != nil { if err != nil {
t.Fatalf("could not create testing checkpointState instance: %v", err) t.Fatalf("could not create testing checkpointState instance: %v", err)
} }
@ -261,9 +264,9 @@ func TestCheckpointStateHelpers(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
// ensure there is no previous checkpoint // ensure there is no previous checkpoint
cpm.RemoveCheckpoint(cpuManagerCheckpointName) cpm.RemoveCheckpoint(testingCheckpoint)
state, err := NewCheckpointState(testingDir, "none") state, err := NewCheckpointState(testingDir, testingCheckpoint, "none")
if err != nil { if err != nil {
t.Fatalf("could not create testing checkpointState instance: %v", err) t.Fatalf("could not create testing checkpointState instance: %v", err)
} }
@ -301,7 +304,7 @@ func TestCheckpointStateClear(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
state, err := NewCheckpointState(testingDir, "none") state, err := NewCheckpointState(testingDir, testingCheckpoint, "none")
if err != nil { if err != nil {
t.Fatalf("could not create testing checkpointState instance: %v", err) t.Fatalf("could not create testing checkpointState instance: %v", err)
} }

View File

@ -0,0 +1,78 @@
/*
Copyright 2018 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 state
import (
"os"
"path"
"testing"
"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
)
const compatibilityTestingCheckpoint = "cpumanager_state_compatibility_test"
var state = &stateMemory{
assignments: ContainerCPUAssignments{
"container1": cpuset.NewCPUSet(4, 5, 6),
"container2": cpuset.NewCPUSet(1, 2, 3),
},
defaultCPUSet: cpuset.NewCPUSet(1, 2, 3),
}
func TestFileToCheckpointCompatibility(t *testing.T) {
statePath := path.Join(testingDir, compatibilityTestingCheckpoint)
// ensure there is no previous state saved at testing path
os.Remove(statePath)
// ensure testing state is removed after testing
defer os.Remove(statePath)
fileState := NewFileState(statePath, "none")
fileState.SetDefaultCPUSet(state.defaultCPUSet)
fileState.SetCPUAssignments(state.assignments)
restoredState, err := NewCheckpointState(testingDir, compatibilityTestingCheckpoint, "none")
if err != nil {
t.Fatalf("could not restore file state: %v", err)
}
AssertStateEqual(t, restoredState, state)
}
func TestCheckpointToFileCompatibility(t *testing.T) {
cpm, err := checkpointmanager.NewCheckpointManager(testingDir)
if err != nil {
t.Fatalf("could not create testing checkpoint manager: %v", err)
}
// ensure there is no previous checkpoint
cpm.RemoveCheckpoint(compatibilityTestingCheckpoint)
// ensure testing checkpoint is removed after testing
defer cpm.RemoveCheckpoint(compatibilityTestingCheckpoint)
checkpointState, err := NewCheckpointState(testingDir, compatibilityTestingCheckpoint, "none")
checkpointState.SetDefaultCPUSet(state.defaultCPUSet)
checkpointState.SetCPUAssignments(state.assignments)
restoredState := NewFileState(path.Join(testingDir, compatibilityTestingCheckpoint), "none")
AssertStateEqual(t, restoredState, state)
}