1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ import collections
16+
1517import mock
1618from oslotest import base as test_base
1719from stevedore import extension
2123
2224
2325def counted (fn ):
24- def wrapper (* args , ** kwargs ):
25- wrapper .called += 1
26- return fn (* args , ** kwargs )
27- wrapper .called = 0
28- wrapper .__name__ = fn .__name__
26+ def wrapper (self , * args , ** kwargs ):
27+ try :
28+ counts = self ._call_counts
29+ except AttributeError :
30+ counts = self ._call_counts = collections .Counter ()
31+ counts [fn .__name__ ] += 1
32+ return fn (self , * args , ** kwargs )
2933 return wrapper
3034
3135
3236class FakeGenericHardwareManager (hardware .HardwareManager ):
3337 @counted
3438 def generic_only (self ):
35- return True
39+ return 'generic_only'
40+
41+ @counted
42+ def generic_none (self ):
43+ return None
44+
45+ @counted
46+ def specific_none (self ):
47+ return 'generic'
48+
49+ @counted
50+ def return_list (self ):
51+ return ['generic' ]
3652
3753 @counted
3854 def specific_only (self ):
3955 raise Exception ("Test fail: This method should not be called" )
4056
4157 @counted
4258 def mainline_fail (self ):
43- return True
59+ return 'generic_mainline_fail'
4460
4561 @counted
4662 def both_succeed (self ):
47- return True
63+ return 'generic_both'
4864
4965 @counted
5066 def unexpected_fail (self ):
@@ -58,15 +74,27 @@ def evaluate_hardware_support(self):
5874class FakeMainlineHardwareManager (hardware .HardwareManager ):
5975 @counted
6076 def specific_only (self ):
61- return True
77+ return 'specific_only'
78+
79+ @counted
80+ def generic_none (self ):
81+ return 'specific'
82+
83+ @counted
84+ def specific_none (self ):
85+ return None
86+
87+ @counted
88+ def return_list (self ):
89+ return ['specific' ]
6290
6391 @counted
6492 def mainline_fail (self ):
6593 raise errors .IncompatibleHardwareMethodError
6694
6795 @counted
6896 def both_succeed (self ):
69- return True
97+ return 'specific_both'
7098
7199 @counted
72100 def unexpected_fail (self ):
@@ -83,12 +111,12 @@ def setUp(self):
83111 fake_ep = mock .Mock ()
84112 fake_ep .module_name = 'fake'
85113 fake_ep .attrs = ['fake attrs' ]
86- ext1 = extension .Extension ('fake_generic' , fake_ep , None ,
114+ self . generic_hwm = extension .Extension ('fake_generic' , fake_ep , None ,
87115 FakeGenericHardwareManager ())
88- ext2 = extension .Extension ('fake_mainline' , fake_ep , None ,
116+ self . mainline_hwm = extension .Extension ('fake_mainline' , fake_ep , None ,
89117 FakeMainlineHardwareManager ())
90118 self .fake_ext_mgr = extension .ExtensionManager .make_test_instance ([
91- ext1 , ext2
119+ self . generic_hwm , self . mainline_hwm
92120 ])
93121
94122 self .extension_mgr_patcher = mock .patch ('stevedore.ExtensionManager' )
@@ -103,30 +131,32 @@ def tearDown(self):
103131 def test_mainline_method_only (self ):
104132 hardware .dispatch_to_managers ('specific_only' )
105133
106- self .assertEqual (1 , FakeMainlineHardwareManager .specific_only .called )
134+ self .assertEqual (
135+ 1 , self .mainline_hwm .obj ._call_counts ['specific_only' ])
107136
108137 def test_generic_method_only (self ):
109138 hardware .dispatch_to_managers ('generic_only' )
110139
111- self .assertEqual (1 , FakeGenericHardwareManager . generic_only . called )
140+ self .assertEqual (1 , self . generic_hwm . obj . _call_counts [ 'generic_only' ] )
112141
113142 def test_both_succeed (self ):
114143 """In the case where both managers will work; only the most specific
115144 manager should have it's function called.
116145 """
117146 hardware .dispatch_to_managers ('both_succeed' )
118147
119- self .assertEqual (1 , FakeMainlineHardwareManager . both_succeed . called )
120- self .assertEqual (0 , FakeGenericHardwareManager . both_succeed . called )
148+ self .assertEqual (1 , self . mainline_hwm . obj . _call_counts [ 'both_succeed' ] )
149+ self .assertEqual (0 , self . generic_hwm . obj . _call_counts [ 'both_succeed' ] )
121150
122151 def test_mainline_fails (self ):
123152 """Ensure that if the mainline manager is unable to run the method
124153 that we properly fall back to generic.
125154 """
126155 hardware .dispatch_to_managers ('mainline_fail' )
127156
128- self .assertEqual (1 , FakeMainlineHardwareManager .mainline_fail .called )
129- self .assertEqual (1 , FakeGenericHardwareManager .mainline_fail .called )
157+ self .assertEqual (
158+ 1 , self .mainline_hwm .obj ._call_counts ['mainline_fail' ])
159+ self .assertEqual (1 , self .generic_hwm .obj ._call_counts ['mainline_fail' ])
130160
131161 def test_manager_method_not_found (self ):
132162 self .assertRaises (errors .HardwareManagerMethodNotFound ,
@@ -138,6 +168,53 @@ def test_method_fails(self):
138168 hardware .dispatch_to_managers ,
139169 'unexpected_fail' )
140170
171+ def test_dispatch_to_all_managers_mainline_only (self ):
172+ results = hardware .dispatch_to_all_managers ('generic_none' )
173+
174+ self .assertEqual (1 , self .generic_hwm .obj ._call_counts ['generic_none' ])
175+ self .assertEqual ({'FakeGenericHardwareManager' : None ,
176+ 'FakeMainlineHardwareManager' : 'specific' },
177+ results )
178+
179+ def test_dispatch_to_all_managers_generic_method_only (self ):
180+ results = hardware .dispatch_to_all_managers ('specific_none' )
181+
182+ self .assertEqual (1 , self .generic_hwm .obj ._call_counts ['specific_none' ])
183+ self .assertEqual ({'FakeGenericHardwareManager' : 'generic' ,
184+ 'FakeMainlineHardwareManager' : None }, results )
185+
186+ def test_dispatch_to_all_managers_both_succeed (self ):
187+ """In the case where both managers will work; only the most specific
188+ manager should have it's function called.
189+ """
190+ results = hardware .dispatch_to_all_managers ('both_succeed' )
191+
192+ self .assertEqual ({'FakeGenericHardwareManager' : 'generic_both' ,
193+ 'FakeMainlineHardwareManager' : 'specific_both' },
194+ results )
195+ self .assertEqual (1 , self .mainline_hwm .obj ._call_counts ['both_succeed' ])
196+ self .assertEqual (1 , self .generic_hwm .obj ._call_counts ['both_succeed' ])
197+
198+ def test_dispatch_to_all_managers_mainline_fails (self ):
199+ """Ensure that if the mainline manager is unable to run the method
200+ that we properly fall back to generic.
201+ """
202+ hardware .dispatch_to_all_managers ('mainline_fail' )
203+
204+ self .assertEqual (
205+ 1 , self .mainline_hwm .obj ._call_counts ['mainline_fail' ])
206+ self .assertEqual (1 , self .generic_hwm .obj ._call_counts ['mainline_fail' ])
207+
208+ def test_dispatch_to_all_managers_manager_method_not_found (self ):
209+ self .assertRaises (errors .HardwareManagerMethodNotFound ,
210+ hardware .dispatch_to_all_managers ,
211+ 'unknown_method' )
212+
213+ def test_dispatch_to_all_managers_method_fails (self ):
214+ self .assertRaises (RuntimeError ,
215+ hardware .dispatch_to_all_managers ,
216+ 'unexpected_fail' )
217+
141218
142219class TestNoHardwareManagerLoading (test_base .BaseTestCase ):
143220 def setUp (self ):
0 commit comments