~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/tests/test_netapp.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandleman, Chuck Short
  • Date: 2012-03-02 11:04:04 UTC
  • mfrom: (1.1.47)
  • Revision ID: package-import@ubuntu.com-20120302110404-fr230yakr8hov3dj
Tags: 2012.1~e4-0ubuntu1
[ Adam Gandleman ]
* debian/patches/libvirt-use-console-pipe.patch: Refreshed. 
* debain/nova-volume.upstart.in: Ensure lock directory is created
  (LP: #940780)
* debain/control: Fix nova-compute-$flavor Depends
* debian/control: Add python-iso8601 to python-nova Depends

[ Chuck Short ]
* debian/rules: Fix FTBFS.
* Merge Ubuntu/Debian packaging:
  - Thanks to Julien Danjou, Ghe Rivero, and Thomas Goirand
  - debian/copyright: Update copyright file.
  - debian/nova-api.init, debian/nova-compute.init,
    debian/nova-network.init, debian/nova-objectstore,
    debian/nova-scheduler, debian/nova-volume.init:
    Synchronize init scripts.
  - nova-common.install, debian/rules: Install policy.json
  - debian/rules, debian/nova-xcp-network.install,
    debian/nova-xcp-plugins.install, nova-xcp-plugins.postrm,
    debian/nova-xcp-plugins.doc, debian/nova-xcp-plugins.postinst,
    debian/README.xcp_and_openstack, debian/control,
    debian/ubuntu_xen-openvswitch-nova.rules,
    debian/patches/path-to-the-xenhost.conf-fixup.patch:
    Add Xen XCP support.
  - debian/control,
    debian/nova-compute-{kvm,lxc,qemu,xen,uml}.postinst: Make
    nova-compute a virtual package.
  - Dropped ubuntu_ubuntu_control_vars: We dont use it
* New upstream release.
* Dropped python-babel, it will be handled by langpacks.
* debian/patches/ec2-fixes.patch: Backport turnk fix for ec2
  permissions.
* debian/patches/path-to-the-xenhost.conf-fixup.patch: Refreshed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright (c) 2012 NetApp, Inc.
 
4
# All Rights Reserved.
 
5
#
 
6
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
7
#    not use this file except in compliance with the License. You may obtain
 
8
#    a copy of the License at
 
9
#
 
10
#         http://www.apache.org/licenses/LICENSE-2.0
 
11
#
 
12
#    Unless required by applicable law or agreed to in writing, software
 
13
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
14
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
15
#    License for the specific language governing permissions and limitations
 
16
#    under the License.
 
17
"""
 
18
Tests for NetApp volume driver
 
19
 
 
20
"""
 
21
 
 
22
import BaseHTTPServer
 
23
import httplib
 
24
import StringIO
 
25
 
 
26
from lxml import etree
 
27
 
 
28
from nova import log as logging
 
29
from nova import test
 
30
from nova.volume.netapp import NetAppISCSIDriver
 
31
 
 
32
LOG = logging.getLogger("nova.volume.driver")
 
33
 
 
34
 
 
35
WSDL_HEADER = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
36
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
 
37
    xmlns:na="http://www.netapp.com/management/v1"
 
38
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 
39
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NetAppDfm"
 
40
    targetNamespace="http://www.netapp.com/management/v1">"""
 
41
 
 
42
WSDL_TYPES = """<types>
 
43
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
 
44
    targetNamespace="http://www.netapp.com/management/v1">
 
45
<xsd:element name="ApiProxy">
 
46
    <xsd:complexType>
 
47
        <xsd:all>
 
48
            <xsd:element name="Request" type="na:Request"/>
 
49
            <xsd:element name="Target" type="xsd:string"/>
 
50
            <xsd:element minOccurs="0" name="Timeout" type="xsd:integer"/>
 
51
            <xsd:element minOccurs="0" name="Username" type="xsd:string"/>
 
52
        </xsd:all>
 
53
    </xsd:complexType>
 
54
</xsd:element>
 
55
<xsd:element name="ApiProxyResult">
 
56
    <xsd:complexType>
 
57
        <xsd:all>
 
58
            <xsd:element name="Response" type="na:Response"/>
 
59
        </xsd:all>
 
60
    </xsd:complexType>
 
61
</xsd:element>
 
62
<xsd:element name="DatasetEditBegin">
 
63
    <xsd:complexType>
 
64
        <xsd:all>
 
65
            <xsd:element name="DatasetNameOrId" type="na:ObjNameOrId"/>
 
66
            <xsd:element minOccurs="0" name="Force" type="xsd:boolean"/>
 
67
        </xsd:all>
 
68
    </xsd:complexType>
 
69
</xsd:element>
 
70
<xsd:element name="DatasetEditBeginResult">
 
71
    <xsd:complexType>
 
72
        <xsd:all>
 
73
            <xsd:element name="EditLockId" type="xsd:integer"/>
 
74
        </xsd:all>
 
75
    </xsd:complexType>
 
76
</xsd:element>
 
77
<xsd:element name="DatasetEditCommit">
 
78
    <xsd:complexType>
 
79
        <xsd:all>
 
80
            <xsd:element minOccurs="0" name="AssumeConfirmation"
 
81
                type="xsd:boolean"/>
 
82
            <xsd:element name="EditLockId" type="xsd:integer"/>
 
83
        </xsd:all>
 
84
    </xsd:complexType>
 
85
</xsd:element>
 
86
<xsd:element name="DatasetEditCommitResult">
 
87
    <xsd:complexType>
 
88
        <xsd:all>
 
89
            <xsd:element minOccurs="0" name="IsProvisioningFailure"
 
90
                type="xsd:boolean"/>
 
91
            <xsd:element minOccurs="0" name="JobIds" type="na:ArrayOfJobInfo"/>
 
92
        </xsd:all>
 
93
    </xsd:complexType>
 
94
</xsd:element>
 
95
<xsd:element name="DatasetEditRollback">
 
96
    <xsd:complexType>
 
97
        <xsd:all>
 
98
            <xsd:element name="EditLockId" type="xsd:integer"/>
 
99
        </xsd:all>
 
100
    </xsd:complexType>
 
101
</xsd:element>
 
102
<xsd:element name="DatasetEditRollbackResult">
 
103
    <xsd:complexType/>
 
104
</xsd:element>
 
105
<xsd:element name="DatasetListInfoIterEnd">
 
106
    <xsd:complexType>
 
107
        <xsd:all>
 
108
            <xsd:element name="Tag" type="xsd:string"/>
 
109
        </xsd:all>
 
110
    </xsd:complexType>
 
111
</xsd:element>
 
112
<xsd:element name="DatasetListInfoIterEndResult">
 
113
    <xsd:complexType/>
 
114
</xsd:element>
 
115
<xsd:element name="DatasetListInfoIterNext">
 
116
    <xsd:complexType>
 
117
        <xsd:all>
 
118
            <xsd:element name="Maximum" type="xsd:integer"/>
 
119
            <xsd:element name="Tag" type="xsd:string"/>
 
120
        </xsd:all>
 
121
    </xsd:complexType>
 
122
</xsd:element>
 
123
<xsd:element name="DatasetListInfoIterNextResult">
 
124
    <xsd:complexType>
 
125
        <xsd:all>
 
126
            <xsd:element name="Datasets" type="na:ArrayOfDatasetInfo"/>
 
127
            <xsd:element name="Records" type="xsd:integer"/>
 
128
        </xsd:all>
 
129
    </xsd:complexType>
 
130
</xsd:element>
 
131
<xsd:element name="DatasetListInfoIterStart">
 
132
    <xsd:complexType>
 
133
        <xsd:all>
 
134
            <xsd:element minOccurs="0" name="ObjectNameOrId"
 
135
                type="na:ObjNameOrId"/>
 
136
        </xsd:all>
 
137
    </xsd:complexType>
 
138
</xsd:element>
 
139
<xsd:element name="DatasetListInfoIterStartResult">
 
140
    <xsd:complexType>
 
141
        <xsd:all>
 
142
            <xsd:element name="Records" type="xsd:integer"/>
 
143
            <xsd:element name="Tag" type="xsd:string"/>
 
144
        </xsd:all>
 
145
    </xsd:complexType>
 
146
</xsd:element>
 
147
<xsd:element name="DatasetMemberListInfoIterEnd">
 
148
    <xsd:complexType>
 
149
        <xsd:all>
 
150
            <xsd:element name="Tag" type="xsd:string"/>
 
151
        </xsd:all>
 
152
    </xsd:complexType>
 
153
</xsd:element>
 
154
<xsd:element name="DatasetMemberListInfoIterEndResult">
 
155
    <xsd:complexType/>
 
156
</xsd:element>
 
157
<xsd:element name="DatasetMemberListInfoIterNext">
 
158
    <xsd:complexType>
 
159
        <xsd:all>
 
160
            <xsd:element name="Maximum" type="xsd:integer"/>
 
161
            <xsd:element name="Tag" type="xsd:string"/>
 
162
        </xsd:all>
 
163
    </xsd:complexType>
 
164
</xsd:element>
 
165
<xsd:element name="DatasetMemberListInfoIterNextResult">
 
166
    <xsd:complexType>
 
167
        <xsd:all>
 
168
            <xsd:element name="DatasetMembers"
 
169
                type="na:ArrayOfDatasetMemberInfo"/>
 
170
            <xsd:element name="Records" type="xsd:integer"/>
 
171
        </xsd:all>
 
172
    </xsd:complexType>
 
173
</xsd:element>
 
174
<xsd:element name="DatasetMemberListInfoIterStart">
 
175
    <xsd:complexType>
 
176
        <xsd:all>
 
177
            <xsd:element name="DatasetNameOrId" type="na:ObjNameOrId"/>
 
178
            <xsd:element minOccurs="0" name="IncludeExportsInfo"
 
179
                type="xsd:boolean"/>
 
180
            <xsd:element minOccurs="0" name="IncludeIndirect"
 
181
                type="xsd:boolean"/>
 
182
            <xsd:element minOccurs="0" name="MemberType" type="xsd:string"/>
 
183
        </xsd:all>
 
184
    </xsd:complexType>
 
185
</xsd:element>
 
186
<xsd:element name="DatasetMemberListInfoIterStartResult">
 
187
    <xsd:complexType>
 
188
        <xsd:all>
 
189
            <xsd:element name="Records" type="xsd:integer"/>
 
190
            <xsd:element name="Tag" type="xsd:string"/>
 
191
        </xsd:all>
 
192
    </xsd:complexType>
 
193
</xsd:element>
 
194
<xsd:element name="DatasetProvisionMember">
 
195
    <xsd:complexType>
 
196
        <xsd:all>
 
197
            <xsd:element name="EditLockId" type="xsd:integer"/>
 
198
            <xsd:element name="ProvisionMemberRequestInfo"
 
199
                type="na:ProvisionMemberRequestInfo"/>
 
200
        </xsd:all>
 
201
    </xsd:complexType>
 
202
</xsd:element>
 
203
<xsd:element name="DatasetProvisionMemberResult">
 
204
    <xsd:complexType/>
 
205
</xsd:element>
 
206
<xsd:element name="DatasetRemoveMember">
 
207
    <xsd:complexType>
 
208
        <xsd:all>
 
209
            <xsd:element name="DatasetMemberParameters"
 
210
                type="na:ArrayOfDatasetMemberParameter"/>
 
211
            <xsd:element minOccurs="0" name="Destroy" type="xsd:boolean"/>
 
212
            <xsd:element name="EditLockId" type="xsd:integer"/>
 
213
        </xsd:all>
 
214
    </xsd:complexType>
 
215
</xsd:element>
 
216
<xsd:element name="DatasetRemoveMemberResult">
 
217
    <xsd:complexType/>
 
218
</xsd:element>
 
219
<xsd:element name="DpJobProgressEventListIterEnd">
 
220
    <xsd:complexType>
 
221
        <xsd:all>
 
222
            <xsd:element name="Tag" type="xsd:string"/>
 
223
        </xsd:all>
 
224
    </xsd:complexType>
 
225
</xsd:element>
 
226
<xsd:element name="DpJobProgressEventListIterEndResult">
 
227
    <xsd:complexType/>
 
228
</xsd:element>
 
229
<xsd:element name="DpJobProgressEventListIterNext">
 
230
    <xsd:complexType>
 
231
        <xsd:all>
 
232
            <xsd:element name="Maximum" type="xsd:integer"/>
 
233
            <xsd:element name="Tag" type="xsd:string"/>
 
234
        </xsd:all>
 
235
    </xsd:complexType>
 
236
</xsd:element>
 
237
<xsd:element name="DpJobProgressEventListIterNextResult">
 
238
    <xsd:complexType>
 
239
        <xsd:all>
 
240
            <xsd:element name="ProgressEvents"
 
241
                type="na:ArrayOfDpJobProgressEventInfo"/>
 
242
            <xsd:element name="Records" type="xsd:integer"/>
 
243
        </xsd:all>
 
244
    </xsd:complexType>
 
245
</xsd:element>
 
246
<xsd:element name="DpJobProgressEventListIterStart">
 
247
    <xsd:complexType>
 
248
        <xsd:all>
 
249
            <xsd:element minOccurs="0" name="JobId" type="xsd:integer"/>
 
250
        </xsd:all>
 
251
    </xsd:complexType>
 
252
</xsd:element>
 
253
<xsd:element name="DpJobProgressEventListIterStartResult">
 
254
    <xsd:complexType>
 
255
        <xsd:all>
 
256
            <xsd:element name="Records" type="xsd:integer"/>
 
257
            <xsd:element name="Tag" type="xsd:string"/>
 
258
        </xsd:all>
 
259
    </xsd:complexType>
 
260
</xsd:element>
 
261
<xsd:element name="DfmAbout">
 
262
    <xsd:complexType>
 
263
        <xsd:all>
 
264
            <xsd:element minOccurs="0" name="IncludeDirectorySizeInfo"
 
265
                type="xsd:boolean"/>
 
266
        </xsd:all>
 
267
    </xsd:complexType>
 
268
</xsd:element>
 
269
<xsd:element name="DfmAboutResult">
 
270
    <xsd:complexType>
 
271
        <xsd:all/>
 
272
    </xsd:complexType>
 
273
</xsd:element>
 
274
<xsd:element name="HostListInfoIterEnd">
 
275
    <xsd:complexType>
 
276
        <xsd:all>
 
277
            <xsd:element name="Tag" type="xsd:string"/>
 
278
        </xsd:all>
 
279
    </xsd:complexType>
 
280
</xsd:element>
 
281
<xsd:element name="HostListInfoIterEndResult">
 
282
    <xsd:complexType/>
 
283
</xsd:element>
 
284
<xsd:element name="HostListInfoIterNext">
 
285
    <xsd:complexType>
 
286
        <xsd:all>
 
287
            <xsd:element name="Maximum" type="xsd:integer"/>
 
288
            <xsd:element name="Tag" type="xsd:string"/>
 
289
        </xsd:all>
 
290
    </xsd:complexType>
 
291
</xsd:element>
 
292
<xsd:element name="HostListInfoIterNextResult">
 
293
    <xsd:complexType>
 
294
        <xsd:all>
 
295
            <xsd:element name="Hosts" type="na:ArrayOfHostInfo"/>
 
296
            <xsd:element name="Records" type="xsd:integer"/>
 
297
        </xsd:all>
 
298
    </xsd:complexType>
 
299
</xsd:element>
 
300
<xsd:element name="HostListInfoIterStart">
 
301
    <xsd:complexType>
 
302
        <xsd:all>
 
303
            <xsd:element minOccurs="0" name="ObjectNameOrId"
 
304
                type="na:ObjNameOrId"/>
 
305
        </xsd:all>
 
306
    </xsd:complexType>
 
307
</xsd:element>
 
308
<xsd:element name="HostListInfoIterStartResult">
 
309
    <xsd:complexType>
 
310
        <xsd:all>
 
311
            <xsd:element name="Records" type="xsd:integer"/>
 
312
            <xsd:element name="Tag" type="xsd:string"/>
 
313
        </xsd:all>
 
314
    </xsd:complexType>
 
315
</xsd:element>
 
316
<xsd:element name="LunListInfoIterEnd">
 
317
    <xsd:complexType>
 
318
        <xsd:all>
 
319
            <xsd:element name="Tag" type="xsd:string"/>
 
320
        </xsd:all>
 
321
    </xsd:complexType>
 
322
</xsd:element>
 
323
<xsd:element name="LunListInfoIterEndResult">
 
324
    <xsd:complexType/>
 
325
</xsd:element>
 
326
<xsd:element name="LunListInfoIterNext">
 
327
    <xsd:complexType>
 
328
        <xsd:all>
 
329
            <xsd:element name="Maximum" type="xsd:integer"/>
 
330
            <xsd:element name="Tag" type="xsd:string"/>
 
331
        </xsd:all>
 
332
    </xsd:complexType>
 
333
</xsd:element>
 
334
<xsd:element name="LunListInfoIterNextResult">
 
335
    <xsd:complexType>
 
336
        <xsd:all>
 
337
            <xsd:element name="Luns" type="na:ArrayOfLunInfo"/>
 
338
            <xsd:element name="Records" type="xsd:integer"/>
 
339
        </xsd:all>
 
340
    </xsd:complexType>
 
341
</xsd:element>
 
342
<xsd:element name="LunListInfoIterStart">
 
343
    <xsd:complexType>
 
344
        <xsd:all>
 
345
            <xsd:element minOccurs="0" name="ObjectNameOrId"
 
346
                type="na:ObjNameOrId"/>
 
347
        </xsd:all>
 
348
    </xsd:complexType>
 
349
</xsd:element>
 
350
<xsd:element name="LunListInfoIterStartResult">
 
351
    <xsd:complexType>
 
352
        <xsd:all>
 
353
            <xsd:element name="Records" type="xsd:integer"/>
 
354
            <xsd:element name="Tag" type="xsd:string"/>
 
355
        </xsd:all>
 
356
    </xsd:complexType>
 
357
</xsd:element>
 
358
<xsd:element name="StorageServiceDatasetProvision">
 
359
    <xsd:complexType>
 
360
        <xsd:all>
 
361
            <xsd:element minOccurs="0" name="AssumeConfirmation"
 
362
                type="xsd:boolean"/>
 
363
            <xsd:element name="DatasetName" type="na:ObjName"/>
 
364
            <xsd:element name="StorageServiceNameOrId" type="na:ObjNameOrId"/>
 
365
            <xsd:element minOccurs="0" name="StorageSetDetails"
 
366
                type="na:ArrayOfStorageSetInfo"/>
 
367
        </xsd:all>
 
368
    </xsd:complexType>
 
369
</xsd:element>
 
370
<xsd:element name="StorageServiceDatasetProvisionResult">
 
371
    <xsd:complexType>
 
372
        <xsd:all>
 
373
            <xsd:element minOccurs="0" name="ConformanceAlerts"
 
374
                type="na:ArrayOfConformanceAlert"/>
 
375
            <xsd:element name="DatasetId" type="na:ObjId"/>
 
376
            <xsd:element minOccurs="0" name="DryRunResults"
 
377
                type="na:ArrayOfDryRunResult"/>
 
378
        </xsd:all>
 
379
    </xsd:complexType>
 
380
</xsd:element>
 
381
<xsd:complexType name="ArrayOfDatasetInfo">
 
382
    <xsd:sequence>
 
383
        <xsd:element maxOccurs="unbounded" name="DatasetInfo"
 
384
            type="na:DatasetInfo"/>
 
385
    </xsd:sequence>
 
386
</xsd:complexType>
 
387
<xsd:complexType name="ArrayOfDatasetMemberInfo">
 
388
    <xsd:sequence>
 
389
        <xsd:element maxOccurs="unbounded" name="DatasetMemberInfo"
 
390
            type="na:DatasetMemberInfo"/>
 
391
    </xsd:sequence>
 
392
</xsd:complexType>
 
393
<xsd:complexType name="ArrayOfDatasetMemberParameter">
 
394
    <xsd:sequence>
 
395
        <xsd:element maxOccurs="unbounded" name="DatasetMemberParameter"
 
396
            type="na:DatasetMemberParameter"/>
 
397
    </xsd:sequence>
 
398
</xsd:complexType>
 
399
<xsd:complexType name="ArrayOfDpJobProgressEventInfo">
 
400
    <xsd:sequence>
 
401
        <xsd:element maxOccurs="unbounded" name="DpJobProgressEventInfo"
 
402
            type="na:DpJobProgressEventInfo"/>
 
403
    </xsd:sequence>
 
404
</xsd:complexType>
 
405
<xsd:complexType name="ArrayOfHostInfo">
 
406
    <xsd:sequence>
 
407
        <xsd:element maxOccurs="unbounded" name="HostInfo" type="na:HostInfo"/>
 
408
    </xsd:sequence>
 
409
</xsd:complexType>
 
410
<xsd:complexType name="ArrayOfJobInfo">
 
411
    <xsd:sequence>
 
412
        <xsd:element maxOccurs="unbounded" name="JobInfo" type="na:JobInfo"/>
 
413
    </xsd:sequence>
 
414
</xsd:complexType>
 
415
<xsd:complexType name="ArrayOfLunInfo">
 
416
    <xsd:sequence>
 
417
        <xsd:element maxOccurs="unbounded" name="LunInfo" type="na:LunInfo"/>
 
418
    </xsd:sequence>
 
419
</xsd:complexType>
 
420
<xsd:complexType name="ArrayOfStorageSetInfo">
 
421
    <xsd:sequence>
 
422
        <xsd:element maxOccurs="unbounded" name="StorageSetInfo"
 
423
            type="na:StorageSetInfo"/>
 
424
    </xsd:sequence>
 
425
</xsd:complexType>
 
426
<xsd:complexType name="DatasetExportInfo">
 
427
    <xsd:all>
 
428
        <xsd:element minOccurs="0" name="DatasetExportProtocol"
 
429
            type="na:DatasetExportProtocol"/>
 
430
        <xsd:element minOccurs="0" name="DatasetLunMappingInfo"
 
431
            type="na:DatasetLunMappingInfo"/>
 
432
    </xsd:all>
 
433
</xsd:complexType>
 
434
<xsd:simpleType name="DatasetExportProtocol">
 
435
    <xsd:restriction base="xsd:string"/>
 
436
</xsd:simpleType>
 
437
<xsd:complexType name="DatasetInfo">
 
438
    <xsd:all>
 
439
        <xsd:element name="DatasetId" type="na:ObjId"/>
 
440
    </xsd:all>
 
441
</xsd:complexType>
 
442
<xsd:complexType name="DatasetLunMappingInfo">
 
443
    <xsd:all>
 
444
        <xsd:element name="IgroupOsType" type="xsd:string"/>
 
445
    </xsd:all>
 
446
</xsd:complexType>
 
447
<xsd:complexType name="DatasetMemberInfo">
 
448
    <xsd:all>
 
449
        <xsd:element name="MemberId" type="na:ObjId"/>
 
450
        <xsd:element name="MemberName" type="na:ObjName"/>
 
451
    </xsd:all>
 
452
</xsd:complexType>
 
453
<xsd:complexType name="DatasetMemberParameter">
 
454
    <xsd:all>
 
455
        <xsd:element name="ObjectNameOrId" type="na:ObjNameOrId"/>
 
456
    </xsd:all>
 
457
</xsd:complexType>
 
458
<xsd:complexType name="DpJobProgressEventInfo">
 
459
    <xsd:all>
 
460
        <xsd:element name="EventStatus" type="na:ObjStatus"/>
 
461
        <xsd:element name="EventType" type="xsd:string"/>
 
462
        <xsd:element minOccurs="0" name="ProgressLunInfo"
 
463
            type="na:ProgressLunInfo"/>
 
464
    </xsd:all>
 
465
</xsd:complexType>
 
466
<xsd:simpleType name="DpPolicyNodeName">
 
467
    <xsd:restriction base="xsd:string"/>
 
468
</xsd:simpleType>
 
469
<xsd:simpleType name="HostId">
 
470
    <xsd:restriction base="xsd:integer"/>
 
471
</xsd:simpleType>
 
472
<xsd:complexType name="HostInfo">
 
473
    <xsd:all>
 
474
        <xsd:element name="HostAddress" type="xsd:string"/>
 
475
        <xsd:element name="HostId" type="na:HostId"/>
 
476
        <xsd:element name="HostName" type="xsd:string"/>
 
477
    </xsd:all>
 
478
</xsd:complexType>
 
479
<xsd:complexType name="JobInfo">
 
480
    <xsd:all>
 
481
        <xsd:element name="JobId" type="xsd:integer"/>
 
482
    </xsd:all>
 
483
</xsd:complexType>
 
484
<xsd:complexType name="LunInfo">
 
485
    <xsd:all>
 
486
        <xsd:element name="HostId" type="na:ObjId"/>
 
487
        <xsd:element name="LunPath" type="na:ObjName"/>
 
488
    </xsd:all>
 
489
</xsd:complexType>
 
490
<xsd:simpleType name="ObjId">
 
491
    <xsd:restriction base="xsd:integer"/>
 
492
</xsd:simpleType>
 
493
<xsd:simpleType name="ObjName">
 
494
    <xsd:restriction base="xsd:string"/>
 
495
</xsd:simpleType>
 
496
<xsd:simpleType name="ObjNameOrId">
 
497
    <xsd:restriction base="xsd:string"/>
 
498
</xsd:simpleType>
 
499
<xsd:simpleType name="ObjStatus">
 
500
    <xsd:restriction base="xsd:string"/>
 
501
</xsd:simpleType>
 
502
<xsd:complexType name="ProgressLunInfo">
 
503
    <xsd:all>
 
504
        <xsd:element name="LunPathId" type="na:ObjId"/>
 
505
    </xsd:all>
 
506
</xsd:complexType>
 
507
<xsd:complexType name="ProvisionMemberRequestInfo">
 
508
    <xsd:all>
 
509
        <xsd:element minOccurs="0" name="Description" type="xsd:string"/>
 
510
        <xsd:element minOccurs="0" name="MaximumSnapshotSpace"
 
511
            type="xsd:integer"/>
 
512
        <xsd:element name="Name" type="xsd:string"/>
 
513
        <xsd:element name="Size" type="xsd:integer"/>
 
514
    </xsd:all>
 
515
</xsd:complexType>
 
516
<xsd:complexType name="Request">
 
517
    <xsd:all>
 
518
        <xsd:element minOccurs="0" name="Args">
 
519
            <xsd:complexType>
 
520
                <xsd:sequence>
 
521
                    <xsd:any maxOccurs="unbounded" minOccurs="0"/>
 
522
                </xsd:sequence>
 
523
            </xsd:complexType>
 
524
        </xsd:element>
 
525
        <xsd:element name="Name" type="xsd:string">
 
526
        </xsd:element>
 
527
    </xsd:all>
 
528
</xsd:complexType>
 
529
<xsd:complexType name="Response">
 
530
    <xsd:all>
 
531
        <xsd:element minOccurs="0" name="Errno" type="xsd:integer"/>
 
532
        <xsd:element minOccurs="0" name="Reason" type="xsd:string"/>
 
533
        <xsd:element minOccurs="0" name="Results">
 
534
            <xsd:complexType>
 
535
                <xsd:sequence>
 
536
                    <xsd:any maxOccurs="unbounded" minOccurs="0"/>
 
537
                </xsd:sequence>
 
538
            </xsd:complexType>
 
539
        </xsd:element>
 
540
        <xsd:element name="Status" type="xsd:string"/>
 
541
    </xsd:all>
 
542
</xsd:complexType>
 
543
<xsd:complexType name="StorageSetInfo">
 
544
    <xsd:all>
 
545
        <xsd:element minOccurs="0" name="DatasetExportInfo"
 
546
            type="na:DatasetExportInfo"/>
 
547
        <xsd:element minOccurs="0" name="DpNodeName"
 
548
            type="na:DpPolicyNodeName"/>
 
549
        <xsd:element minOccurs="0" name="ServerNameOrId"
 
550
            type="na:ObjNameOrId"/>
 
551
    </xsd:all>
 
552
</xsd:complexType>
 
553
</xsd:schema></types>"""
 
554
 
 
555
WSDL_TRAILER = """<service name="DfmService">
 
556
<port binding="na:DfmBinding" name="DfmPort">
 
557
<soap:address location="https://HOST_NAME:8488/apis/soap/v1"/>
 
558
</port></service></definitions>"""
 
559
 
 
560
RESPONSE_PREFIX = """<?xml version="1.0" encoding="UTF-8"?>
 
561
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
 
562
    xmlns:na="http://www.netapp.com/management/v1"><env:Header/><env:Body>"""
 
563
 
 
564
RESPONSE_SUFFIX = """</env:Body></env:Envelope>"""
 
565
 
 
566
APIS = ['ApiProxy', 'DatasetListInfoIterStart', 'DatasetListInfoIterNext',
 
567
    'DatasetListInfoIterEnd', 'DatasetEditBegin', 'DatasetEditCommit',
 
568
    'DatasetProvisionMember', 'DatasetRemoveMember', 'DfmAbout',
 
569
    'DpJobProgressEventListIterStart', 'DpJobProgressEventListIterNext',
 
570
    'DpJobProgressEventListIterEnd', 'DatasetMemberListInfoIterStart',
 
571
    'DatasetMemberListInfoIterNext', 'DatasetMemberListInfoIterEnd',
 
572
    'HostListInfoIterStart', 'HostListInfoIterNext', 'HostListInfoIterEnd',
 
573
    'LunListInfoIterStart', 'LunListInfoIterNext', 'LunListInfoIterEnd',
 
574
    'StorageServiceDatasetProvision']
 
575
 
 
576
iter_count = 0
 
577
iter_table = {}
 
578
 
 
579
 
 
580
class FakeDfmServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
 
581
    """HTTP handler that fakes enough stuff to allow the driver to run"""
 
582
 
 
583
    def do_GET(s):
 
584
        """Respond to a GET request."""
 
585
        if '/dfm.wsdl' != s.path:
 
586
            s.send_response(404)
 
587
            s.end_headers
 
588
            return
 
589
        s.send_response(200)
 
590
        s.send_header("Content-Type", "application/wsdl+xml")
 
591
        s.end_headers()
 
592
        out = s.wfile
 
593
        out.write(WSDL_HEADER)
 
594
        out.write(WSDL_TYPES)
 
595
        for api in APIS:
 
596
            out.write('<message name="%sRequest">' % api)
 
597
            out.write('<part element="na:%s" name="parameters"/>' % api)
 
598
            out.write('</message>')
 
599
            out.write('<message name="%sResponse">' % api)
 
600
            out.write('<part element="na:%sResult" name="results"/>' % api)
 
601
            out.write('</message>')
 
602
        out.write('<portType name="DfmInterface">')
 
603
        for api in APIS:
 
604
            out.write('<operation name="%s">' % api)
 
605
            out.write('<input message="na:%sRequest"/>' % api)
 
606
            out.write('<output message="na:%sResponse"/>' % api)
 
607
            out.write('</operation>')
 
608
        out.write('</portType>')
 
609
        out.write('<binding name="DfmBinding" type="na:DfmInterface">')
 
610
        out.write('<soap:binding style="document" ' +
 
611
            'transport="http://schemas.xmlsoap.org/soap/http"/>')
 
612
        for api in APIS:
 
613
            out.write('<operation name="%s">' % api)
 
614
            out.write('<soap:operation soapAction="urn:%s"/>' % api)
 
615
            out.write('<input><soap:body use="literal"/></input>')
 
616
            out.write('<output><soap:body use="literal"/></output>')
 
617
            out.write('</operation>')
 
618
        out.write('</binding>')
 
619
        out.write(WSDL_TRAILER)
 
620
        return
 
621
 
 
622
    def do_POST(s):
 
623
        """Respond to a POST request."""
 
624
        if '/apis/soap/v1' != s.path:
 
625
            s.send_response(404)
 
626
            s.end_headers
 
627
            return
 
628
        request_xml = s.rfile.read(int(s.headers['Content-Length']))
 
629
        ntap_ns = 'http://www.netapp.com/management/v1'
 
630
        nsmap = {'env': 'http://schemas.xmlsoap.org/soap/envelope/',
 
631
            'na': ntap_ns}
 
632
        root = etree.fromstring(request_xml)
 
633
 
 
634
        body = root.xpath('/env:Envelope/env:Body', namespaces=nsmap)[0]
 
635
        request = body.getchildren()[0]
 
636
        tag = request.tag
 
637
        if not tag.startswith('{' + ntap_ns + '}'):
 
638
            s.send_response(500)
 
639
            s.end_headers
 
640
            return
 
641
        api = tag[(2 + len(ntap_ns)):]
 
642
        global iter_count
 
643
        global iter_table
 
644
        if 'DatasetListInfoIterStart' == api:
 
645
            body = """<na:DatasetListInfoIterStartResult>
 
646
                    <na:Records>1</na:Records>
 
647
                    <na:Tag>dataset</na:Tag>
 
648
                </na:DatasetListInfoIterStartResult>"""
 
649
        elif 'DatasetListInfoIterNext' == api:
 
650
            body = """<na:DatasetListInfoIterNextResult>
 
651
                    <na:Datasets>
 
652
                        <na:DatasetInfo>
 
653
                            <na:DatasetId>0</na:DatasetId>
 
654
                        </na:DatasetInfo>
 
655
                    </na:Datasets>
 
656
                    <na:Records>1</na:Records>
 
657
                </na:DatasetListInfoIterNextResult>"""
 
658
        elif 'DatasetListInfoIterEnd' == api:
 
659
            body = """<na:DatasetListInfoIterEndResult/>"""
 
660
        elif 'DatasetEditBegin' == api:
 
661
            body = """<na:DatasetEditBeginResult>
 
662
                    <na:EditLockId>0</na:EditLockId>
 
663
                </na:DatasetEditBeginResult>"""
 
664
        elif 'DatasetEditCommit' == api:
 
665
            body = """<na:DatasetEditCommitResult>
 
666
                    <na:IsProvisioningFailure>false</na:IsProvisioningFailure>
 
667
                    <na:JobIds>
 
668
                        <na:JobInfo>
 
669
                            <na:JobId>0</na:JobId>
 
670
                        </na:JobInfo>
 
671
                    </na:JobIds>
 
672
                </na:DatasetEditCommitResult>"""
 
673
        elif 'DatasetProvisionMember' == api:
 
674
            body = """<na:DatasetProvisionMemberResult/>"""
 
675
        elif 'DatasetRemoveMember' == api:
 
676
            body = """<na:DatasetRemoveMemberResult/>"""
 
677
        elif 'DfmAbout' == api:
 
678
            body = """<na:DfmAboutResult/>"""
 
679
        elif 'DpJobProgressEventListIterStart' == api:
 
680
            iter_name = 'dpjobprogress_%s' % iter_count
 
681
            iter_count = iter_count + 1
 
682
            iter_table[iter_name] = 0
 
683
            body = """<na:DpJobProgressEventListIterStartResult>
 
684
                    <na:Records>2</na:Records>
 
685
                    <na:Tag>%s</na:Tag>
 
686
                </na:DpJobProgressEventListIterStartResult>""" % iter_name
 
687
        elif 'DpJobProgressEventListIterNext' == api:
 
688
            tags = body.xpath('na:DpJobProgressEventListIterNext/na:Tag',
 
689
                              namespaces=nsmap)
 
690
            iter_name = tags[0].text
 
691
            if iter_table[iter_name]:
 
692
                body = """<na:DpJobProgressEventListIterNextResult/>"""
 
693
            else:
 
694
                iter_table[iter_name] = 1
 
695
                body = """<na:DpJobProgressEventListIterNextResult>
 
696
                        <na:ProgressEvents>
 
697
                            <na:DpJobProgressEventInfo>
 
698
                                <na:EventStatus>normal</na:EventStatus>
 
699
                                <na:EventType>lun-create</na:EventType>
 
700
                                <na:ProgressLunInfo>
 
701
                                    <na:LunPathId>0</na:LunPathId>
 
702
                                 </na:ProgressLunInfo>
 
703
                            </na:DpJobProgressEventInfo>
 
704
                            <na:DpJobProgressEventInfo>
 
705
                                <na:EventStatus>normal</na:EventStatus>
 
706
                                <na:EventType>job-end</na:EventType>
 
707
                            </na:DpJobProgressEventInfo>
 
708
                        </na:ProgressEvents>
 
709
                        <na:Records>2</na:Records>
 
710
                    </na:DpJobProgressEventListIterNextResult>"""
 
711
        elif 'DpJobProgressEventListIterEnd' == api:
 
712
            body = """<na:DpJobProgressEventListIterEndResult/>"""
 
713
        elif 'DatasetMemberListInfoIterStart' == api:
 
714
            body = """<na:DatasetMemberListInfoIterStartResult>
 
715
                    <na:Records>1</na:Records>
 
716
                    <na:Tag>dataset-member</na:Tag>
 
717
                </na:DatasetMemberListInfoIterStartResult>"""
 
718
        elif 'DatasetMemberListInfoIterNext' == api:
 
719
            name = 'filer:/OpenStack_testproj/volume-00000001/volume-00000001'
 
720
            body = """<na:DatasetMemberListInfoIterNextResult>
 
721
                    <na:DatasetMembers>
 
722
                        <na:DatasetMemberInfo>
 
723
                            <na:MemberId>0</na:MemberId>
 
724
                            <na:MemberName>%s</na:MemberName>
 
725
                        </na:DatasetMemberInfo>
 
726
                    </na:DatasetMembers>
 
727
                    <na:Records>1</na:Records>
 
728
                </na:DatasetMemberListInfoIterNextResult>""" % name
 
729
        elif 'DatasetMemberListInfoIterEnd' == api:
 
730
            body = """<na:DatasetMemberListInfoIterEndResult/>"""
 
731
        elif 'HostListInfoIterStart' == api:
 
732
            body = """<na:HostListInfoIterStartResult>
 
733
                    <na:Records>1</na:Records>
 
734
                    <na:Tag>host</na:Tag>
 
735
                </na:HostListInfoIterStartResult>"""
 
736
        elif 'HostListInfoIterNext' == api:
 
737
            body = """<na:HostListInfoIterNextResult>
 
738
                    <na:Hosts>
 
739
                        <na:HostInfo>
 
740
                            <na:HostAddress>1.2.3.4</na:HostAddress>
 
741
                            <na:HostId>0</na:HostId>
 
742
                            <na:HostName>filer</na:HostName>
 
743
                        </na:HostInfo>
 
744
                    </na:Hosts>
 
745
                    <na:Records>1</na:Records>
 
746
                </na:HostListInfoIterNextResult>"""
 
747
        elif 'HostListInfoIterEnd' == api:
 
748
            body = """<na:HostListInfoIterEndResult/>"""
 
749
        elif 'LunListInfoIterStart' == api:
 
750
            body = """<na:LunListInfoIterStartResult>
 
751
                    <na:Records>1</na:Records>
 
752
                    <na:Tag>lun</na:Tag>
 
753
                </na:LunListInfoIterStartResult>"""
 
754
        elif 'LunListInfoIterNext' == api:
 
755
            path = 'OpenStack_testproj/volume-00000001/volume-00000001'
 
756
            body = """<na:LunListInfoIterNextResult>
 
757
                    <na:Luns>
 
758
                        <na:LunInfo>
 
759
                            <na:HostId>0</na:HostId>
 
760
                            <na:LunPath>%s</na:LunPath>
 
761
                        </na:LunInfo>
 
762
                    </na:Luns>
 
763
                    <na:Records>1</na:Records>
 
764
                </na:LunListInfoIterNextResult>""" % path
 
765
        elif 'LunListInfoIterEnd' == api:
 
766
            body = """<na:LunListInfoIterEndResult/>"""
 
767
        elif 'ApiProxy' == api:
 
768
            names = body.xpath('na:ApiProxy/na:Request/na:Name',
 
769
                               namespaces=nsmap)
 
770
            proxy = names[0].text
 
771
            if 'igroup-list-info' == proxy:
 
772
                igroup = 'openstack-iqn.1993-08.org.debian:01:23456789'
 
773
                initiator = 'iqn.1993-08.org.debian:01:23456789'
 
774
                proxy_body = """<initiator-groups>
 
775
                        <initiator-group-info>
 
776
                            <initiator-group-name>%s</initiator-group-name>
 
777
                            <initiator-group-type>iscsi</initiator-group-type>
 
778
                       <initiator-group-os-type>linux</initiator-group-os-type>
 
779
                            <initiators>
 
780
                                <initiator-info>
 
781
                                    <initiator-name>%s</initiator-name>
 
782
                                </initiator-info>
 
783
                            </initiators>
 
784
                        </initiator-group-info>
 
785
                    </initiator-groups>""" % (igroup, initiator)
 
786
            elif 'igroup-create' == proxy:
 
787
                proxy_body = ''
 
788
            elif 'igroup-add' == proxy:
 
789
                proxy_body = ''
 
790
            elif 'lun-map-list-info' == proxy:
 
791
                proxy_body = '<initiator-groups/>'
 
792
            elif 'lun-map' == proxy:
 
793
                proxy_body = '<lun-id-assigned>0</lun-id-assigned>'
 
794
            elif 'lun-unmap' == proxy:
 
795
                proxy_body = ''
 
796
            elif 'iscsi-portal-list-info' == proxy:
 
797
                proxy_body = """<iscsi-portal-list-entries>
 
798
                        <iscsi-portal-list-entry-info>
 
799
                            <ip-address>1.2.3.4</ip-address>
 
800
                            <ip-port>3260</ip-port>
 
801
                            <tpgroup-tag>1000</tpgroup-tag>
 
802
                        </iscsi-portal-list-entry-info>
 
803
                    </iscsi-portal-list-entries>"""
 
804
            elif 'iscsi-node-get-name' == proxy:
 
805
                target = 'iqn.1992-08.com.netapp:sn.111111111'
 
806
                proxy_body = '<node-name>%s</node-name>' % target
 
807
            else:
 
808
                # Unknown proxy API
 
809
                s.send_response(500)
 
810
                s.end_headers
 
811
                return
 
812
            api = api + ':' + proxy
 
813
            proxy_header = '<na:ApiProxyResult><na:Response><na:Results>'
 
814
            proxy_trailer = """</na:Results><na:Status>passed</na:Status>
 
815
                </na:Response></na:ApiProxyResult>"""
 
816
            body = proxy_header + proxy_body + proxy_trailer
 
817
        else:
 
818
            # Unknown API
 
819
            s.send_response(500)
 
820
            s.end_headers
 
821
            return
 
822
        s.send_response(200)
 
823
        s.send_header("Content-Type", "text/xml; charset=utf-8")
 
824
        s.end_headers()
 
825
        s.wfile.write(RESPONSE_PREFIX)
 
826
        s.wfile.write(body)
 
827
        s.wfile.write(RESPONSE_SUFFIX)
 
828
        return
 
829
 
 
830
 
 
831
class FakeHttplibSocket(object):
 
832
    """A fake socket implementation for httplib.HTTPResponse"""
 
833
    def __init__(self, value):
 
834
        self._rbuffer = StringIO.StringIO(value)
 
835
        self._wbuffer = StringIO.StringIO('')
 
836
        oldclose = self._wbuffer.close
 
837
 
 
838
        def newclose():
 
839
            self.result = self._wbuffer.getvalue()
 
840
            oldclose()
 
841
        self._wbuffer.close = newclose
 
842
 
 
843
    def makefile(self, mode, _other):
 
844
        """Returns the socket's internal buffer"""
 
845
        if mode == 'r' or mode == 'rb':
 
846
            return self._rbuffer
 
847
        if mode == 'w' or mode == 'wb':
 
848
            return self._wbuffer
 
849
 
 
850
 
 
851
class FakeHTTPConnection(object):
 
852
    """A fake httplib.HTTPConnection for netapp tests
 
853
 
 
854
    Requests made via this connection actually get translated and routed into
 
855
    the fake Dfm handler above, we then turn the response into
 
856
    the httplib.HTTPResponse that the caller expects.
 
857
    """
 
858
    def __init__(self, host, timeout=None):
 
859
        self.host = host
 
860
 
 
861
    def request(self, method, path, data=None, headers=None):
 
862
        if not headers:
 
863
            headers = {}
 
864
        req_str = '%s %s HTTP/1.1\r\n' % (method, path)
 
865
        for key, value in headers.iteritems():
 
866
            req_str += "%s: %s\r\n" % (key, value)
 
867
        if data:
 
868
            req_str += '\r\n%s' % data
 
869
 
 
870
        # NOTE(vish): normally the http transport normailizes from unicode
 
871
        sock = FakeHttplibSocket(req_str.decode("latin-1").encode("utf-8"))
 
872
        # NOTE(vish): stop the server from trying to look up address from
 
873
        #             the fake socket
 
874
        FakeDfmServerHandler.address_string = lambda x: '127.0.0.1'
 
875
        self.app = FakeDfmServerHandler(sock, '127.0.0.1:8088', None)
 
876
 
 
877
        self.sock = FakeHttplibSocket(sock.result)
 
878
        self.http_response = httplib.HTTPResponse(self.sock)
 
879
 
 
880
    def set_debuglevel(self, level):
 
881
        pass
 
882
 
 
883
    def getresponse(self):
 
884
        self.http_response.begin()
 
885
        return self.http_response
 
886
 
 
887
    def getresponsebody(self):
 
888
        return self.sock.result
 
889
 
 
890
 
 
891
class NetAppDriverTestCase(test.TestCase):
 
892
    """Test case for NetAppISCSIDriver"""
 
893
    STORAGE_SERVICE = 'Thin Provisioned Space for VMFS Datastores'
 
894
    PROJECT_ID = 'testproj'
 
895
    VOLUME_NAME = 'volume-00000001'
 
896
    VOLUME_SIZE = 2147483648L  # 2 GB
 
897
    INITIATOR = 'iqn.1993-08.org.debian:01:23456789'
 
898
 
 
899
    def setUp(self):
 
900
        super(NetAppDriverTestCase, self).setUp()
 
901
        driver = NetAppISCSIDriver()
 
902
        self.stubs.Set(httplib, 'HTTPConnection', FakeHTTPConnection)
 
903
        driver._create_client('http://localhost:8088/dfm.wsdl',
 
904
                              'root', 'password', 'localhost', 8088)
 
905
        driver._set_storage_service(self.STORAGE_SERVICE)
 
906
        self.driver = driver
 
907
 
 
908
    def test_connect(self):
 
909
        self.driver.check_for_setup_error()
 
910
 
 
911
    def test_create_destroy(self):
 
912
        self.driver._provision(self.VOLUME_NAME, None, self.PROJECT_ID,
 
913
                               self.VOLUME_SIZE)
 
914
        self.driver._remove_destroy(self.VOLUME_NAME, self.PROJECT_ID)
 
915
 
 
916
    def test_map_unmap(self):
 
917
        self.driver._provision(self.VOLUME_NAME, None, self.PROJECT_ID,
 
918
                               self.VOLUME_SIZE)
 
919
        volume = {'name': self.VOLUME_NAME, 'project_id': self.PROJECT_ID,
 
920
            'id': 0, 'provider_auth': None}
 
921
        updates = self.driver._get_export(volume)
 
922
        self.assertTrue(updates['provider_location'])
 
923
        volume['provider_location'] = updates['provider_location']
 
924
        connector = {'initiator': self.INITIATOR}
 
925
        connection_info = self.driver.initialize_connection(volume, connector)
 
926
        self.assertEqual(connection_info['driver_volume_type'], 'iscsi')
 
927
        properties = connection_info['data']
 
928
        self.driver.terminate_connection(volume, connector)
 
929
        self.driver._remove_destroy(self.VOLUME_NAME, self.PROJECT_ID)