@@ -2283,6 +2283,95 @@ func TestClient_AddSession(t *testing.T) {
22832283 }
22842284}
22852285
2286+ func TestClient_filterDevicesBySize (t * testing.T ) {
2287+ mockCtrl := gomock .NewController (t )
2288+ mockDevices := mock_devices .NewMockDevices (mockCtrl )
2289+
2290+ client := NewDetailed (
2291+ "" ,
2292+ nil ,
2293+ nil ,
2294+ nil ,
2295+ mockDevices ,
2296+ nil ,
2297+ nil ,
2298+ nil ,
2299+ afero.Afero {},
2300+ nil ,
2301+ )
2302+
2303+ ctx := context .TODO ()
2304+ deviceInfo := & models.ScsiDeviceInfo {
2305+ Devices : []string {"sda" , "sdb" },
2306+ }
2307+ minSize := int64 (10 )
2308+
2309+ // Negative case.
2310+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sda" ).Return (int64 (1 ), nil )
2311+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sdb" ).Return (int64 (0 ), errors .New ("failed to open disk" ))
2312+ deviceSizeMap , err := client .filterDevicesBySize (ctx , deviceInfo , minSize )
2313+ assert .Error (t , err )
2314+ assert .Nil (t , deviceSizeMap )
2315+ assert .NotEqual (t , len (deviceInfo .Devices ), len (deviceSizeMap ))
2316+
2317+ // Positive case #1: Only one device needs a resize.
2318+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sda" ).Return (minSize , nil )
2319+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sdb" ).Return (int64 (1 ), nil )
2320+ deviceSizeMap , err = client .filterDevicesBySize (ctx , deviceInfo , minSize )
2321+ assert .NoError (t , err )
2322+ assert .NotNil (t , deviceSizeMap )
2323+ assert .NotEqual (t , len (deviceInfo .Devices ), len (deviceSizeMap ))
2324+
2325+ // Positive case #2: All devices need to resize.
2326+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sda" ).Return (int64 (1 ), nil )
2327+ mockDevices .EXPECT ().GetDiskSize (ctx , "/dev/sdb" ).Return (int64 (1 ), nil )
2328+ deviceSizeMap , err = client .filterDevicesBySize (ctx , deviceInfo , minSize )
2329+ assert .NoError (t , err )
2330+ assert .NotNil (t , deviceSizeMap )
2331+ assert .Equal (t , len (deviceInfo .Devices ), len (deviceSizeMap ))
2332+ }
2333+
2334+ func TestClient_rescanDevices (t * testing.T ) {
2335+ mockCtrl := gomock .NewController (t )
2336+ mockDevices := mock_devices .NewMockDevices (mockCtrl )
2337+
2338+ fs := afero .NewMemMapFs ()
2339+ _ , err := fs .Create ("/sys/block/sda/device/rescan" )
2340+ assert .NoError (t , err )
2341+
2342+ client := NewDetailed (
2343+ "" ,
2344+ nil ,
2345+ nil ,
2346+ nil ,
2347+ mockDevices ,
2348+ nil ,
2349+ nil ,
2350+ nil ,
2351+ afero.Afero {Fs : fs },
2352+ nil ,
2353+ )
2354+
2355+ ctx := context .TODO ()
2356+ deviceSizeMap := map [string ]int64 {
2357+ "sda" : 1 ,
2358+ "sdb" : 1 ,
2359+ }
2360+
2361+ // Should fail because a device path does not exist.
2362+ mockDevices .EXPECT ().ListAllDevices (ctx ).AnyTimes ()
2363+ err = client .rescanDevices (ctx , deviceSizeMap )
2364+ assert .Error (t , err )
2365+
2366+ // Add the missing device path.
2367+ _ , err = fs .Create ("/sys/block/sdb/device/rescan" )
2368+ assert .NoError (t , err )
2369+
2370+ // Should succeed now that the device path exists.
2371+ err = client .rescanDevices (ctx , deviceSizeMap )
2372+ assert .NoError (t , err )
2373+ }
2374+
22862375func TestClient_RescanDevices (t * testing.T ) {
22872376 type parameters struct {
22882377 targetIQN string
@@ -2447,8 +2536,12 @@ func TestClient_RescanDevices(t *testing.T) {
24472536 getDeviceClient : func (controller * gomock.Controller ) devices.Devices {
24482537 mockDevices := mock_devices .NewMockDevices (controller )
24492538 mockDevices .EXPECT ().FindMultipathDeviceForDevice (context .TODO (), "sda" ).Return ("dm-0" ).Times (1 )
2539+
2540+ // This will be called twice because we read from each disk twice during an expansion.
2541+ mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/sda" ).Return (int64 (0 ), nil ).Times (1 )
2542+ mockDevices .EXPECT ().ListAllDevices (context .TODO ()).Times (2 )
24502543 mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/sda" ).Return (int64 (1 ), nil ).Times (1 )
2451- mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/dm-0" ).Return (int64 (1 ), nil ). Times ( 1 )
2544+ mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/dm-0" ).Return (int64 (1 ), nil )
24522545 return mockDevices
24532546 },
24542547 getCommandClient : func (controller * gomock.Controller ) tridentexec.Command {
@@ -2684,6 +2777,7 @@ func TestClient_RescanDevices(t *testing.T) {
26842777 assertError : assert .NoError ,
26852778 },
26862779 "happy path" : {
2780+ minSize : 10 ,
26872781 targetIQN : targetIQN ,
26882782 getReconcileUtils : func (controller * gomock.Controller ) IscsiReconcileUtils {
26892783 mockReconcileUtils := mock_iscsi .NewMockIscsiReconcileUtils (controller )
@@ -2696,8 +2790,12 @@ func TestClient_RescanDevices(t *testing.T) {
26962790 getDeviceClient : func (controller * gomock.Controller ) devices.Devices {
26972791 mockDevices := mock_devices .NewMockDevices (controller )
26982792 mockDevices .EXPECT ().FindMultipathDeviceForDevice (context .TODO (), "sda" ).Return ("dm-0" ).Times (1 )
2699- mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/sda" ).Return (int64 (0 ), nil )
2700- mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/dm-0" ).Return (int64 (0 ), nil )
2793+
2794+ // This will be called twice because we read from each disk twice during an expansion.
2795+ mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/sda" ).Return (int64 (0 ), nil ).Times (1 )
2796+ mockDevices .EXPECT ().ListAllDevices (context .TODO ()).Times (2 )
2797+ mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/sda" ).Return (int64 (10 ), nil ).Times (1 )
2798+ mockDevices .EXPECT ().GetDiskSize (context .TODO (), "/dev/dm-0" ).Return (int64 (10 ), nil )
27012799 return mockDevices
27022800 },
27032801 getCommandClient : func (controller * gomock.Controller ) tridentexec.Command {
@@ -2706,6 +2804,8 @@ func TestClient_RescanDevices(t *testing.T) {
27062804 },
27072805 getFileSystemUtils : func () afero.Fs {
27082806 fs := afero .NewMemMapFs ()
2807+ _ , err := fs .Create ("/sys/block/sda/device/rescan" )
2808+ assert .NoError (t , err )
27092809 return fs
27102810 },
27112811 assertError : assert .NoError ,
@@ -2728,110 +2828,6 @@ func TestClient_RescanDevices(t *testing.T) {
27282828 }
27292829}
27302830
2731- func TestClient_rescanDisk (t * testing.T ) {
2732- type parameters struct {
2733- getFileSystemUtils func () afero.Fs
2734- assertError assert.ErrorAssertionFunc
2735- getDevices func (controller * gomock.Controller ) devices.Devices
2736- }
2737- const deviceName = "sda"
2738- tests := map [string ]parameters {
2739- "happy path" : {
2740- getFileSystemUtils : func () afero.Fs {
2741- fs := afero .NewMemMapFs ()
2742- _ , err := fs .Create (fmt .Sprintf ("/sys/block/%s/device/rescan" , deviceName ))
2743- assert .NoError (t , err )
2744- return fs
2745- },
2746- getDevices : func (controller * gomock.Controller ) devices.Devices {
2747- mockDevices := mock_devices .NewMockDevices (controller )
2748- mockDevices .EXPECT ().ListAllDevices (context .TODO ()).Times (2 )
2749- return mockDevices
2750- },
2751- assertError : assert .NoError ,
2752- },
2753- "error opening rescan file" : {
2754- getFileSystemUtils : func () afero.Fs {
2755- fs := afero .NewMemMapFs ()
2756- return fs
2757- },
2758- getDevices : func (controller * gomock.Controller ) devices.Devices {
2759- mockDevices := mock_devices .NewMockDevices (controller )
2760- mockDevices .EXPECT ().ListAllDevices (context .TODO ())
2761- return mockDevices
2762- },
2763- assertError : assert .Error ,
2764- },
2765- "error writing to file" : {
2766- getFileSystemUtils : func () afero.Fs {
2767- f := & aferoFileWrapper {
2768- WriteStringError : errors .New ("some error" ),
2769- File : mem .NewFileHandle (& mem.FileData {}),
2770- }
2771-
2772- memMapFs := afero .NewMemMapFs ()
2773- _ , err := memMapFs .Create (fmt .Sprintf ("/sys/block/%s/device/rescan" , deviceName ))
2774- assert .NoError (t , err )
2775-
2776- fs := & aferoWrapper {
2777- openFileResponse : f ,
2778- openResponse : f ,
2779- Fs : memMapFs ,
2780- }
2781-
2782- return fs
2783- },
2784- getDevices : func (controller * gomock.Controller ) devices.Devices {
2785- mockDevices := mock_devices .NewMockDevices (controller )
2786- mockDevices .EXPECT ().ListAllDevices (context .TODO ())
2787- return mockDevices
2788- },
2789- assertError : assert .Error ,
2790- },
2791- "failed writing to file" : {
2792- getFileSystemUtils : func () afero.Fs {
2793- f := & aferoFileWrapper {
2794- WriteStringCount : 0 ,
2795- File : mem .NewFileHandle (& mem.FileData {}),
2796- }
2797-
2798- memMapFs := afero .NewMemMapFs ()
2799- _ , err := memMapFs .Create (fmt .Sprintf ("/sys/block/%s/device/rescan" , deviceName ))
2800- assert .NoError (t , err )
2801-
2802- fs := & aferoWrapper {
2803- openFileResponse : f ,
2804- openResponse : f ,
2805- Fs : memMapFs ,
2806- }
2807-
2808- return fs
2809- },
2810- getDevices : func (controller * gomock.Controller ) devices.Devices {
2811- mockDevices := mock_devices .NewMockDevices (controller )
2812- mockDevices .EXPECT ().ListAllDevices (context .TODO ())
2813- return mockDevices
2814- },
2815- assertError : assert .Error ,
2816- },
2817- }
2818-
2819- for name , params := range tests {
2820- t .Run (name , func (t * testing.T ) {
2821- var deviceClient devices.Devices
2822- if params .getDevices != nil {
2823- deviceClient = params .getDevices (gomock .NewController (t ))
2824- }
2825- client := NewDetailed ("" , nil , nil , nil , deviceClient , nil , nil , nil ,
2826- afero.Afero {Fs : params .getFileSystemUtils ()}, nil )
2827- err := client .rescanDisk (context .TODO (), deviceName )
2828- if params .assertError != nil {
2829- params .assertError (t , err )
2830- }
2831- })
2832- }
2833- }
2834-
28352831func TestClient_reloadMultipathDevice (t * testing.T ) {
28362832 type parameters struct {
28372833 multipathDeviceName string
0 commit comments