github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/client/pluginmanager/csimanager/fingerprint_test.go (about)

     1  package csimanager
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/nomad/nomad/structs"
     9  	"github.com/hashicorp/nomad/plugins/csi"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestBuildBasicFingerprint_Node(t *testing.T) {
    14  	tt := []struct {
    15  		Name string
    16  
    17  		Capabilities          *csi.PluginCapabilitySet
    18  		CapabilitiesErr       error
    19  		CapabilitiesCallCount int64
    20  
    21  		NodeInfo          *csi.NodeGetInfoResponse
    22  		NodeInfoErr       error
    23  		NodeInfoCallCount int64
    24  
    25  		ExpectedCSIInfo *structs.CSIInfo
    26  		ExpectedErr     error
    27  	}{
    28  		{
    29  			Name: "Minimal successful response",
    30  
    31  			Capabilities:          &csi.PluginCapabilitySet{},
    32  			CapabilitiesCallCount: 1,
    33  
    34  			NodeInfo: &csi.NodeGetInfoResponse{
    35  				NodeID:             "foobar",
    36  				MaxVolumes:         5,
    37  				AccessibleTopology: nil,
    38  			},
    39  			NodeInfoCallCount: 1,
    40  
    41  			ExpectedCSIInfo: &structs.CSIInfo{
    42  				PluginID:          "test-plugin",
    43  				Healthy:           false,
    44  				HealthDescription: "initial fingerprint not completed",
    45  				NodeInfo: &structs.CSINodeInfo{
    46  					ID:         "foobar",
    47  					MaxVolumes: 5,
    48  				},
    49  			},
    50  		},
    51  		{
    52  			Name: "Successful response with capabilities and topologies",
    53  
    54  			Capabilities:          csi.NewTestPluginCapabilitySet(true, false),
    55  			CapabilitiesCallCount: 1,
    56  
    57  			NodeInfo: &csi.NodeGetInfoResponse{
    58  				NodeID:     "foobar",
    59  				MaxVolumes: 5,
    60  				AccessibleTopology: &csi.Topology{
    61  					Segments: map[string]string{
    62  						"com.hashicorp.nomad/node-id": "foobar",
    63  					},
    64  				},
    65  			},
    66  			NodeInfoCallCount: 1,
    67  
    68  			ExpectedCSIInfo: &structs.CSIInfo{
    69  				PluginID:          "test-plugin",
    70  				Healthy:           false,
    71  				HealthDescription: "initial fingerprint not completed",
    72  
    73  				RequiresTopologies: true,
    74  
    75  				NodeInfo: &structs.CSINodeInfo{
    76  					ID:         "foobar",
    77  					MaxVolumes: 5,
    78  					AccessibleTopology: &structs.CSITopology{
    79  						Segments: map[string]string{
    80  							"com.hashicorp.nomad/node-id": "foobar",
    81  						},
    82  					},
    83  				},
    84  			},
    85  		},
    86  		{
    87  			Name: "PluginGetCapabilities Failed",
    88  
    89  			CapabilitiesErr:       errors.New("request failed"),
    90  			CapabilitiesCallCount: 1,
    91  
    92  			NodeInfoCallCount: 0,
    93  
    94  			ExpectedCSIInfo: &structs.CSIInfo{
    95  				PluginID:          "test-plugin",
    96  				Healthy:           false,
    97  				HealthDescription: "initial fingerprint not completed",
    98  				NodeInfo:          &structs.CSINodeInfo{},
    99  			},
   100  			ExpectedErr: errors.New("request failed"),
   101  		},
   102  		{
   103  			Name: "NodeGetInfo Failed",
   104  
   105  			Capabilities:          &csi.PluginCapabilitySet{},
   106  			CapabilitiesCallCount: 1,
   107  
   108  			NodeInfoErr:       errors.New("request failed"),
   109  			NodeInfoCallCount: 1,
   110  
   111  			ExpectedCSIInfo: &structs.CSIInfo{
   112  				PluginID:          "test-plugin",
   113  				Healthy:           false,
   114  				HealthDescription: "initial fingerprint not completed",
   115  				NodeInfo:          &structs.CSINodeInfo{},
   116  			},
   117  			ExpectedErr: errors.New("request failed"),
   118  		},
   119  	}
   120  
   121  	for _, test := range tt {
   122  		t.Run(test.Name, func(t *testing.T) {
   123  			client, im := setupTestNodeInstanceManager(t)
   124  
   125  			client.NextPluginGetCapabilitiesResponse = test.Capabilities
   126  			client.NextPluginGetCapabilitiesErr = test.CapabilitiesErr
   127  
   128  			client.NextNodeGetInfoResponse = test.NodeInfo
   129  			client.NextNodeGetInfoErr = test.NodeInfoErr
   130  
   131  			info, err := im.fp.buildBasicFingerprint(context.Background())
   132  
   133  			require.Equal(t, test.ExpectedCSIInfo, info)
   134  			require.Equal(t, test.ExpectedErr, err)
   135  
   136  			require.Equal(t, test.CapabilitiesCallCount, client.PluginGetCapabilitiesCallCount)
   137  			require.Equal(t, test.NodeInfoCallCount, client.NodeGetInfoCallCount)
   138  		})
   139  	}
   140  }
   141  
   142  func TestBuildControllerFingerprint(t *testing.T) {
   143  	tt := []struct {
   144  		Name string
   145  
   146  		Capabilities          *csi.ControllerCapabilitySet
   147  		CapabilitiesErr       error
   148  		CapabilitiesCallCount int64
   149  
   150  		ProbeResponse  bool
   151  		ProbeErr       error
   152  		ProbeCallCount int64
   153  
   154  		ExpectedControllerInfo *structs.CSIControllerInfo
   155  		ExpectedErr            error
   156  	}{
   157  		{
   158  			Name: "Minimal successful response",
   159  
   160  			Capabilities:          &csi.ControllerCapabilitySet{},
   161  			CapabilitiesCallCount: 1,
   162  
   163  			ProbeResponse:  true,
   164  			ProbeCallCount: 1,
   165  
   166  			ExpectedControllerInfo: &structs.CSIControllerInfo{},
   167  		},
   168  		{
   169  			Name: "Successful response with capabilities",
   170  
   171  			Capabilities: &csi.ControllerCapabilitySet{
   172  				HasListVolumes: true,
   173  			},
   174  			CapabilitiesCallCount: 1,
   175  
   176  			ProbeResponse:  true,
   177  			ProbeCallCount: 1,
   178  
   179  			ExpectedControllerInfo: &structs.CSIControllerInfo{
   180  				SupportsListVolumes: true,
   181  			},
   182  		},
   183  		{
   184  			Name: "ControllerGetCapabilities Failed",
   185  
   186  			CapabilitiesErr:       errors.New("request failed"),
   187  			CapabilitiesCallCount: 1,
   188  
   189  			ProbeResponse:  true,
   190  			ProbeCallCount: 1,
   191  
   192  			ExpectedControllerInfo: &structs.CSIControllerInfo{},
   193  			ExpectedErr:            errors.New("request failed"),
   194  		},
   195  	}
   196  
   197  	for _, test := range tt {
   198  		t.Run(test.Name, func(t *testing.T) {
   199  			client, im := setupTestNodeInstanceManager(t)
   200  
   201  			client.NextControllerGetCapabilitiesResponse = test.Capabilities
   202  			client.NextControllerGetCapabilitiesErr = test.CapabilitiesErr
   203  
   204  			client.NextPluginProbeResponse = test.ProbeResponse
   205  			client.NextPluginProbeErr = test.ProbeErr
   206  
   207  			info, err := im.fp.buildControllerFingerprint(context.Background(), &structs.CSIInfo{ControllerInfo: &structs.CSIControllerInfo{}})
   208  
   209  			require.Equal(t, test.ExpectedControllerInfo, info.ControllerInfo)
   210  			require.Equal(t, test.ExpectedErr, err)
   211  
   212  			require.Equal(t, test.CapabilitiesCallCount, client.ControllerGetCapabilitiesCallCount)
   213  			require.Equal(t, test.ProbeCallCount, client.PluginProbeCallCount)
   214  		})
   215  	}
   216  }
   217  
   218  func TestBuildNodeFingerprint(t *testing.T) {
   219  	tt := []struct {
   220  		Name string
   221  
   222  		Capabilities          *csi.NodeCapabilitySet
   223  		CapabilitiesErr       error
   224  		CapabilitiesCallCount int64
   225  
   226  		ExpectedCSINodeInfo *structs.CSINodeInfo
   227  		ExpectedErr         error
   228  	}{
   229  		{
   230  			Name: "Minimal successful response",
   231  
   232  			Capabilities:          &csi.NodeCapabilitySet{},
   233  			CapabilitiesCallCount: 1,
   234  
   235  			ExpectedCSINodeInfo: &structs.CSINodeInfo{
   236  				RequiresNodeStageVolume: false,
   237  			},
   238  		},
   239  		{
   240  			Name: "Successful response with capabilities and topologies",
   241  
   242  			Capabilities: &csi.NodeCapabilitySet{
   243  				HasStageUnstageVolume: true,
   244  			},
   245  			CapabilitiesCallCount: 1,
   246  
   247  			ExpectedCSINodeInfo: &structs.CSINodeInfo{
   248  				RequiresNodeStageVolume: true,
   249  			},
   250  		},
   251  		{
   252  			Name: "NodeGetCapabilities Failed",
   253  
   254  			CapabilitiesErr:       errors.New("request failed"),
   255  			CapabilitiesCallCount: 1,
   256  
   257  			ExpectedCSINodeInfo: &structs.CSINodeInfo{},
   258  			ExpectedErr:         errors.New("request failed"),
   259  		},
   260  	}
   261  
   262  	for _, test := range tt {
   263  		t.Run(test.Name, func(t *testing.T) {
   264  			client, im := setupTestNodeInstanceManager(t)
   265  
   266  			client.NextNodeGetCapabilitiesResponse = test.Capabilities
   267  			client.NextNodeGetCapabilitiesErr = test.CapabilitiesErr
   268  
   269  			info, err := im.fp.buildNodeFingerprint(context.Background(), &structs.CSIInfo{NodeInfo: &structs.CSINodeInfo{}})
   270  
   271  			require.Equal(t, test.ExpectedCSINodeInfo, info.NodeInfo)
   272  			require.Equal(t, test.ExpectedErr, err)
   273  
   274  			require.Equal(t, test.CapabilitiesCallCount, client.NodeGetCapabilitiesCallCount)
   275  		})
   276  	}
   277  }