Coverage for drivers/DummySR.py : 18%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/python3
2#
3# Copyright (C) Citrix Systems Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published
7# by the Free Software Foundation; version 2.1 only.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17#
18# DummySR: an example dummy SR for the SDK
20import SR
21import VDI
22import SRCommand
23import util
24import time
25import xs_errors
27CAPABILITIES = ["SR_PROBE", "VDI_CREATE", "VDI_DELETE", "VDI_ATTACH", "VDI_DETACH",
28 "VDI_ACTIVATE", "VDI_DEACTIVATE", "VDI_CLONE", "VDI_SNAPSHOT", "VDI_RESIZE",
29 "VDI_INTRODUCE", "VDI_MIRROR"]
31CONFIGURATION = []
33DRIVER_INFO = {
34 'name': 'dummy',
35 'description': 'SR plugin which manages fake data',
36 'vendor': 'Citrix Systems Inc',
37 'copyright': '(C) 2008 Citrix Systems Inc',
38 'driver_version': '1.0',
39 'required_api_version': '1.1',
40 'capabilities': CAPABILITIES,
41 'configuration': CONFIGURATION
42 }
44TYPE = 'dummy'
47class DummySR(SR.SR):
48 """dummy storage repository"""
50 def handles(type):
51 if type == TYPE:
52 return True
53 return False
54 handles = staticmethod(handles)
56 def load(self, sr_uuid):
57 self.sr_vditype = 'phy'
59 def content_type(self, sr_uuid):
60 return super(DummySR, self).content_type(sr_uuid)
62 def create(self, sr_uuid, size):
63 self._assertValues(['sr_uuid', 'args', 'host_ref', 'session_ref', 'device_config', 'command', 'sr_ref'])
64 assert(len(self.srcmd.params['args']) == 1)
66 def delete(self, sr_uuid):
67 self._assertValues(['sr_uuid', 'args', 'host_ref', 'session_ref', 'device_config', 'command', 'sr_ref'])
68 assert(len(self.srcmd.params['args']) == 0)
70 def attach(self, sr_uuid):
71 self._assertValues(['sr_uuid', 'args', 'host_ref', 'session_ref', 'device_config', 'command', 'sr_ref'])
72 assert(len(self.srcmd.params['args']) == 0)
74 def detach(self, sr_uuid):
75 self._assertValues(['sr_uuid', 'args', 'host_ref', 'session_ref', 'device_config', 'command', 'sr_ref'])
76 assert(len(self.srcmd.params['args']) == 0)
78 def probe(self):
79 # N.B. There are no SR references
80 self._assertValues(['args', 'host_ref', 'session_ref', 'device_config', 'command'])
81 assert(len(self.srcmd.params['args']) == 0)
83 # Create some Dummy SR records
84 entry = {}
85 entry['size'] = 1024
86 SRlist = {}
87 SRlist[util.gen_uuid()] = entry
89 # Return the Probe XML
90 return util.SRtoXML(SRlist)
92 def vdi(self, uuid):
93 return DummyVDI(self, uuid)
95 def scan(self, sr_uuid):
96 self._assertValues(['sr_uuid', 'args', 'host_ref', 'session_ref', 'device_config', 'command', 'sr_ref'])
97 assert(len(self.srcmd.params['args']) == 0)
99 # The list of VDIs comes from the XenAPI - we have no state
100 for v in self._getallVDIrecords():
101 x = DummyVDI(self, v['uuid'])
102 x.size = v['virtual_size']
103 x.utilisation = v['physical_utilisation']
104 self.vdis[x.uuid] = x
106 self.physical_size = 2000000000000
107 self.physical_utilisation = 0
108 self.virtual_allocation = 0
109 return super(DummySR, self).scan(sr_uuid)
111 def _assertValues(self, vals):
112 for attr in vals:
113 assert(attr in self.srcmd.params)
114 util.SMlog("%s param %s: [%s]" % (self.cmd, attr, self.srcmd.params[attr]))
116 # Iterate through the device_config dictionary
117 for key in self.dconf.keys():
118 util.SMlog("\tdevice_config: [%s:%s]" % (key, self.dconf[key]))
120 # Query the sm_config; parameters can be set at Create time. Iterate through keys
121 self.sm_config = self.session.xenapi.SR.get_sm_config(self.sr_ref)
122 for key in self.sm_config.keys():
123 util.SMlog("\tsm_config: [%s:%s]" % (key, self.sm_config[key]))
125 def _getallVDIrecords(self):
126 """Helper function which returns a list of all VDI records for this SR
127 stored in the XenAPI server"""
128 # Returns a list of (reference, record) pairs: we only need the records
129 vdis = list(self.session.VDI.get_all_records(self.session_ref)['Value'].values())
130 # We only need the VDIs corresponding to this SR
131 return [v for v in vdis if v['SR'] == self.sr_ref]
134class DummyVDI(VDI.VDI):
135 def load(self, vdi_uuid):
136 self.path = "/dev/null" # returned on attach
137 self.uuid = vdi_uuid
138 self.size = 0
139 self.utilisation = 0
140 self.location = vdi_uuid
141 self.sm_config = {}
143 def create(self, sr_uuid, vdi_uuid, size):
144 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_sm_config'])
145 assert(len(self.sr.srcmd.params['args']) == 8)
147 self.vdi_sm_config = self.sr.srcmd.params['vdi_sm_config']
148 for key in self.vdi_sm_config.keys():
149 util.SMlog("\tvdi_sm_config: [%s:%s]" % (key, self.vdi_sm_config[key]))
151 for v in self.sr._getallVDIrecords():
152 if v['uuid'] == vdi_uuid:
153 raise xs_errors.XenError('VDIExists')
155 self.size = size
156 self.utilisation = size
157 self.sm_config['samplekey'] = "This is a dummy SR VDI"
158 self._db_introduce()
159 self.run_corner_cases_tests()
160 return self.get_params()
162 def delete(self, sr_uuid, vdi_uuid):
163 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
164 assert(len(self.sr.srcmd.params['args']) == 0)
166 # Assert that the VDI record exists
167 self.session.VDI.get_record(self.sr.session_ref)
168 self.run_corner_cases_tests()
169 self._db_forget()
171 def introduce(self, sr_uuid, vdi_uuid):
172 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_sm_config', 'new_uuid'])
173 assert(len(self.sr.srcmd.params['args']) == 0)
174 self.vdi_sm_config = self.sr.srcmd.params['vdi_sm_config']
175 for key in self.vdi_sm_config.keys():
176 util.SMlog("\tvdi_sm_config: [%s:%s]" % (key, self.vdi_sm_config[key]))
178 for v in self.sr._getallVDIrecords():
179 if v['uuid'] == vdi_uuid:
180 raise xs_errors.XenError('VDIExists')
181 self.uuid = vdi_uuid
182 self.location = self.sr.srcmd.params['vdi_location']
183 self._db_introduce()
184 self.run_corner_cases_tests()
185 return super(DummyVDI, self).get_params()
187 def attach(self, sr_uuid, vdi_uuid):
188 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
189 assert(len(self.sr.srcmd.params['args']) == 1)
190 vdi = super(DummyVDI, self).attach(sr_uuid, vdi_uuid)
191 self.run_corner_cases_tests()
192 return vdi
194 def detach(self, sr_uuid, vdi_uuid):
195 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
196 self.run_corner_cases_tests()
197 assert(len(self.sr.srcmd.params['args']) == 0)
199 def activate(self, sr_uuid, vdi_uuid):
200 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
201 assert(len(self.sr.srcmd.params['args']) == 1)
202 self.vdi_ref = self.sr.srcmd.params['vdi_ref']
203 self.other_config = self.session.xenapi.VDI.get_other_config(self.vdi_ref)
204 self.run_corner_cases_tests()
205 for key in self.other_config.keys():
206 util.SMlog("\tvdi_other_config: [%s:%s]" % (key, self.other_config[key]))
208 def deactivate(self, sr_uuid, vdi_uuid):
209 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
210 self.run_corner_cases_tests()
211 assert(len(self.sr.srcmd.params['args']) == 0)
213 def resize(self, sr_uuid, vdi_uuid, size):
214 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref', 'vdi_ref', 'vdi_location', 'vdi_uuid'])
215 assert(len(self.sr.srcmd.params['args']) == 1)
217 self.size = size
218 self.utilisation = size
219 self._db_update()
220 self.run_corner_cases_tests()
221 return super(DummyVDI, self).get_params()
223 def snapshot(self, sr_uuid, vdi_uuid):
224 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref'])
225 assert(len(self.sr.srcmd.params['args']) == 0)
227 dest = util.gen_uuid()
228 vdi = VDI.VDI(self.sr, dest)
229 vdi.read_only = True
230 vdi.location = dest
231 vdi.size = 0
232 vdi.utilisation = 0
233 vdi._db_introduce()
234 self.run_corner_cases_tests()
235 return vdi.get_params()
237 def clone(self, sr_uuid, vdi_uuid):
238 self.sr._assertValues(['sr_uuid', 'args', 'host_ref', 'device_config', 'command', 'sr_ref'])
239 assert(len(self.sr.srcmd.params['args']) == 0)
241 dest = util.gen_uuid()
242 vdi = VDI.VDI(self.sr, dest)
243 vdi.read_only = False
244 vdi.location = dest
245 vdi.size = 0
246 vdi.utilisation = 0
247 vdi._db_introduce()
248 self.run_corner_cases_tests()
249 return vdi.get_params()
251 def check_no_other_vdi_operation_in_progress(self):
252 vdis = util.list_VDI_records_in_sr(self.sr)
253 vdi_ref = self.session.xenapi.VDI.get_by_uuid(self.uuid)
254 del vdis[vdi_ref]
255 active_vdis = [v for v in list(vdis.values()) if v['current_operations'] != {}]
256 if len(active_vdis) != 0:
257 msg = "LVHDRT: found other operations in progress for VDI: %s" % active_vdis[0]['uuid']
258 util.SMlog(msg)
259 raise xs_errors.XenError('OtherVDIOperationInProgress')
261 def get_attached_vbds(self):
262 vdi_ref = self.session.xenapi.VDI.get_by_uuid(self.uuid)
263 vbds = self.session.xenapi.VBD.get_all_records_where("field \"VDI\" = \"%s\"" % vdi_ref)
264 return [v for v in list(vbds.values()) if v['currently_attached'] == "true"]
266 def check_vbd_list_is_stable(self, attached_vbds):
267 newly_attached_vbds = self.get_attached_vbds()
268 old_set = set(attached_vbds)
269 new_set = set(newly_attached_vbds)
270 diff_set = old_set.difference(new_set) | new_set.difference(old_set)
271 if len(diff_set) != 0:
272 msg = "LVHDRT: found a non-stable VBD: %s" % (diff_set.pop())
273 util.SMlog(msg)
274 raise xs_errors.XenError('VBDListNotStable')
276 def run_corner_cases_tests(self):
278 def fn():
279 attached_vbds = self.get_attached_vbds()
280 for i in range(0, 10):
281 time.sleep(2)
282 self.check_no_other_vdi_operation_in_progress()
283 self.check_vbd_list_is_stable(attached_vbds)
285 util.fistpoint.activate_custom_fn("LVHDRT_xapiSM_serialization_tests", fn)
287if __name__ == '__main__': 287 ↛ 288line 287 didn't jump to line 288, because the condition on line 287 was never true
288 SRCommand.run(DummySR, DRIVER_INFO)
289else:
290 SR.registerSR(DummySR)