@@ -130,6 +130,8 @@ def test_get_vf_count_and_functions(self, gim, gidn):
130130 name: enp[4-5]
131131 enp0:
132132 mtu: 9000
133+ enp8:
134+ virtual-function-count: 7
133135 enp9: {}
134136 wlp6s0: {}
135137 enp1s16f1:
@@ -151,7 +153,7 @@ def test_get_vf_count_and_functions(self, gim, gidn):
151153 link: enp9
152154''' , file = fd )
153155 self .configmanager .parse ()
154- interfaces = ['enp1' , 'enp2' , 'enp3' , 'enp5' , 'enp0' ]
156+ interfaces = ['enp1' , 'enp2' , 'enp3' , 'enp5' , 'enp0' , 'enp8' ]
155157 vf_counts = defaultdict (int )
156158 vfs = {}
157159 pfs = {}
@@ -162,7 +164,7 @@ def test_get_vf_count_and_functions(self, gim, gidn):
162164 # check if the right vf counts have been recorded in vf_counts
163165 self .assertDictEqual (
164166 vf_counts ,
165- {'enp1' : 2 , 'enp2' : 2 , 'enp3' : 1 , 'enp5' : 1 })
167+ {'enp1' : 2 , 'enp2' : 2 , 'enp3' : 1 , 'enp5' : 1 , 'enp8' : 7 })
166168 # also check if the vfs and pfs dictionaries got properly set
167169 self .assertDictEqual (
168170 vfs ,
@@ -171,7 +173,7 @@ def test_get_vf_count_and_functions(self, gim, gidn):
171173 self .assertDictEqual (
172174 pfs ,
173175 {'enp1' : 'enp1' , 'enp2' : 'enp2' , 'enp3' : 'enp3' ,
174- 'enpx' : 'enp5' })
176+ 'enpx' : 'enp5' , 'enp8' : 'enp8' })
175177
176178 @patch ('netplan.cli.utils.get_interface_driver_name' )
177179 @patch ('netplan.cli.utils.get_interface_macaddress' )
@@ -207,24 +209,60 @@ def test_get_vf_count_and_functions_many_match(self, gim, gidn):
207209 self .assertIn ('matched more than one interface for a PF device: enpx' ,
208210 str (e .exception ))
209211
212+ @patch ('netplan.cli.utils.get_interface_driver_name' )
213+ @patch ('netplan.cli.utils.get_interface_macaddress' )
214+ def test_get_vf_count_and_functions_not_enough_explicit (self , gim , gidn ):
215+ # we mock-out get_interface_driver_name and get_interface_macaddress
216+ # to return useful values for the test
217+ gim .side_effect = lambda x : '00:01:02:03:04:05' if x == 'enp3' else '00:00:00:00:00:00'
218+ gidn .side_effect = lambda x : 'foo' if x == 'enp2' else 'bar'
219+ with open (os .path .join (self .workdir .name , "etc/netplan/test.yaml" ), 'w' ) as fd :
220+ print ('''network:
221+ version: 2
222+ renderer: networkd
223+ ethernets:
224+ renderer: networkd
225+ enp1:
226+ virtual-function-count: 2
227+ mtu: 9000
228+ enp1s16f1:
229+ link: enp1
230+ enp1s16f2:
231+ link: enp1
232+ enp1s16f3:
233+ link: enp1
234+ ''' , file = fd )
235+ self .configmanager .parse ()
236+ interfaces = ['enp1' , 'wlp6s0' ]
237+ vf_counts = defaultdict (int )
238+ vfs = {}
239+ pfs = {}
240+
241+ # call the function under test
242+ with self .assertRaises (ConfigurationError ) as e :
243+ sriov .get_vf_count_and_functions (interfaces , self .configmanager ,
244+ vf_counts , vfs , pfs )
245+
246+ self .assertIn ('more VFs allocated than the explicit size declared: 3 > 2' ,
247+ str (e .exception ))
248+
210249 def test_set_numvfs_for_pf (self ):
211250 sriov_open = MockSRIOVOpen ()
212- sriov_open .read_queue = ['1 \n ' , ' 8\n ' ]
251+ sriov_open .read_queue = ['8\n ' ]
213252
214253 with patch ('builtins.open' , sriov_open .open ):
215254 ret = sriov .set_numvfs_for_pf ('enp1' , 2 )
216255
217256 self .assertTrue (ret )
218257 self .assertListEqual (sriov_open .open .call_args_list ,
219- [call ('/sys/class/net/enp1/device/sriov_numvfs' ),
220- call ('/sys/class/net/enp1/device/sriov_totalvfs' ),
258+ [call ('/sys/class/net/enp1/device/sriov_totalvfs' ),
221259 call ('/sys/class/net/enp1/device/sriov_numvfs' , 'w' )])
222260 handle = sriov_open .open ()
223261 handle .write .assert_called_once_with ('2' )
224262
225263 def test_set_numvfs_for_pf_failsafe (self ):
226264 sriov_open = MockSRIOVOpen ()
227- sriov_open .read_queue = ['1 \n ' , ' 8\n ' ]
265+ sriov_open .read_queue = ['8\n ' ]
228266 sriov_open .write_queue = [IOError (16 , 'Error' ), None , None ]
229267
230268 with patch ('builtins.open' , sriov_open .open ):
@@ -236,7 +274,7 @@ def test_set_numvfs_for_pf_failsafe(self):
236274
237275 def test_set_numvfs_for_pf_over_max (self ):
238276 sriov_open = MockSRIOVOpen ()
239- sriov_open .read_queue = ['1 \n ' , ' 8\n ' ]
277+ sriov_open .read_queue = ['8\n ' ]
240278
241279 with patch ('builtins.open' , sriov_open .open ):
242280 with self .assertRaises (ConfigurationError ) as e :
@@ -247,7 +285,7 @@ def test_set_numvfs_for_pf_over_max(self):
247285
248286 def test_set_numvfs_for_pf_over_theoretical_max (self ):
249287 sriov_open = MockSRIOVOpen ()
250- sriov_open .read_queue = ['1 \n ' , ' 1337\n ' ]
288+ sriov_open .read_queue = ['1337\n ' ]
251289
252290 with patch ('builtins.open' , sriov_open .open ):
253291 with self .assertRaises (ConfigurationError ) as e :
@@ -256,24 +294,11 @@ def test_set_numvfs_for_pf_over_theoretical_max(self):
256294 self .assertIn ('cannot allocate more VFs for PF enp1 than the SR-IOV maximum' ,
257295 str (e .exception ))
258296
259- def test_set_numvfs_for_pf_smaller (self ):
260- sriov_open = MockSRIOVOpen ()
261- sriov_open .read_queue = ['4\n ' , '8\n ' ]
262-
263- with patch ('builtins.open' , sriov_open .open ):
264- ret = sriov .set_numvfs_for_pf ('enp1' , 3 )
265-
266- self .assertFalse (ret )
267- handle = sriov_open .open ()
268- self .assertEqual (handle .write .call_count , 0 )
269-
270297 def test_set_numvfs_for_pf_read_failed (self ):
271298 sriov_open = MockSRIOVOpen ()
272299 cases = (
273300 [IOError ],
274301 ['not a number\n ' ],
275- ['1\n ' , IOError ],
276- ['1\n ' , 'not a number\n ' ],
277302 )
278303
279304 with patch ('builtins.open' , sriov_open .open ):
@@ -284,7 +309,7 @@ def test_set_numvfs_for_pf_read_failed(self):
284309
285310 def test_set_numvfs_for_pf_write_failed (self ):
286311 sriov_open = MockSRIOVOpen ()
287- sriov_open .read_queue = ['1 \n ' , ' 8\n ' ]
312+ sriov_open .read_queue = ['8\n ' ]
288313 sriov_open .write_queue = [IOError (16 , 'Error' ), IOError (16 , 'Error' )]
289314
290315 with patch ('builtins.open' , sriov_open .open ):
0 commit comments