...

Source file src/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checkpoint_manager_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/checkpointmanager

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package checkpointmanager
    18  
    19  import (
    20  	"encoding/json"
    21  	"sort"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum"
    26  	utilstore "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/testing"
    27  	"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/testing/example_checkpoint_formats/v1"
    28  )
    29  
    30  var testStore *utilstore.MemStore
    31  
    32  type FakeCheckpoint interface {
    33  	Checkpoint
    34  	GetData() ([]*PortMapping, bool)
    35  }
    36  
    37  // Data contains all types of data that can be stored in the checkpoint.
    38  type Data struct {
    39  	PortMappings []*PortMapping `json:"port_mappings,omitempty"`
    40  	HostNetwork  bool           `json:"host_network,omitempty"`
    41  }
    42  
    43  type CheckpointDataV2 struct {
    44  	PortMappings []*PortMapping `json:"port_mappings,omitempty"`
    45  	HostNetwork  bool           `json:"host_network,omitempty"`
    46  	V2Field      string         `json:"v2field"`
    47  }
    48  
    49  type protocol string
    50  
    51  // portMapping is the port mapping configurations of a sandbox.
    52  type PortMapping struct {
    53  	// protocol of the port mapping.
    54  	Protocol *protocol
    55  	// Port number within the container.
    56  	ContainerPort *int32
    57  	// Port number on the host.
    58  	HostPort *int32
    59  	// Host ip to expose.
    60  	HostIP string
    61  }
    62  
    63  // CheckpointData is a sample example structure to be used in test cases for checkpointing
    64  type CheckpointData struct {
    65  	Version  string
    66  	Name     string
    67  	Data     *Data
    68  	Checksum checksum.Checksum
    69  }
    70  
    71  func newFakeCheckpointV1(name string, portMappings []*PortMapping, hostNetwork bool) FakeCheckpoint {
    72  	return &CheckpointData{
    73  		Version: "v1",
    74  		Name:    name,
    75  		Data: &Data{
    76  			PortMappings: portMappings,
    77  			HostNetwork:  hostNetwork,
    78  		},
    79  	}
    80  }
    81  
    82  func (cp *CheckpointData) MarshalCheckpoint() ([]byte, error) {
    83  	cp.Checksum = checksum.New(*cp.Data)
    84  	return json.Marshal(*cp)
    85  }
    86  
    87  func (cp *CheckpointData) UnmarshalCheckpoint(blob []byte) error {
    88  	return json.Unmarshal(blob, cp)
    89  }
    90  
    91  func (cp *CheckpointData) VerifyChecksum() error {
    92  	return cp.Checksum.Verify(*cp.Data)
    93  }
    94  
    95  func (cp *CheckpointData) GetData() ([]*PortMapping, bool) {
    96  	return cp.Data.PortMappings, cp.Data.HostNetwork
    97  }
    98  
    99  type checkpointDataV2 struct {
   100  	Version  string
   101  	Name     string
   102  	Data     *CheckpointDataV2
   103  	Checksum checksum.Checksum
   104  }
   105  
   106  func newFakeCheckpointV2(name string, portMappings []*PortMapping, hostNetwork bool) FakeCheckpoint {
   107  	return &checkpointDataV2{
   108  		Version: "v2",
   109  		Name:    name,
   110  		Data: &CheckpointDataV2{
   111  			PortMappings: portMappings,
   112  			HostNetwork:  hostNetwork,
   113  		},
   114  	}
   115  }
   116  
   117  func newFakeCheckpointRemoteV1(name string, portMappings []*v1.PortMapping, hostNetwork bool) Checkpoint {
   118  	return &v1.CheckpointData{
   119  		Version: "v1",
   120  		Name:    name,
   121  		Data: &v1.Data{
   122  			PortMappings: portMappings,
   123  			HostNetwork:  hostNetwork,
   124  		},
   125  	}
   126  }
   127  
   128  func (cp *checkpointDataV2) MarshalCheckpoint() ([]byte, error) {
   129  	cp.Checksum = checksum.New(*cp.Data)
   130  	return json.Marshal(*cp)
   131  }
   132  
   133  func (cp *checkpointDataV2) UnmarshalCheckpoint(blob []byte) error {
   134  	return json.Unmarshal(blob, cp)
   135  }
   136  
   137  func (cp *checkpointDataV2) VerifyChecksum() error {
   138  	return cp.Checksum.Verify(*cp.Data)
   139  }
   140  
   141  func (cp *checkpointDataV2) GetData() ([]*PortMapping, bool) {
   142  	return cp.Data.PortMappings, cp.Data.HostNetwork
   143  }
   144  
   145  func newTestCheckpointManager() CheckpointManager {
   146  	return &impl{store: testStore}
   147  }
   148  
   149  func TestCheckpointManager(t *testing.T) {
   150  	var err error
   151  	testStore = utilstore.NewMemStore()
   152  	manager := newTestCheckpointManager()
   153  	port80 := int32(80)
   154  	port443 := int32(443)
   155  	proto := protocol("tcp")
   156  	ip1234 := "1.2.3.4"
   157  
   158  	portMappings := []*PortMapping{
   159  		{
   160  			&proto,
   161  			&port80,
   162  			&port80,
   163  			ip1234,
   164  		},
   165  		{
   166  			&proto,
   167  			&port443,
   168  			&port443,
   169  			ip1234,
   170  		},
   171  	}
   172  	checkpoint1 := newFakeCheckpointV1("check1", portMappings, true)
   173  
   174  	checkpoints := []struct {
   175  		checkpointKey     string
   176  		checkpoint        FakeCheckpoint
   177  		expectHostNetwork bool
   178  	}{
   179  		{
   180  			"key1",
   181  			checkpoint1,
   182  			true,
   183  		},
   184  		{
   185  			"key2",
   186  			newFakeCheckpointV1("check2", nil, false),
   187  			false,
   188  		},
   189  	}
   190  
   191  	for _, tc := range checkpoints {
   192  		// Test CreateCheckpoints
   193  		err = manager.CreateCheckpoint(tc.checkpointKey, tc.checkpoint)
   194  		assert.NoError(t, err)
   195  
   196  		// Test GetCheckpoints
   197  		checkpointOut := newFakeCheckpointV1("", nil, false)
   198  		err := manager.GetCheckpoint(tc.checkpointKey, checkpointOut)
   199  		assert.NoError(t, err)
   200  		actualPortMappings, actualHostNetwork := checkpointOut.GetData()
   201  		expPortMappings, expHostNetwork := tc.checkpoint.GetData()
   202  		assert.Equal(t, actualPortMappings, expPortMappings)
   203  		assert.Equal(t, actualHostNetwork, expHostNetwork)
   204  	}
   205  	// Test it fails if tried to read V1 structure into V2, a different structure from the structure which is checkpointed
   206  	checkpointV2 := newFakeCheckpointV2("", nil, false)
   207  	err = manager.GetCheckpoint("key1", checkpointV2)
   208  	assert.EqualError(t, err, "checkpoint is corrupted")
   209  
   210  	// Test it fails if tried to read V1 structure into the same structure but defined in another package
   211  	checkpointRemoteV1 := newFakeCheckpointRemoteV1("", nil, false)
   212  	err = manager.GetCheckpoint("key1", checkpointRemoteV1)
   213  	assert.EqualError(t, err, "checkpoint is corrupted")
   214  
   215  	// Test it works if tried to read V1 structure using into a new V1 structure
   216  	checkpointV1 := newFakeCheckpointV1("", nil, false)
   217  	err = manager.GetCheckpoint("key1", checkpointV1)
   218  	assert.NoError(t, err)
   219  
   220  	// Test corrupt checksum case
   221  	checkpointOut := newFakeCheckpointV1("", nil, false)
   222  	blob, err := checkpointOut.MarshalCheckpoint()
   223  	assert.NoError(t, err)
   224  	testStore.Write("key1", blob)
   225  	err = manager.GetCheckpoint("key1", checkpoint1)
   226  	assert.EqualError(t, err, "checkpoint is corrupted")
   227  
   228  	// Test ListCheckpoints
   229  	keys, err := manager.ListCheckpoints()
   230  	assert.NoError(t, err)
   231  	sort.Strings(keys)
   232  	assert.Equal(t, keys, []string{"key1", "key2"})
   233  
   234  	// Test RemoveCheckpoints
   235  	err = manager.RemoveCheckpoint("key1")
   236  	assert.NoError(t, err)
   237  	// Test Remove Nonexisted Checkpoints
   238  	err = manager.RemoveCheckpoint("key1")
   239  	assert.NoError(t, err)
   240  
   241  	// Test ListCheckpoints
   242  	keys, err = manager.ListCheckpoints()
   243  	assert.NoError(t, err)
   244  	assert.Equal(t, keys, []string{"key2"})
   245  
   246  	// Test Get NonExisted Checkpoint
   247  	checkpointNE := newFakeCheckpointV1("NE", nil, false)
   248  	err = manager.GetCheckpoint("key1", checkpointNE)
   249  	assert.Error(t, err)
   250  }
   251  

View as plain text