mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			251 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
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 checkpointmanager
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"sort"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
	"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum"
 | 
						|
	utilstore "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/testing"
 | 
						|
	"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/testing/example_checkpoint_formats/v1"
 | 
						|
)
 | 
						|
 | 
						|
var testStore *utilstore.MemStore
 | 
						|
 | 
						|
type FakeCheckpoint interface {
 | 
						|
	Checkpoint
 | 
						|
	GetData() ([]*PortMapping, bool)
 | 
						|
}
 | 
						|
 | 
						|
// Data contains all types of data that can be stored in the checkpoint.
 | 
						|
type Data struct {
 | 
						|
	PortMappings []*PortMapping `json:"port_mappings,omitempty"`
 | 
						|
	HostNetwork  bool           `json:"host_network,omitempty"`
 | 
						|
}
 | 
						|
 | 
						|
type CheckpointDataV2 struct {
 | 
						|
	PortMappings []*PortMapping `json:"port_mappings,omitempty"`
 | 
						|
	HostNetwork  bool           `json:"host_network,omitempty"`
 | 
						|
	V2Field      string         `json:"v2field"`
 | 
						|
}
 | 
						|
 | 
						|
type protocol string
 | 
						|
 | 
						|
// portMapping is the port mapping configurations of a sandbox.
 | 
						|
type PortMapping struct {
 | 
						|
	// protocol of the port mapping.
 | 
						|
	Protocol *protocol
 | 
						|
	// Port number within the container.
 | 
						|
	ContainerPort *int32
 | 
						|
	// Port number on the host.
 | 
						|
	HostPort *int32
 | 
						|
	// Host ip to expose.
 | 
						|
	HostIP string
 | 
						|
}
 | 
						|
 | 
						|
// CheckpointData is a sample example structure to be used in test cases for checkpointing
 | 
						|
type CheckpointData struct {
 | 
						|
	Version  string
 | 
						|
	Name     string
 | 
						|
	Data     *Data
 | 
						|
	Checksum checksum.Checksum
 | 
						|
}
 | 
						|
 | 
						|
func newFakeCheckpointV1(name string, portMappings []*PortMapping, hostNetwork bool) FakeCheckpoint {
 | 
						|
	return &CheckpointData{
 | 
						|
		Version: "v1",
 | 
						|
		Name:    name,
 | 
						|
		Data: &Data{
 | 
						|
			PortMappings: portMappings,
 | 
						|
			HostNetwork:  hostNetwork,
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (cp *CheckpointData) MarshalCheckpoint() ([]byte, error) {
 | 
						|
	cp.Checksum = checksum.New(*cp.Data)
 | 
						|
	return json.Marshal(*cp)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *CheckpointData) UnmarshalCheckpoint(blob []byte) error {
 | 
						|
	return json.Unmarshal(blob, cp)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *CheckpointData) VerifyChecksum() error {
 | 
						|
	return cp.Checksum.Verify(*cp.Data)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *CheckpointData) GetData() ([]*PortMapping, bool) {
 | 
						|
	return cp.Data.PortMappings, cp.Data.HostNetwork
 | 
						|
}
 | 
						|
 | 
						|
type checkpointDataV2 struct {
 | 
						|
	Version  string
 | 
						|
	Name     string
 | 
						|
	Data     *CheckpointDataV2
 | 
						|
	Checksum checksum.Checksum
 | 
						|
}
 | 
						|
 | 
						|
func newFakeCheckpointV2(name string, portMappings []*PortMapping, hostNetwork bool) FakeCheckpoint {
 | 
						|
	return &checkpointDataV2{
 | 
						|
		Version: "v2",
 | 
						|
		Name:    name,
 | 
						|
		Data: &CheckpointDataV2{
 | 
						|
			PortMappings: portMappings,
 | 
						|
			HostNetwork:  hostNetwork,
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func newFakeCheckpointRemoteV1(name string, portMappings []*v1.PortMapping, hostNetwork bool) Checkpoint {
 | 
						|
	return &v1.CheckpointData{
 | 
						|
		Version: "v1",
 | 
						|
		Name:    name,
 | 
						|
		Data: &v1.Data{
 | 
						|
			PortMappings: portMappings,
 | 
						|
			HostNetwork:  hostNetwork,
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (cp *checkpointDataV2) MarshalCheckpoint() ([]byte, error) {
 | 
						|
	cp.Checksum = checksum.New(*cp.Data)
 | 
						|
	return json.Marshal(*cp)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *checkpointDataV2) UnmarshalCheckpoint(blob []byte) error {
 | 
						|
	return json.Unmarshal(blob, cp)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *checkpointDataV2) VerifyChecksum() error {
 | 
						|
	return cp.Checksum.Verify(*cp.Data)
 | 
						|
}
 | 
						|
 | 
						|
func (cp *checkpointDataV2) GetData() ([]*PortMapping, bool) {
 | 
						|
	return cp.Data.PortMappings, cp.Data.HostNetwork
 | 
						|
}
 | 
						|
 | 
						|
func newTestCheckpointManager() CheckpointManager {
 | 
						|
	return &impl{store: testStore}
 | 
						|
}
 | 
						|
 | 
						|
func TestCheckpointManager(t *testing.T) {
 | 
						|
	var err error
 | 
						|
	testStore = utilstore.NewMemStore()
 | 
						|
	manager := newTestCheckpointManager()
 | 
						|
	port80 := int32(80)
 | 
						|
	port443 := int32(443)
 | 
						|
	proto := protocol("tcp")
 | 
						|
	ip1234 := "1.2.3.4"
 | 
						|
 | 
						|
	portMappings := []*PortMapping{
 | 
						|
		{
 | 
						|
			&proto,
 | 
						|
			&port80,
 | 
						|
			&port80,
 | 
						|
			ip1234,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			&proto,
 | 
						|
			&port443,
 | 
						|
			&port443,
 | 
						|
			ip1234,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	checkpoint1 := newFakeCheckpointV1("check1", portMappings, true)
 | 
						|
 | 
						|
	checkpoints := []struct {
 | 
						|
		checkpointKey     string
 | 
						|
		checkpoint        FakeCheckpoint
 | 
						|
		expectHostNetwork bool
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			"key1",
 | 
						|
			checkpoint1,
 | 
						|
			true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			"key2",
 | 
						|
			newFakeCheckpointV1("check2", nil, false),
 | 
						|
			false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tc := range checkpoints {
 | 
						|
		// Test CreateCheckpoints
 | 
						|
		err = manager.CreateCheckpoint(tc.checkpointKey, tc.checkpoint)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		// Test GetCheckpoints
 | 
						|
		checkpointOut := newFakeCheckpointV1("", nil, false)
 | 
						|
		err := manager.GetCheckpoint(tc.checkpointKey, checkpointOut)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		actualPortMappings, actualHostNetwork := checkpointOut.GetData()
 | 
						|
		expPortMappings, expHostNetwork := tc.checkpoint.GetData()
 | 
						|
		assert.Equal(t, actualPortMappings, expPortMappings)
 | 
						|
		assert.Equal(t, actualHostNetwork, expHostNetwork)
 | 
						|
	}
 | 
						|
	// Test it fails if tried to read V1 structure into V2, a different structure from the structure which is checkpointed
 | 
						|
	checkpointV2 := newFakeCheckpointV2("", nil, false)
 | 
						|
	err = manager.GetCheckpoint("key1", checkpointV2)
 | 
						|
	assert.EqualError(t, err, "checkpoint is corrupted")
 | 
						|
 | 
						|
	// Test it fails if tried to read V1 structure into the same structure but defined in another package
 | 
						|
	checkpointRemoteV1 := newFakeCheckpointRemoteV1("", nil, false)
 | 
						|
	err = manager.GetCheckpoint("key1", checkpointRemoteV1)
 | 
						|
	assert.EqualError(t, err, "checkpoint is corrupted")
 | 
						|
 | 
						|
	// Test it works if tried to read V1 structure using into a new V1 structure
 | 
						|
	checkpointV1 := newFakeCheckpointV1("", nil, false)
 | 
						|
	err = manager.GetCheckpoint("key1", checkpointV1)
 | 
						|
	assert.NoError(t, err)
 | 
						|
 | 
						|
	// Test corrupt checksum case
 | 
						|
	checkpointOut := newFakeCheckpointV1("", nil, false)
 | 
						|
	blob, err := checkpointOut.MarshalCheckpoint()
 | 
						|
	assert.NoError(t, err)
 | 
						|
	testStore.Write("key1", blob)
 | 
						|
	err = manager.GetCheckpoint("key1", checkpoint1)
 | 
						|
	assert.EqualError(t, err, "checkpoint is corrupted")
 | 
						|
 | 
						|
	// Test ListCheckpoints
 | 
						|
	keys, err := manager.ListCheckpoints()
 | 
						|
	assert.NoError(t, err)
 | 
						|
	sort.Strings(keys)
 | 
						|
	assert.Equal(t, keys, []string{"key1", "key2"})
 | 
						|
 | 
						|
	// Test RemoveCheckpoints
 | 
						|
	err = manager.RemoveCheckpoint("key1")
 | 
						|
	assert.NoError(t, err)
 | 
						|
	// Test Remove Nonexisted Checkpoints
 | 
						|
	err = manager.RemoveCheckpoint("key1")
 | 
						|
	assert.NoError(t, err)
 | 
						|
 | 
						|
	// Test ListCheckpoints
 | 
						|
	keys, err = manager.ListCheckpoints()
 | 
						|
	assert.NoError(t, err)
 | 
						|
	assert.Equal(t, keys, []string{"key2"})
 | 
						|
 | 
						|
	// Test Get NonExisted Checkpoint
 | 
						|
	checkpointNE := newFakeCheckpointV1("NE", nil, false)
 | 
						|
	err = manager.GetCheckpoint("key1", checkpointNE)
 | 
						|
	assert.Error(t, err)
 | 
						|
}
 |