github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/specgen/generate/kube/play_test.go (about)

     1  package kube
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math"
     7  	"runtime"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/containers/common/pkg/secrets"
    12  	v1 "github.com/hanks177/podman/v4/pkg/k8s.io/api/core/v1"
    13  	"github.com/hanks177/podman/v4/pkg/k8s.io/apimachinery/pkg/api/resource"
    14  	v12 "github.com/hanks177/podman/v4/pkg/k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	"github.com/docker/docker/pkg/system"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  func createSecrets(t *testing.T, d string) *secrets.SecretsManager {
    20  	secretsManager, err := secrets.NewManager(d)
    21  	assert.NoError(t, err)
    22  
    23  	driver := "file"
    24  	driverOpts := map[string]string{
    25  		"path": d,
    26  	}
    27  
    28  	for _, s := range k8sSecrets {
    29  		data, err := json.Marshal(s.Data)
    30  		assert.NoError(t, err)
    31  
    32  		_, err = secretsManager.Store(s.ObjectMeta.Name, data, driver, driverOpts)
    33  		assert.NoError(t, err)
    34  	}
    35  
    36  	return secretsManager
    37  }
    38  
    39  func TestEnvVarsFrom(t *testing.T) {
    40  	d := t.TempDir()
    41  	secretsManager := createSecrets(t, d)
    42  
    43  	tests := []struct {
    44  		name     string
    45  		envFrom  v1.EnvFromSource
    46  		options  CtrSpecGenOptions
    47  		succeed  bool
    48  		expected map[string]string
    49  	}{
    50  		{
    51  			"ConfigMapExists",
    52  			v1.EnvFromSource{
    53  				ConfigMapRef: &v1.ConfigMapEnvSource{
    54  					LocalObjectReference: v1.LocalObjectReference{
    55  						Name: "foo",
    56  					},
    57  				},
    58  			},
    59  			CtrSpecGenOptions{
    60  				ConfigMaps: configMapList,
    61  			},
    62  			true,
    63  			map[string]string{
    64  				"myvar": "foo",
    65  			},
    66  		},
    67  		{
    68  			"ConfigMapDoesNotExist",
    69  			v1.EnvFromSource{
    70  				ConfigMapRef: &v1.ConfigMapEnvSource{
    71  					LocalObjectReference: v1.LocalObjectReference{
    72  						Name: "doesnotexist",
    73  					},
    74  				},
    75  			},
    76  			CtrSpecGenOptions{
    77  				ConfigMaps: configMapList,
    78  			},
    79  			false,
    80  			nil,
    81  		},
    82  		{
    83  			"OptionalConfigMapDoesNotExist",
    84  			v1.EnvFromSource{
    85  				ConfigMapRef: &v1.ConfigMapEnvSource{
    86  					LocalObjectReference: v1.LocalObjectReference{
    87  						Name: "doesnotexist",
    88  					},
    89  					Optional: &optional,
    90  				},
    91  			},
    92  			CtrSpecGenOptions{
    93  				ConfigMaps: configMapList,
    94  			},
    95  			true,
    96  			map[string]string{},
    97  		},
    98  		{
    99  			"EmptyConfigMapList",
   100  			v1.EnvFromSource{
   101  				ConfigMapRef: &v1.ConfigMapEnvSource{
   102  					LocalObjectReference: v1.LocalObjectReference{
   103  						Name: "foo",
   104  					},
   105  				},
   106  			},
   107  			CtrSpecGenOptions{
   108  				ConfigMaps: []v1.ConfigMap{},
   109  			},
   110  			false,
   111  			nil,
   112  		},
   113  		{
   114  			"OptionalEmptyConfigMapList",
   115  			v1.EnvFromSource{
   116  				ConfigMapRef: &v1.ConfigMapEnvSource{
   117  					LocalObjectReference: v1.LocalObjectReference{
   118  						Name: "foo",
   119  					},
   120  					Optional: &optional,
   121  				},
   122  			},
   123  			CtrSpecGenOptions{
   124  				ConfigMaps: []v1.ConfigMap{},
   125  			},
   126  			true,
   127  			map[string]string{},
   128  		},
   129  		{
   130  			"SecretExists",
   131  			v1.EnvFromSource{
   132  				SecretRef: &v1.SecretEnvSource{
   133  					LocalObjectReference: v1.LocalObjectReference{
   134  						Name: "foo",
   135  					},
   136  				},
   137  			},
   138  			CtrSpecGenOptions{
   139  				SecretsManager: secretsManager,
   140  			},
   141  			true,
   142  			map[string]string{
   143  				"myvar": "foo",
   144  			},
   145  		},
   146  		{
   147  			"SecretDoesNotExist",
   148  			v1.EnvFromSource{
   149  				SecretRef: &v1.SecretEnvSource{
   150  					LocalObjectReference: v1.LocalObjectReference{
   151  						Name: "doesnotexist",
   152  					},
   153  				},
   154  			},
   155  			CtrSpecGenOptions{
   156  				SecretsManager: secretsManager,
   157  			},
   158  			false,
   159  			nil,
   160  		},
   161  		{
   162  			"OptionalSecretDoesNotExist",
   163  			v1.EnvFromSource{
   164  				SecretRef: &v1.SecretEnvSource{
   165  					LocalObjectReference: v1.LocalObjectReference{
   166  						Name: "doesnotexist",
   167  					},
   168  					Optional: &optional,
   169  				},
   170  			},
   171  			CtrSpecGenOptions{
   172  				SecretsManager: secretsManager,
   173  			},
   174  			true,
   175  			map[string]string{},
   176  		},
   177  	}
   178  
   179  	for _, test := range tests {
   180  		test := test
   181  		t.Run(test.name, func(t *testing.T) {
   182  			result, err := envVarsFrom(test.envFrom, &test.options)
   183  			assert.Equal(t, err == nil, test.succeed)
   184  			assert.Equal(t, test.expected, result)
   185  		})
   186  	}
   187  }
   188  
   189  func TestEnvVarValue(t *testing.T) {
   190  	d := t.TempDir()
   191  	secretsManager := createSecrets(t, d)
   192  	stringNumCPUs := strconv.Itoa(runtime.NumCPU())
   193  
   194  	mi, err := system.ReadMemInfo()
   195  	assert.Nil(t, err)
   196  	stringMemTotal := strconv.FormatInt(mi.MemTotal, 10)
   197  
   198  	tests := []struct {
   199  		name     string
   200  		envVar   v1.EnvVar
   201  		options  CtrSpecGenOptions
   202  		succeed  bool
   203  		expected string
   204  	}{
   205  		{
   206  			"ConfigMapExists",
   207  			v1.EnvVar{
   208  				Name: "FOO",
   209  				ValueFrom: &v1.EnvVarSource{
   210  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   211  						LocalObjectReference: v1.LocalObjectReference{
   212  							Name: "foo",
   213  						},
   214  						Key: "myvar",
   215  					},
   216  				},
   217  			},
   218  			CtrSpecGenOptions{
   219  				ConfigMaps: configMapList,
   220  			},
   221  			true,
   222  			"foo",
   223  		},
   224  		{
   225  			"ContainerKeyDoesNotExistInConfigMap",
   226  			v1.EnvVar{
   227  				Name: "FOO",
   228  				ValueFrom: &v1.EnvVarSource{
   229  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   230  						LocalObjectReference: v1.LocalObjectReference{
   231  							Name: "foo",
   232  						},
   233  						Key: "doesnotexist",
   234  					},
   235  				},
   236  			},
   237  			CtrSpecGenOptions{
   238  				ConfigMaps: configMapList,
   239  			},
   240  			false,
   241  			nilString,
   242  		},
   243  		{
   244  			"OptionalContainerKeyDoesNotExistInConfigMap",
   245  			v1.EnvVar{
   246  				Name: "FOO",
   247  				ValueFrom: &v1.EnvVarSource{
   248  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   249  						LocalObjectReference: v1.LocalObjectReference{
   250  							Name: "foo",
   251  						},
   252  						Key:      "doesnotexist",
   253  						Optional: &optional,
   254  					},
   255  				},
   256  			},
   257  			CtrSpecGenOptions{
   258  				ConfigMaps: configMapList,
   259  			},
   260  			true,
   261  			nilString,
   262  		},
   263  		{
   264  			"ConfigMapDoesNotExist",
   265  			v1.EnvVar{
   266  				Name: "FOO",
   267  				ValueFrom: &v1.EnvVarSource{
   268  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   269  						LocalObjectReference: v1.LocalObjectReference{
   270  							Name: "doesnotexist",
   271  						},
   272  						Key: "myvar",
   273  					},
   274  				},
   275  			},
   276  			CtrSpecGenOptions{
   277  				ConfigMaps: configMapList,
   278  			},
   279  			false,
   280  			nilString,
   281  		},
   282  		{
   283  			"OptionalConfigMapDoesNotExist",
   284  			v1.EnvVar{
   285  				Name: "FOO",
   286  				ValueFrom: &v1.EnvVarSource{
   287  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   288  						LocalObjectReference: v1.LocalObjectReference{
   289  							Name: "doesnotexist",
   290  						},
   291  						Key:      "myvar",
   292  						Optional: &optional,
   293  					},
   294  				},
   295  			},
   296  			CtrSpecGenOptions{
   297  				ConfigMaps: configMapList,
   298  			},
   299  			true,
   300  			nilString,
   301  		},
   302  		{
   303  			"EmptyConfigMapList",
   304  			v1.EnvVar{
   305  				Name: "FOO",
   306  				ValueFrom: &v1.EnvVarSource{
   307  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   308  						LocalObjectReference: v1.LocalObjectReference{
   309  							Name: "foo",
   310  						},
   311  						Key: "myvar",
   312  					},
   313  				},
   314  			},
   315  			CtrSpecGenOptions{
   316  				ConfigMaps: []v1.ConfigMap{},
   317  			},
   318  			false,
   319  			nilString,
   320  		},
   321  		{
   322  			"OptionalEmptyConfigMapList",
   323  			v1.EnvVar{
   324  				Name: "FOO",
   325  				ValueFrom: &v1.EnvVarSource{
   326  					ConfigMapKeyRef: &v1.ConfigMapKeySelector{
   327  						LocalObjectReference: v1.LocalObjectReference{
   328  							Name: "foo",
   329  						},
   330  						Key:      "myvar",
   331  						Optional: &optional,
   332  					},
   333  				},
   334  			},
   335  			CtrSpecGenOptions{
   336  				ConfigMaps: []v1.ConfigMap{},
   337  			},
   338  			true,
   339  			nilString,
   340  		},
   341  		{
   342  			"SecretExists",
   343  			v1.EnvVar{
   344  				Name: "FOO",
   345  				ValueFrom: &v1.EnvVarSource{
   346  					SecretKeyRef: &v1.SecretKeySelector{
   347  						LocalObjectReference: v1.LocalObjectReference{
   348  							Name: "foo",
   349  						},
   350  						Key: "myvar",
   351  					},
   352  				},
   353  			},
   354  			CtrSpecGenOptions{
   355  				SecretsManager: secretsManager,
   356  			},
   357  			true,
   358  			"foo",
   359  		},
   360  		{
   361  			"ContainerKeyDoesNotExistInSecret",
   362  			v1.EnvVar{
   363  				Name: "FOO",
   364  				ValueFrom: &v1.EnvVarSource{
   365  					SecretKeyRef: &v1.SecretKeySelector{
   366  						LocalObjectReference: v1.LocalObjectReference{
   367  							Name: "foo",
   368  						},
   369  						Key: "doesnotexist",
   370  					},
   371  				},
   372  			},
   373  			CtrSpecGenOptions{
   374  				SecretsManager: secretsManager,
   375  			},
   376  			false,
   377  			nilString,
   378  		},
   379  		{
   380  			"OptionalContainerKeyDoesNotExistInSecret",
   381  			v1.EnvVar{
   382  				Name: "FOO",
   383  				ValueFrom: &v1.EnvVarSource{
   384  					SecretKeyRef: &v1.SecretKeySelector{
   385  						LocalObjectReference: v1.LocalObjectReference{
   386  							Name: "foo",
   387  						},
   388  						Key:      "doesnotexist",
   389  						Optional: &optional,
   390  					},
   391  				},
   392  			},
   393  			CtrSpecGenOptions{
   394  				SecretsManager: secretsManager,
   395  			},
   396  			true,
   397  			nilString,
   398  		},
   399  		{
   400  			"SecretDoesNotExist",
   401  			v1.EnvVar{
   402  				Name: "FOO",
   403  				ValueFrom: &v1.EnvVarSource{
   404  					SecretKeyRef: &v1.SecretKeySelector{
   405  						LocalObjectReference: v1.LocalObjectReference{
   406  							Name: "doesnotexist",
   407  						},
   408  						Key: "myvar",
   409  					},
   410  				},
   411  			},
   412  			CtrSpecGenOptions{
   413  				SecretsManager: secretsManager,
   414  			},
   415  			false,
   416  			nilString,
   417  		},
   418  		{
   419  			"OptionalSecretDoesNotExist",
   420  			v1.EnvVar{
   421  				Name: "FOO",
   422  				ValueFrom: &v1.EnvVarSource{
   423  					SecretKeyRef: &v1.SecretKeySelector{
   424  						LocalObjectReference: v1.LocalObjectReference{
   425  							Name: "doesnotexist",
   426  						},
   427  						Key:      "myvar",
   428  						Optional: &optional,
   429  					},
   430  				},
   431  			},
   432  			CtrSpecGenOptions{
   433  				SecretsManager: secretsManager,
   434  			},
   435  			true,
   436  			nilString,
   437  		},
   438  		{
   439  			"FieldRefMetadataName",
   440  			v1.EnvVar{
   441  				Name: "FOO",
   442  				ValueFrom: &v1.EnvVarSource{
   443  					FieldRef: &v1.ObjectFieldSelector{
   444  						FieldPath: "metadata.name",
   445  					},
   446  				},
   447  			},
   448  			CtrSpecGenOptions{
   449  				PodName: "test",
   450  			},
   451  			true,
   452  			"test",
   453  		},
   454  		{
   455  			"FieldRefMetadataUID",
   456  			v1.EnvVar{
   457  				Name: "FOO",
   458  				ValueFrom: &v1.EnvVarSource{
   459  					FieldRef: &v1.ObjectFieldSelector{
   460  						FieldPath: "metadata.uid",
   461  					},
   462  				},
   463  			},
   464  			CtrSpecGenOptions{
   465  				PodID: "ec71ff37c67b688598c0008187ab0960dc34e1dfdcbf3a74e3d778bafcfe0977",
   466  			},
   467  			true,
   468  			"ec71ff37c67b688598c0008187ab0960dc34e1dfdcbf3a74e3d778bafcfe0977",
   469  		},
   470  		{
   471  			"FieldRefMetadataLabelsExist",
   472  			v1.EnvVar{
   473  				Name: "FOO",
   474  				ValueFrom: &v1.EnvVarSource{
   475  					FieldRef: &v1.ObjectFieldSelector{
   476  						FieldPath: "metadata.labels['label']",
   477  					},
   478  				},
   479  			},
   480  			CtrSpecGenOptions{
   481  				Labels: map[string]string{"label": "label"},
   482  			},
   483  			true,
   484  			"label",
   485  		},
   486  		{
   487  			"FieldRefMetadataLabelsEmpty",
   488  			v1.EnvVar{
   489  				Name: "FOO",
   490  				ValueFrom: &v1.EnvVarSource{
   491  					FieldRef: &v1.ObjectFieldSelector{
   492  						FieldPath: "metadata.labels['label']",
   493  					},
   494  				},
   495  			},
   496  			CtrSpecGenOptions{
   497  				Labels: map[string]string{"label": ""},
   498  			},
   499  			true,
   500  			"",
   501  		},
   502  		{
   503  			"FieldRefMetadataLabelsNotExist",
   504  			v1.EnvVar{
   505  				Name: "FOO",
   506  				ValueFrom: &v1.EnvVarSource{
   507  					FieldRef: &v1.ObjectFieldSelector{
   508  						FieldPath: "metadata.labels['label']",
   509  					},
   510  				},
   511  			},
   512  			CtrSpecGenOptions{},
   513  			true,
   514  			"",
   515  		},
   516  		{
   517  			"FieldRefMetadataAnnotationsExist",
   518  			v1.EnvVar{
   519  				Name: "FOO",
   520  				ValueFrom: &v1.EnvVarSource{
   521  					FieldRef: &v1.ObjectFieldSelector{
   522  						FieldPath: "metadata.annotations['annotation']",
   523  					},
   524  				},
   525  			},
   526  			CtrSpecGenOptions{
   527  				Annotations: map[string]string{"annotation": "annotation"},
   528  			},
   529  			true,
   530  			"annotation",
   531  		},
   532  		{
   533  			"FieldRefMetadataAnnotationsEmpty",
   534  			v1.EnvVar{
   535  				Name: "FOO",
   536  				ValueFrom: &v1.EnvVarSource{
   537  					FieldRef: &v1.ObjectFieldSelector{
   538  						FieldPath: "metadata.annotations['annotation']",
   539  					},
   540  				},
   541  			},
   542  			CtrSpecGenOptions{
   543  				Annotations: map[string]string{"annotation": ""},
   544  			},
   545  			true,
   546  			"",
   547  		},
   548  		{
   549  			"FieldRefMetadataAnnotationsNotExist",
   550  			v1.EnvVar{
   551  				Name: "FOO",
   552  				ValueFrom: &v1.EnvVarSource{
   553  					FieldRef: &v1.ObjectFieldSelector{
   554  						FieldPath: "metadata.annotations['annotation']",
   555  					},
   556  				},
   557  			},
   558  			CtrSpecGenOptions{},
   559  			true,
   560  			"",
   561  		},
   562  		{
   563  			"FieldRefInvalid1",
   564  			v1.EnvVar{
   565  				Name: "FOO",
   566  				ValueFrom: &v1.EnvVarSource{
   567  					FieldRef: &v1.ObjectFieldSelector{
   568  						FieldPath: "metadata.annotations['annotation]",
   569  					},
   570  				},
   571  			},
   572  			CtrSpecGenOptions{},
   573  			false,
   574  			nilString,
   575  		},
   576  		{
   577  			"FieldRefInvalid2",
   578  			v1.EnvVar{
   579  				Name: "FOO",
   580  				ValueFrom: &v1.EnvVarSource{
   581  					FieldRef: &v1.ObjectFieldSelector{
   582  						FieldPath: "metadata.dummy['annotation']",
   583  					},
   584  				},
   585  			},
   586  			CtrSpecGenOptions{},
   587  			false,
   588  			nilString,
   589  		},
   590  		{
   591  			"FieldRefNotSupported",
   592  			v1.EnvVar{
   593  				Name: "FOO",
   594  				ValueFrom: &v1.EnvVarSource{
   595  					FieldRef: &v1.ObjectFieldSelector{
   596  						FieldPath: "metadata.namespace",
   597  					},
   598  				},
   599  			},
   600  			CtrSpecGenOptions{},
   601  			false,
   602  			nilString,
   603  		},
   604  		{
   605  			"ResourceFieldRefNotSupported",
   606  			v1.EnvVar{
   607  				Name: "FOO",
   608  				ValueFrom: &v1.EnvVarSource{
   609  					ResourceFieldRef: &v1.ResourceFieldSelector{
   610  						Resource: "limits.dummy",
   611  					},
   612  				},
   613  			},
   614  			CtrSpecGenOptions{},
   615  			false,
   616  			nilString,
   617  		},
   618  		{
   619  			"ResourceFieldRefMemoryDivisorNotValid",
   620  			v1.EnvVar{
   621  				Name: "FOO",
   622  				ValueFrom: &v1.EnvVarSource{
   623  					ResourceFieldRef: &v1.ResourceFieldSelector{
   624  						Resource: "limits.memory",
   625  						Divisor:  resource.MustParse("2M"),
   626  					},
   627  				},
   628  			},
   629  			CtrSpecGenOptions{},
   630  			false,
   631  			nilString,
   632  		},
   633  		{
   634  			"ResourceFieldRefCpuDivisorNotValid",
   635  			v1.EnvVar{
   636  				Name: "FOO",
   637  				ValueFrom: &v1.EnvVarSource{
   638  					ResourceFieldRef: &v1.ResourceFieldSelector{
   639  						Resource: "limits.cpu",
   640  						Divisor:  resource.MustParse("2m"),
   641  					},
   642  				},
   643  			},
   644  			CtrSpecGenOptions{},
   645  			false,
   646  			nilString,
   647  		},
   648  		{
   649  			"ResourceFieldRefNoDivisor",
   650  			v1.EnvVar{
   651  				Name: "FOO",
   652  				ValueFrom: &v1.EnvVarSource{
   653  					ResourceFieldRef: &v1.ResourceFieldSelector{
   654  						Resource: "limits.memory",
   655  					},
   656  				},
   657  			},
   658  			CtrSpecGenOptions{
   659  				Container: container,
   660  			},
   661  			true,
   662  			memoryString,
   663  		},
   664  		{
   665  			"ResourceFieldRefMemoryDivisor",
   666  			v1.EnvVar{
   667  				Name: "FOO",
   668  				ValueFrom: &v1.EnvVarSource{
   669  					ResourceFieldRef: &v1.ResourceFieldSelector{
   670  						Resource: "limits.memory",
   671  						Divisor:  resource.MustParse("1Mi"),
   672  					},
   673  				},
   674  			},
   675  			CtrSpecGenOptions{
   676  				Container: container,
   677  			},
   678  			true,
   679  			strconv.Itoa(int(math.Ceil(float64(memoryInt) / 1024 / 1024))),
   680  		},
   681  		{
   682  			"ResourceFieldRefCpuDivisor",
   683  			v1.EnvVar{
   684  				Name: "FOO",
   685  				ValueFrom: &v1.EnvVarSource{
   686  					ResourceFieldRef: &v1.ResourceFieldSelector{
   687  						Resource: "requests.cpu",
   688  						Divisor:  resource.MustParse("1m"),
   689  					},
   690  				},
   691  			},
   692  			CtrSpecGenOptions{
   693  				Container: container,
   694  			},
   695  			true,
   696  			strconv.Itoa(int(float64(cpuInt) / 0.001)),
   697  		},
   698  		{
   699  			"ResourceFieldRefNoLimitMemory",
   700  			v1.EnvVar{
   701  				Name: "FOO",
   702  				ValueFrom: &v1.EnvVarSource{
   703  					ResourceFieldRef: &v1.ResourceFieldSelector{
   704  						Resource: "limits.memory",
   705  					},
   706  				},
   707  			},
   708  			CtrSpecGenOptions{
   709  				Container: v1.Container{
   710  					Name: "test",
   711  				},
   712  			},
   713  			true,
   714  			stringMemTotal,
   715  		},
   716  		{
   717  			"ResourceFieldRefNoRequestMemory",
   718  			v1.EnvVar{
   719  				Name: "FOO",
   720  				ValueFrom: &v1.EnvVarSource{
   721  					ResourceFieldRef: &v1.ResourceFieldSelector{
   722  						Resource: "requests.memory",
   723  					},
   724  				},
   725  			},
   726  			CtrSpecGenOptions{
   727  				Container: v1.Container{
   728  					Name: "test",
   729  				},
   730  			},
   731  			true,
   732  			stringMemTotal,
   733  		},
   734  		{
   735  			"ResourceFieldRefNoLimitCPU",
   736  			v1.EnvVar{
   737  				Name: "FOO",
   738  				ValueFrom: &v1.EnvVarSource{
   739  					ResourceFieldRef: &v1.ResourceFieldSelector{
   740  						Resource: "limits.cpu",
   741  					},
   742  				},
   743  			},
   744  			CtrSpecGenOptions{
   745  				Container: v1.Container{
   746  					Name: "test",
   747  				},
   748  			},
   749  			true,
   750  			stringNumCPUs,
   751  		},
   752  		{
   753  			"ResourceFieldRefNoRequestCPU",
   754  			v1.EnvVar{
   755  				Name: "FOO",
   756  				ValueFrom: &v1.EnvVarSource{
   757  					ResourceFieldRef: &v1.ResourceFieldSelector{
   758  						Resource: "requests.cpu",
   759  					},
   760  				},
   761  			},
   762  			CtrSpecGenOptions{
   763  				Container: v1.Container{
   764  					Name: "test",
   765  				},
   766  			},
   767  			true,
   768  			stringNumCPUs,
   769  		},
   770  	}
   771  
   772  	for _, test := range tests {
   773  		test := test
   774  		t.Run(test.name, func(t *testing.T) {
   775  			result, err := envVarValue(test.envVar, &test.options)
   776  			assert.Equal(t, err == nil, test.succeed)
   777  			if test.expected == nilString {
   778  				assert.Nil(t, result)
   779  			} else {
   780  				fmt.Println(*result, test.expected)
   781  				assert.Equal(t, &(test.expected), result)
   782  			}
   783  		})
   784  	}
   785  }
   786  
   787  var (
   788  	nilString     = "<nil>"
   789  	configMapList = []v1.ConfigMap{
   790  		{
   791  			TypeMeta: v12.TypeMeta{
   792  				Kind: "ConfigMap",
   793  			},
   794  			ObjectMeta: v12.ObjectMeta{
   795  				Name: "bar",
   796  			},
   797  			Data: map[string]string{
   798  				"myvar": "bar",
   799  			},
   800  		},
   801  		{
   802  			TypeMeta: v12.TypeMeta{
   803  				Kind: "ConfigMap",
   804  			},
   805  			ObjectMeta: v12.ObjectMeta{
   806  				Name: "foo",
   807  			},
   808  			Data: map[string]string{
   809  				"myvar": "foo",
   810  			},
   811  		},
   812  	}
   813  
   814  	optional = true
   815  
   816  	k8sSecrets = []v1.Secret{
   817  		{
   818  			TypeMeta: v12.TypeMeta{
   819  				Kind: "Secret",
   820  			},
   821  			ObjectMeta: v12.ObjectMeta{
   822  				Name: "bar",
   823  			},
   824  			Data: map[string][]byte{
   825  				"myvar": []byte("bar"),
   826  			},
   827  		},
   828  		{
   829  			TypeMeta: v12.TypeMeta{
   830  				Kind: "Secret",
   831  			},
   832  			ObjectMeta: v12.ObjectMeta{
   833  				Name: "foo",
   834  			},
   835  			Data: map[string][]byte{
   836  				"myvar": []byte("foo"),
   837  			},
   838  		},
   839  	}
   840  
   841  	cpuInt       = 4
   842  	cpuString    = strconv.Itoa(cpuInt)
   843  	memoryInt    = 30000000
   844  	memoryString = strconv.Itoa(memoryInt)
   845  	container    = v1.Container{
   846  		Name: "test",
   847  		Resources: v1.ResourceRequirements{
   848  			Limits: v1.ResourceList{
   849  				v1.ResourceCPU:    resource.MustParse(cpuString),
   850  				v1.ResourceMemory: resource.MustParse(memoryString),
   851  			},
   852  			Requests: v1.ResourceList{
   853  				v1.ResourceCPU:    resource.MustParse(cpuString),
   854  				v1.ResourceMemory: resource.MustParse(memoryString),
   855  			},
   856  		},
   857  	}
   858  )