github.com/containerd/nerdctl/v2@v2.0.0-beta.5.0.20240520001846-b5758f54fa28/pkg/cmd/builder/build_test.go (about)

     1  /*
     2     Copyright The containerd 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 builder
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/containerd/containerd/platforms"
    24  	"go.uber.org/mock/gomock"
    25  	"gotest.tools/v3/assert"
    26  )
    27  
    28  type MockParse struct {
    29  	ctrl     *gomock.Controller
    30  	recorder *MockParseRecorder
    31  }
    32  
    33  type MockParseRecorder struct {
    34  	mock *MockParse
    35  }
    36  
    37  func newMockParser(ctrl *gomock.Controller) *MockParse {
    38  	mock := &MockParse{ctrl: ctrl}
    39  	mock.recorder = &MockParseRecorder{mock}
    40  	return mock
    41  }
    42  
    43  func (m *MockParse) EXPECT() *MockParseRecorder {
    44  	return m.recorder
    45  }
    46  
    47  func (m *MockParse) Parse(platform string) (platforms.Platform, error) {
    48  	m.ctrl.T.Helper()
    49  	ret := m.ctrl.Call(m, "Parse")
    50  	ret0, _ := ret[0].(platforms.Platform)
    51  	ret1, _ := ret[1].(error)
    52  	return ret0, ret1
    53  }
    54  
    55  func (m *MockParseRecorder) Parse(platform string) *gomock.Call {
    56  	m.mock.ctrl.T.Helper()
    57  	return m.mock.ctrl.RecordCallWithMethodType(m.mock, "Parse", reflect.TypeOf((*MockParse)(nil).Parse))
    58  }
    59  
    60  func (m *MockParse) DefaultSpec() platforms.Platform {
    61  	m.ctrl.T.Helper()
    62  	ret := m.ctrl.Call(m, "DefaultSpec")
    63  	ret0, _ := ret[0].(platforms.Platform)
    64  	return ret0
    65  }
    66  
    67  func (m *MockParseRecorder) DefaultSpec() *gomock.Call {
    68  	m.mock.ctrl.T.Helper()
    69  	return m.mock.ctrl.RecordCallWithMethodType(m.mock, "DefaultSpec", reflect.TypeOf((*MockParse)(nil).DefaultSpec))
    70  }
    71  
    72  func TestIsMatchingRuntimePlatform(t *testing.T) {
    73  	t.Parallel()
    74  
    75  	testCases := []struct {
    76  		name string
    77  		mock func(*MockParse)
    78  		want bool
    79  	}{
    80  		{
    81  			name: "Image is shareable when Runtime and build platform match for os, arch and variant",
    82  			mock: func(mockParser *MockParse) {
    83  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"}, nil)
    84  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
    85  			},
    86  			want: true,
    87  		},
    88  		{
    89  			name: "Image is shareable when Runtime and build platform match for os, arch. Variant is not defined",
    90  			mock: func(mockParser *MockParse) {
    91  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: ""}, nil)
    92  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
    93  			},
    94  			want: true,
    95  		},
    96  		{
    97  			name: "Image is not shareable when Runtime and build platform donot math OS",
    98  			mock: func(mockParser *MockParse) {
    99  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "OS", Architecture: "mockArch", Variant: ""}, nil)
   100  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
   101  			},
   102  			want: false,
   103  		},
   104  		{
   105  			name: "Image is not shareable when Runtime and build platform donot math Arch",
   106  			mock: func(mockParser *MockParse) {
   107  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "mockOS", Architecture: "Arch", Variant: ""}, nil)
   108  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
   109  			},
   110  			want: false,
   111  		},
   112  		{
   113  			name: "Image is not shareable when Runtime and build platform donot math Variant",
   114  			mock: func(mockParser *MockParse) {
   115  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "Variant"}, nil)
   116  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
   117  			},
   118  			want: false,
   119  		},
   120  	}
   121  
   122  	for _, tc := range testCases {
   123  		tc := tc
   124  		t.Run(tc.name, func(t *testing.T) {
   125  			t.Parallel()
   126  
   127  			ctrl := gomock.NewController(t)
   128  			mockParser := newMockParser(ctrl)
   129  			tc.mock(mockParser)
   130  			r := isMatchingRuntimePlatform("test", mockParser)
   131  			assert.Equal(t, r, tc.want, tc.name)
   132  		})
   133  	}
   134  }
   135  
   136  func TestIsBuildPlatformDefault(t *testing.T) {
   137  	t.Parallel()
   138  
   139  	testCases := []struct {
   140  		name     string
   141  		mock     func(*MockParse)
   142  		platform []string
   143  		want     bool
   144  	}{
   145  		{
   146  			name:     "Image is shreable when len of platform is 0",
   147  			platform: make([]string, 0),
   148  			want:     true,
   149  		},
   150  		{
   151  			name:     "Image is shareable when Runtime and build platform match for os, arch and variant",
   152  			platform: []string{"test"},
   153  			mock: func(mockParser *MockParse) {
   154  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"}, nil)
   155  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
   156  			},
   157  			want: true,
   158  		},
   159  		{
   160  			name:     "Image is not shareable when Runtime build platform dont match",
   161  			platform: []string{"test"},
   162  			mock: func(mockParser *MockParse) {
   163  				mockParser.EXPECT().Parse("test").Return(platforms.Platform{OS: "OS", Architecture: "mockArch", Variant: "mockVariant"}, nil)
   164  				mockParser.EXPECT().DefaultSpec().Return(platforms.Platform{OS: "mockOS", Architecture: "mockArch", Variant: "mockVariant"})
   165  			},
   166  			want: false,
   167  		},
   168  		{
   169  			name:     "Image is not shareable when more than 2 platforms are passed",
   170  			platform: []string{"test1", "test2"},
   171  			want:     false,
   172  		},
   173  	}
   174  
   175  	for _, tc := range testCases {
   176  		tc := tc
   177  		t.Run(tc.name, func(t *testing.T) {
   178  			t.Parallel()
   179  
   180  			ctrl := gomock.NewController(t)
   181  			mockParser := newMockParser(ctrl)
   182  			if len(tc.platform) == 1 {
   183  				tc.mock(mockParser)
   184  			}
   185  			r := isBuildPlatformDefault(tc.platform, mockParser)
   186  			assert.Equal(t, r, tc.want, tc.name)
   187  		})
   188  	}
   189  }