github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/container-utils/cri/cri_test.go (about)

     1  // Copyright 2019-2022 The Inspektor Gadget authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cri
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  
    23  	runtimeclient "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils/runtime-client"
    24  )
    25  
    26  func TestParseExtraInfo(t *testing.T) {
    27  	table := []struct {
    28  		description string
    29  		info        map[string]string
    30  		expected    *runtimeclient.ContainerDetailsData
    31  	}{
    32  		// Invalid params
    33  		{
    34  			description: "From empty map",
    35  			info:        map[string]string{},
    36  		},
    37  		{
    38  			description: "Nil map",
    39  			info:        nil,
    40  		},
    41  		// Former format
    42  		{
    43  			description: "Former format: No pid entry",
    44  			info:        map[string]string{"sandboxID": "myID"},
    45  		},
    46  		{
    47  			description: "Former format: Invalid PID",
    48  			info:        map[string]string{"sandboxID": "myID", "pid": "abc"},
    49  		},
    50  		{
    51  			description: "Former format: Zero PID",
    52  			info:        map[string]string{"sandboxID": "myID", "pid": "0"},
    53  		},
    54  		{
    55  			description: "Former format: Pid 1234",
    56  			info:        map[string]string{"sandboxID": "myID", "pid": "1234"},
    57  			expected:    &runtimeclient.ContainerDetailsData{Pid: 1234},
    58  		},
    59  		{
    60  			description: "Former format: cgroupPath missing",
    61  			info: map[string]string{
    62  				"sandboxID": "myID", "pid": "1234",
    63  				"runtimeSpec": `{"linux":{"cgroupsPath2":"/mypath"}}`,
    64  			},
    65  			expected: &runtimeclient.ContainerDetailsData{Pid: 1234},
    66  		},
    67  		{
    68  			description: "Former format: cgroupPath",
    69  			info: map[string]string{
    70  				"sandboxID": "myID", "pid": "1234",
    71  				"runtimeSpec": `{"linux":{"cgroupsPath":"/mypath"}}`,
    72  			},
    73  			expected: &runtimeclient.ContainerDetailsData{Pid: 1234, CgroupsPath: "/mypath"},
    74  		},
    75  		{
    76  			description: "Former format: mounts",
    77  			info: map[string]string{
    78  				"sandboxID": "myID", "pid": "1234",
    79  				"runtimeSpec": `{
    80  					"linux": { "cgroupsPath": "/mypath" },
    81  					"mounts": [
    82  						{
    83  							"source": "/src/a1",
    84  							"destination": "/dst/b1"
    85  						},
    86  						{
    87  							"source": "/src/a2",
    88  							"destination": "/dst/b2"
    89  						}
    90  					]
    91  				}`,
    92  			},
    93  			expected: &runtimeclient.ContainerDetailsData{
    94  				Pid:         1234,
    95  				CgroupsPath: "/mypath",
    96  				Mounts: []runtimeclient.ContainerMountData{
    97  					{Source: "/src/a1", Destination: "/dst/b1"},
    98  					{Source: "/src/a2", Destination: "/dst/b2"},
    99  				},
   100  			},
   101  		},
   102  		// New format
   103  		{
   104  			description: "New format: Invalid format",
   105  			info:        map[string]string{"info": `{"InvalidFormat"}`},
   106  		},
   107  		{
   108  			description: "New format: No pid entry",
   109  			info:        map[string]string{"info": `{"sandboxID":"myID"}`},
   110  		},
   111  		{
   112  			description: "New format: Zero pid",
   113  			info:        map[string]string{"info": `{"sandboxID":"myID","pid":0}`},
   114  		},
   115  		{
   116  			description: "New format: Invalid PID",
   117  			info:        map[string]string{"info": `{"sandboxID":"myID","pid":1.2}`},
   118  		},
   119  		{
   120  			description: "New format: Pid 1234",
   121  			info:        map[string]string{"info": `{"sandboxID":"myID","pid":1234}`},
   122  			expected:    &runtimeclient.ContainerDetailsData{Pid: 1234},
   123  		},
   124  
   125  		{
   126  			description: "New format: cgroupPath missing",
   127  			info: map[string]string{
   128  				"info": `{
   129  					"pid": 1234,
   130  					"runtimeSpec": {
   131  						"linux": { "cgroupsPath2": "/mypath" }
   132  					}
   133  				}`,
   134  			},
   135  			expected: &runtimeclient.ContainerDetailsData{Pid: 1234},
   136  		},
   137  		{
   138  			description: "New format: cgroupPath",
   139  			info: map[string]string{
   140  				"info": `{
   141  					"pid": 1234,
   142  					"runtimeSpec": {
   143  						"linux": { "cgroupsPath": "/mypath" }
   144  					}
   145  				}`,
   146  			},
   147  			expected: &runtimeclient.ContainerDetailsData{Pid: 1234, CgroupsPath: "/mypath"},
   148  		},
   149  		{
   150  			description: "New format: mounts",
   151  			info: map[string]string{
   152  				"info": `{
   153  					"pid": 1234,
   154  					"runtimeSpec": {
   155  						"linux": { "cgroupsPath": "/mypath" },
   156  						"mounts": [
   157  							{
   158  								"source": "/src/a1",
   159  								"destination": "/dst/b1"
   160  							},
   161  							{
   162  								"source": "/src/a2",
   163  								"destination": "/dst/b2"
   164  							}
   165  						]
   166  					}
   167  				}`,
   168  			},
   169  			expected: &runtimeclient.ContainerDetailsData{
   170  				Pid:         1234,
   171  				CgroupsPath: "/mypath",
   172  				Mounts: []runtimeclient.ContainerMountData{
   173  					{Source: "/src/a1", Destination: "/dst/b1"},
   174  					{Source: "/src/a2", Destination: "/dst/b2"},
   175  				},
   176  			},
   177  		},
   178  	}
   179  
   180  	// Iterate on all tests.
   181  	for _, entry := range table {
   182  		// Parse the extra info.
   183  		containerDetailsData := &runtimeclient.ContainerDetailsData{}
   184  		err := parseExtraInfo(entry.info, containerDetailsData)
   185  		// Expected error.
   186  		if err != nil {
   187  			if entry.expected != nil {
   188  				t.Fatalf("Failed test %q: unexpected error: %s", entry.description, err.Error())
   189  			}
   190  
   191  			// An error was returned, no point in checking rest of fields.
   192  			continue
   193  		}
   194  
   195  		// Make sure expected field was filled.
   196  		if entry.expected == nil {
   197  			t.Fatalf("Failed test %q: unexpected success (expected error)", entry.description)
   198  		}
   199  
   200  		if !reflect.DeepEqual(entry.expected, containerDetailsData) {
   201  			t.Fatalf("%q: event doesn't match:\n%s", entry.description,
   202  				cmp.Diff(entry.expected, containerDetailsData))
   203  		}
   204  	}
   205  }