1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright (c) 2012 NetApp, Inc.
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
10
# http://www.apache.org/licenses/LICENSE-2.0
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
17
"""Unit tests for the NetApp-specific NFS driver module (netapp_nfs)"""
19
from nova import context
20
from nova import exception
23
from nova.volume import netapp
24
from nova.volume import netapp_nfs
25
from nova.volume import nfs
27
from mox import IgnoreArg
29
from mox import MockObject
36
class FakeVolume(object):
37
def __init__(self, size=0):
42
def __getitem__(self, key):
43
return self.__dict__[key]
46
class FakeSnapshot(object):
47
def __init__(self, volume_size=0):
48
self.volume_name = None
51
self.volume_size = volume_size
55
def __getitem__(self, key):
56
return self.__dict__[key]
59
class FakeResponce(object):
60
def __init__(self, status):
62
:param status: Either 'failed' or 'passed'
66
if status == 'failed':
67
self.Reason = 'Sample error'
70
class NetappNfsDriverTestCase(test.TestCase):
71
"""Test case for NetApp specific NFS clone driver"""
74
self._driver = netapp_nfs.NetAppNFSDriver()
78
self._mox.UnsetStubs()
80
def test_check_for_setup_error(self):
87
'netapp_server_hostname',
91
# check exception raises when flags are not set
92
self.assertRaises(exception.NovaException,
93
drv.check_for_setup_error)
96
for flag in required_flags:
97
setattr(netapp.FLAGS, flag, 'val')
99
mox.StubOutWithMock(nfs.NfsDriver, 'check_for_setup_error')
100
nfs.NfsDriver.check_for_setup_error()
103
drv.check_for_setup_error()
107
# restore initial FLAGS
108
for flag in required_flags:
109
delattr(netapp.FLAGS, flag)
111
def test_do_setup(self):
115
mox.StubOutWithMock(drv, 'check_for_setup_error')
116
mox.StubOutWithMock(netapp_nfs.NetAppNFSDriver, '_get_client')
118
drv.check_for_setup_error()
119
netapp_nfs.NetAppNFSDriver._get_client()
123
drv.do_setup(IsA(context.RequestContext))
127
def test_create_snapshot(self):
128
"""Test snapshot can be created and deleted"""
132
mox.StubOutWithMock(drv, '_clone_volume')
133
drv._clone_volume(IgnoreArg(), IgnoreArg(), IgnoreArg())
136
drv.create_snapshot(FakeSnapshot())
140
def test_create_volume_from_snapshot(self):
141
"""Tests volume creation from snapshot"""
144
volume = FakeVolume(1)
145
snapshot = FakeSnapshot(2)
147
self.assertRaises(exception.NovaException,
148
drv.create_volume_from_snapshot,
152
snapshot = FakeSnapshot(1)
154
location = '127.0.0.1:/nfs'
155
expected_result = {'provider_location': location}
156
mox.StubOutWithMock(drv, '_clone_volume')
157
mox.StubOutWithMock(drv, '_get_volume_location')
158
drv._clone_volume(IgnoreArg(), IgnoreArg(), IgnoreArg())
159
drv._get_volume_location(IgnoreArg()).AndReturn(location)
163
loc = drv.create_volume_from_snapshot(volume, snapshot)
165
self.assertEquals(loc, expected_result)
169
def _prepare_delete_snapshot_mock(self, snapshot_exists):
173
mox.StubOutWithMock(drv, '_get_provider_location')
174
mox.StubOutWithMock(drv, '_volume_not_present')
177
mox.StubOutWithMock(drv, '_execute')
178
mox.StubOutWithMock(drv, '_get_volume_path')
180
drv._get_provider_location(IgnoreArg())
181
drv._volume_not_present(IgnoreArg(), IgnoreArg())\
182
.AndReturn(not snapshot_exists)
185
drv._get_volume_path(IgnoreArg(), IgnoreArg())
186
drv._execute('rm', None, run_as_root=True)
192
def test_delete_existing_snapshot(self):
194
mox = self._prepare_delete_snapshot_mock(True)
196
drv.delete_snapshot(FakeSnapshot())
200
def test_delete_missing_snapshot(self):
202
mox = self._prepare_delete_snapshot_mock(False)
204
drv.delete_snapshot(FakeSnapshot())
208
def _prepare_clone_mock(self, status):
212
volume = FakeVolume()
213
setattr(volume, 'provider_location', '127.0.0.1:/nfs')
215
drv._client = MockObject(suds.client.Client)
216
drv._client.factory = MockObject(suds.client.Factory)
217
drv._client.service = MockObject(suds.client.ServiceSelector)
219
# ApiProxy() method is generated by ServiceSelector at runtime from the
220
# XML, so mocking is impossible.
221
setattr(drv._client.service,
223
types.MethodType(lambda *args, **kwargs: FakeResponce(status),
224
suds.client.ServiceSelector))
225
mox.StubOutWithMock(drv, '_get_host_id')
226
mox.StubOutWithMock(drv, '_get_full_export_path')
228
drv._get_host_id(IgnoreArg()).AndReturn('10')
229
drv._get_full_export_path(IgnoreArg(), IgnoreArg()).AndReturn('/nfs')
233
def test_successfull_clone_volume(self):
235
mox = self._prepare_clone_mock('passed')
239
volume_name = 'volume_name'
240
clone_name = 'clone_name'
241
volume_id = volume_name + str(hash(volume_name))
243
drv._clone_volume(volume_name, clone_name, volume_id)
247
def test_failed_clone_volume(self):
249
mox = self._prepare_clone_mock('failed')
253
volume_name = 'volume_name'
254
clone_name = 'clone_name'
255
volume_id = volume_name + str(hash(volume_name))
257
self.assertRaises(exception.NovaException,
259
volume_name, clone_name, volume_id)