Coverage for manila/tests/share/drivers/glusterfs/test_glusterfs_native.py: 99%

120 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright (c) 2014 Red Hat, Inc. 

2# All Rights Reserved. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); you may 

5# not use this file except in compliance with the License. You may obtain 

6# a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

13# License for the specific language governing permissions and limitations 

14# under the License. 

15 

16""" GlusterFS native protocol (glusterfs) driver for shares. 

17 

18Test cases for GlusterFS native protocol driver. 

19""" 

20 

21from unittest import mock 

22 

23import ddt 

24from oslo_config import cfg 

25 

26from manila.common import constants 

27from manila import context 

28from manila import exception 

29from manila.share import configuration as config 

30from manila.share.drivers.glusterfs import common 

31from manila.share.drivers.glusterfs import glusterfs_native 

32from manila import test 

33from manila.tests import fake_utils 

34 

35 

36CONF = cfg.CONF 

37 

38 

39def new_share(**kwargs): 

40 share = { 

41 'id': 'fakeid', 

42 'name': 'fakename', 

43 'size': 1, 

44 'share_proto': 'glusterfs', 

45 } 

46 share.update(kwargs) 

47 return share 

48 

49 

50@ddt.ddt 

51class GlusterfsNativeShareDriverTestCase(test.TestCase): 

52 """Tests GlusterfsNativeShareDriver.""" 

53 

54 def setUp(self): 

55 super(GlusterfsNativeShareDriverTestCase, self).setUp() 

56 fake_utils.stub_out_utils_execute(self) 

57 self._execute = fake_utils.fake_execute 

58 self._context = context.get_admin_context() 

59 

60 self.glusterfs_target1 = 'root@host1:/gv1' 

61 self.glusterfs_target2 = 'root@host2:/gv2' 

62 self.glusterfs_server1 = 'root@host1' 

63 self.glusterfs_server2 = 'root@host2' 

64 self.glusterfs_server1_volumes = 'manila-share-1-1G\nshare1' 

65 self.glusterfs_server2_volumes = 'manila-share-2-2G\nshare2' 

66 self.share1 = new_share( 

67 export_location=self.glusterfs_target1, 

68 status=constants.STATUS_AVAILABLE) 

69 self.share2 = new_share( 

70 export_location=self.glusterfs_target2, 

71 status=constants.STATUS_AVAILABLE) 

72 self.gmgr1 = common.GlusterManager(self.glusterfs_server1, 

73 self._execute, None, None, 

74 requires={'volume': False}) 

75 self.gmgr2 = common.GlusterManager(self.glusterfs_server2, 

76 self._execute, None, None, 

77 requires={'volume': False}) 

78 self.glusterfs_volumes_dict = ( 

79 {'root@host1:/manila-share-1-1G': {'size': 1}, 

80 'root@host2:/manila-share-2-2G': {'size': 2}}) 

81 self.glusterfs_used_vols = set([ 

82 'root@host1:/manila-share-1-1G', 

83 'root@host2:/manila-share-2-2G']) 

84 

85 CONF.set_default('glusterfs_volume_pattern', 

86 r'manila-share-\d+-#{size}G$') 

87 CONF.set_default('driver_handles_share_servers', False) 

88 

89 self.fake_conf = config.Configuration(None) 

90 self.mock_object(common.GlusterManager, 'make_gluster_call') 

91 

92 self._driver = glusterfs_native.GlusterfsNativeShareDriver( 

93 execute=self._execute, 

94 configuration=self.fake_conf) 

95 self.addCleanup(fake_utils.fake_execute_set_repliers, []) 

96 self.addCleanup(fake_utils.fake_execute_clear_log) 

97 

98 def test_supported_protocols(self): 

99 self.assertEqual(('GLUSTERFS', ), 

100 self._driver.supported_protocols) 

101 

102 def test_setup_via_manager(self): 

103 gmgr = mock.Mock() 

104 

105 gmgr.gluster_call = mock.Mock() 

106 gmgr.set_vol_option = mock.Mock() 

107 gmgr.volume = 'fakevol' 

108 gmgr.export = 'fakehost:/fakevol' 

109 gmgr.get_vol_option = mock.Mock( 

110 return_value='glusterfs-server-name,some-other-name') 

111 share = mock.Mock() 

112 settings = ( 

113 ('nfs.export-volumes', False, {}), 

114 ('client.ssl', True, {}), 

115 ('server.ssl', True, {}), 

116 ('server.dynamic-auth', True, {'ignore_failure': True}), 

117 ) 

118 call_args = ( 

119 ('volume', 'stop', 'fakevol', '--mode=script', {'log': mock.ANY}), 

120 ('volume', 'start', 'fakevol', {'log': mock.ANY}), 

121 ) 

122 

123 ret = self._driver._setup_via_manager({'manager': gmgr, 

124 'share': share}) 

125 

126 gmgr.get_vol_option.assert_called_once_with('auth.ssl-allow') 

127 gmgr.set_vol_option.assert_has_calls( 

128 [mock.call(*a[:-1], **a[-1]) for a in settings]) 

129 gmgr.gluster_call.assert_has_calls( 

130 [mock.call(*a[:-1], **a[-1]) for a in call_args]) 

131 self.assertEqual(ret, gmgr.export) 

132 

133 def test_setup_via_manager_with_parent(self): 

134 gmgr = mock.Mock() 

135 gmgr.set_vol_option = mock.Mock() 

136 gmgr.volume = 'fakevol' 

137 gmgr.export = 'fakehost:/fakevol' 

138 gmgr_parent = mock.Mock() 

139 gmgr_parent.get_vol_option = mock.Mock( 

140 return_value=( 

141 'glusterfs-server-name,some-other-name,manila-host.com')) 

142 share = mock.Mock() 

143 share_parent = mock.Mock() 

144 settings = ( 

145 ('auth.ssl-allow', 

146 'glusterfs-server-name,manila-host.com', {}), 

147 ('nfs.export-volumes', False, {}), 

148 ('client.ssl', True, {}), 

149 ('server.ssl', True, {}), 

150 ('server.dynamic-auth', True, {'ignore_failure': True}), 

151 ) 

152 

153 ret = self._driver._setup_via_manager( 

154 {'manager': gmgr, 'share': share}, 

155 {'manager': gmgr_parent, 'share': share_parent}) 

156 

157 gmgr_parent.get_vol_option.assert_called_once_with( 

158 'auth.ssl-allow') 

159 gmgr.set_vol_option.assert_has_calls( 

160 [mock.call(*a[:-1], **a[-1]) for a in settings]) 

161 self.assertEqual(ret, gmgr.export) 

162 

163 @ddt.data(True, False) 

164 def test_setup_via_manager_no_option_data(self, has_parent): 

165 share = mock.Mock() 

166 gmgr = mock.Mock() 

167 if has_parent: 

168 share_parent = mock.Mock() 

169 gmgr_parent = mock.Mock() 

170 share_mgr_parent = {'share': share_parent, 'manager': gmgr_parent} 

171 gmgr_queried = gmgr_parent 

172 else: 

173 share_mgr_parent = None 

174 gmgr_queried = gmgr 

175 gmgr_queried.get_vol_option = mock.Mock(return_value='') 

176 

177 self.assertRaises(exception.GlusterfsException, 

178 self._driver._setup_via_manager, 

179 {'share': share, 'manager': gmgr}, 

180 share_mgr_parent=share_mgr_parent) 

181 

182 gmgr_queried.get_vol_option.assert_called_once_with( 

183 'auth.ssl-allow') 

184 

185 def test_snapshots_are_supported(self): 

186 self.assertTrue(self._driver.snapshots_are_supported) 

187 

188 @ddt.data({'delta': (["oldCN"], []), 'expected': "glusterCN,oldCN"}, 

189 {'delta': (["newCN"], []), 'expected': "glusterCN,newCN,oldCN"}, 

190 {'delta': ([], ["newCN"]), 'expected': "glusterCN,oldCN"}, 

191 {'delta': ([], ["oldCN"]), 'expected': "glusterCN"}) 

192 @ddt.unpack 

193 def test_update_access_via_manager(self, delta, expected): 

194 gluster_mgr = common.GlusterManager(self.glusterfs_target1, 

195 self._execute, None, None) 

196 self.mock_object( 

197 gluster_mgr, 'get_vol_option', mock.Mock( 

198 side_effect=lambda a, *x, **kw: { 

199 'auth.ssl-allow': "glusterCN,oldCN", 

200 'server.dynamic-auth': True}[a])) 

201 self.mock_object(gluster_mgr, 'set_vol_option') 

202 add_rules, delete_rules = ( 

203 map(lambda a: {'access_to': a}, r) for r in delta) 

204 

205 self._driver._update_access_via_manager( 

206 gluster_mgr, self._context, self.share1, add_rules, delete_rules) 

207 

208 argseq = [('auth.ssl-allow', {})] 

209 if delete_rules: 209 ↛ 211line 209 didn't jump to line 211 because the condition on line 209 was always true

210 argseq.append(('server.dynamic-auth', {'boolean': True})) 

211 self.assertEqual([mock.call(a[0], **a[1]) for a in argseq], 

212 gluster_mgr.get_vol_option.call_args_list) 

213 gluster_mgr.set_vol_option.assert_called_once_with('auth.ssl-allow', 

214 expected) 

215 

216 def test_update_access_via_manager_restart(self): 

217 gluster_mgr = common.GlusterManager(self.glusterfs_target1, 

218 self._execute, None, None) 

219 self.mock_object( 

220 gluster_mgr, 'get_vol_option', mock.Mock( 

221 side_effect=lambda a, *x, **kw: { 

222 'auth.ssl-allow': "glusterCN,oldCN", 

223 'server.dynamic-auth': False}[a])) 

224 self.mock_object(gluster_mgr, 'set_vol_option') 

225 self.mock_object(common, '_restart_gluster_vol') 

226 

227 self._driver._update_access_via_manager( 

228 gluster_mgr, self._context, self.share1, [], 

229 [{'access_to': "oldCN"}]) 

230 

231 common._restart_gluster_vol.assert_called_once_with(gluster_mgr) 

232 

233 @ddt.data('common name with space', 'comma,nama') 

234 def test_update_access_via_manager_badcn(self, common_name): 

235 gluster_mgr = common.GlusterManager(self.glusterfs_target1, 

236 self._execute, None, None) 

237 self.mock_object(gluster_mgr, 'get_vol_option', mock.Mock( 

238 return_value="glusterCN,oldCN")) 

239 

240 self.assertRaises(exception.GlusterfsException, 

241 self._driver._update_access_via_manager, 

242 gluster_mgr, self._context, self.share1, 

243 [{'access_to': common_name}], []) 

244 

245 def test_update_share_stats(self): 

246 self._driver._update_share_stats() 

247 

248 test_data = { 

249 'share_backend_name': 'GlusterFS-Native', 

250 'driver_handles_share_servers': False, 

251 'vendor_name': 'Red Hat', 

252 'driver_version': '1.1', 

253 'storage_protocol': 'glusterfs', 

254 'reserved_percentage': 0, 

255 'reserved_snapshot_percentage': 0, 

256 'reserved_share_extend_percentage': 0, 

257 'qos': False, 

258 'total_capacity_gb': 'unknown', 

259 'free_capacity_gb': 'unknown', 

260 'pools': None, 

261 'snapshot_support': True, 

262 'create_share_from_snapshot_support': True, 

263 'revert_to_snapshot_support': False, 

264 'mount_snapshot_support': False, 

265 'share_group_stats': { 

266 'consistent_snapshot_support': None, 

267 }, 

268 'replication_domain': None, 

269 'filter_function': None, 

270 'goodness_function': None, 

271 'mount_point_name_support': False, 

272 'ipv4_support': True, 

273 'ipv6_support': False, 

274 'security_service_update_support': False, 

275 'share_server_multiple_subnet_support': False, 

276 'network_allocation_update_support': False, 

277 'share_replicas_migration_support': False, 

278 'encryption_support': None, 

279 } 

280 self.assertEqual(test_data, self._driver._stats) 

281 

282 def test_get_network_allocations_number(self): 

283 self.assertEqual(0, self._driver.get_network_allocations_number())