k8s.io/kubernetes@v1.29.3/pkg/kubelet/checkpointmanager/checkpoint_manager_test.go (about) 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 }