github.com/GoogleCloudPlatform/compute-image-tools/cli_tools@v0.0.0-20240516224744-de2dabc4ed1b/common/utils/param/network_resolver_test.go (about)

     1  //  Copyright 2021 Google Inc. All Rights Reserved.
     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 param
    16  
    17  import (
    18  	"errors"
    19  	"testing"
    20  
    21  	"github.com/golang/mock/gomock"
    22  	"github.com/stretchr/testify/assert"
    23  	"google.golang.org/api/compute/v1"
    24  
    25  	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/mocks"
    26  )
    27  
    28  func TestNetworkResolver_PassingCases(t *testing.T) {
    29  	type getNetworkComputeParams struct{ project, name string }
    30  	type getSubnetComputeParams struct{ project, region, name string }
    31  	tests := []struct {
    32  		name                            string
    33  		originalNetwork, originalSubnet string
    34  		expectedNetwork, expectedSubnet string
    35  		expectedGetNetworkParams        *getNetworkComputeParams
    36  		expectedGetSubnetParams         *getSubnetComputeParams
    37  	}{
    38  		{
    39  			name:                     "expand names to URIs",
    40  			originalNetwork:          "network-id",
    41  			originalSubnet:           "subnet-id",
    42  			expectedNetwork:          "projects/project-id/global/networks/network-id",
    43  			expectedSubnet:           "projects/project-id/regions/region-id/subnetworks/subnet-id",
    44  			expectedGetNetworkParams: &getNetworkComputeParams{"project-id", "network-id"},
    45  			expectedGetSubnetParams:  &getSubnetComputeParams{"project-id", "region-id", "subnet-id"},
    46  		}, {
    47  			name:                     "use default for network when both empty",
    48  			originalNetwork:          "",
    49  			originalSubnet:           "",
    50  			expectedNetwork:          "projects/project-id/global/networks/default",
    51  			expectedSubnet:           "",
    52  			expectedGetNetworkParams: &getNetworkComputeParams{"project-id", "default"},
    53  		}, {
    54  			name:                    "leave network empty when subnet populated",
    55  			originalNetwork:         "",
    56  			originalSubnet:          "subnet-id",
    57  			expectedNetwork:         "",
    58  			expectedSubnet:          "projects/project-id/regions/region-id/subnetworks/subnet-id",
    59  			expectedGetSubnetParams: &getSubnetComputeParams{"project-id", "region-id", "subnet-id"},
    60  		}, {
    61  			name:                     "leave subnet empty when network populated",
    62  			originalNetwork:          "network-id",
    63  			originalSubnet:           "",
    64  			expectedNetwork:          "projects/project-id/global/networks/network-id",
    65  			expectedSubnet:           "",
    66  			expectedGetNetworkParams: &getNetworkComputeParams{"project-id", "network-id"},
    67  		}, {
    68  			name:                     "call API using project and region from original URIs",
    69  			originalNetwork:          "projects/uri-project-id/global/networks/network-id",
    70  			originalSubnet:           "projects/uri-project-id/regions/uri-region-id/subnetworks/subnet-id",
    71  			expectedNetwork:          "projects/uri-project-id/global/networks/network-id",
    72  			expectedSubnet:           "projects/uri-project-id/regions/uri-region-id/subnetworks/subnet-id",
    73  			expectedGetNetworkParams: &getNetworkComputeParams{"uri-project-id", "network-id"},
    74  			expectedGetSubnetParams:  &getSubnetComputeParams{"uri-project-id", "uri-region-id", "subnet-id"},
    75  		},
    76  	}
    77  	for _, tt := range tests {
    78  		t.Run(tt.name, func(t *testing.T) {
    79  			mockCtrl := gomock.NewController(t)
    80  			defer mockCtrl.Finish()
    81  			mockComputeClient := mocks.NewMockClient(mockCtrl)
    82  
    83  			if tt.expectedGetSubnetParams != nil {
    84  				mockComputeClient.EXPECT().GetSubnetwork(tt.expectedGetSubnetParams.project, tt.expectedGetSubnetParams.region, tt.expectedGetSubnetParams.name).Return(&compute.Subnetwork{
    85  					Network: tt.expectedNetwork,
    86  				}, nil)
    87  			}
    88  			if tt.expectedGetNetworkParams != nil {
    89  				mockComputeClient.EXPECT().GetNetwork(tt.expectedGetNetworkParams.project, tt.expectedGetNetworkParams.name).Return(&compute.Network{
    90  					SelfLink: tt.expectedNetwork,
    91  				}, nil)
    92  			}
    93  
    94  			n := NewNetworkResolver(mockComputeClient)
    95  			actualNetwork, actualSubnet, err := n.Resolve(
    96  				tt.originalNetwork, tt.originalSubnet, "region-id", "project-id")
    97  			assert.NoError(t, err)
    98  			assert.Equal(t, tt.expectedNetwork, actualNetwork)
    99  			assert.Equal(t, tt.expectedSubnet, actualSubnet)
   100  		})
   101  	}
   102  }
   103  
   104  func TestNetworkResolver_FailWhenNetworkDoesntContainSubnet(t *testing.T) {
   105  	mockCtrl := gomock.NewController(t)
   106  	defer mockCtrl.Finish()
   107  	mockComputeClient := mocks.NewMockClient(mockCtrl)
   108  
   109  	mockComputeClient.EXPECT().GetSubnetwork("project", "region", "subnet").Return(&compute.Subnetwork{
   110  		Network: "other-network",
   111  	}, nil)
   112  	mockComputeClient.EXPECT().GetNetwork("project", "network").Return(&compute.Network{
   113  		SelfLink: "network",
   114  	}, nil)
   115  
   116  	n := NewNetworkResolver(mockComputeClient)
   117  	_, _, err := n.Resolve(
   118  		"network", "subnet", "region", "project")
   119  	assert.EqualError(t, err, "Network \"projects/project/global/networks/network\" "+
   120  		"does not contain subnet \"projects/project/regions/region/subnetworks/subnet\"")
   121  }
   122  
   123  func TestNetworkResolver_FailWhenNetworkLookupFails(t *testing.T) {
   124  	mockCtrl := gomock.NewController(t)
   125  	defer mockCtrl.Finish()
   126  	mockComputeClient := mocks.NewMockClient(mockCtrl)
   127  
   128  	mockComputeClient.EXPECT().GetNetwork("project", "network").Return(nil, errors.New("failed to lookup network"))
   129  
   130  	n := NewNetworkResolver(mockComputeClient)
   131  	_, _, err := n.Resolve(
   132  		"network", "", "region", "project")
   133  	assert.EqualError(t, err, "Validation of network \"projects/project/global/networks/network\" failed: failed to lookup network")
   134  }
   135  
   136  func TestNetworkResolver_FailWhenSubnetLookupFails(t *testing.T) {
   137  	mockCtrl := gomock.NewController(t)
   138  	defer mockCtrl.Finish()
   139  	mockComputeClient := mocks.NewMockClient(mockCtrl)
   140  
   141  	mockComputeClient.EXPECT().GetSubnetwork("project", "region", "subnet").Return(nil, errors.New("failed to lookup subnet"))
   142  
   143  	n := NewNetworkResolver(mockComputeClient)
   144  	_, _, err := n.Resolve(
   145  		"", "subnet", "region", "project")
   146  	assert.EqualError(t, err, "Validation of subnetwork \"projects/project/regions/region/subnetworks/subnet\" failed: failed to lookup subnet")
   147  }