1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# Copyright (C) 2020 Red Hat, Inc. <http://www.redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from glusto.core import Glusto as g
from glustolibs.gluster.exceptions import ExecutionError
from glustolibs.gluster.gluster_base_class import GlusterBaseClass, runs_on
from glustolibs.io.utils import open_file_fd
from glustolibs.gluster.volume_libs import expand_volume
from glustolibs.gluster.rebalance_ops import (rebalance_start,
wait_for_rebalance_to_complete,
get_rebalance_status)
@runs_on([['distributed', 'replicated', 'arbiter',
'dispersed'],
['glusterfs']])
class TestOpenFileMigration(GlusterBaseClass):
def setUp(self):
# Calling GlusterBaseClass setUp
self.get_super_method(self, 'setUp')()
# Setup Volume and Mount Volume
ret = self.setup_volume_and_mount_volume(mounts=self.mounts)
if not ret:
raise ExecutionError("Failed to Setup_Volume and Mount_Volume")
def tearDown(self):
"""
Cleanup and umount volume
"""
# Calling GlusterBaseClass teardown
self.get_super_method(self, 'tearDown')()
# Cleanup and umount volume
ret = self.unmount_volume_and_cleanup_volume(mounts=self.mounts)
if not ret:
raise ExecutionError("Failed to umount the vol & cleanup Volume")
g.log.info("Successful in umounting the volume and Cleanup")
def test_open_file_migration(self):
"""
Description: Checks that files with open fd are migrated successfully.
Steps :
1) Create a volume.
2) Mount the volume using FUSE.
3) Create files on volume mount.
4) Open fd for the files and keep on doing read write operations on
these files.
5) While fds are open, add bricks to the volume and trigger rebalance.
6) Wait for rebalance to complete.
7) Wait for write on open fd to complete.
8) Check for any data loss during rebalance.
9) Check if rebalance has any failures.
"""
# Create files and open fd for the files on mount point
m_point = self.mounts[0].mountpoint
cmd = ('cd {}; for i in `seq 261 1261`;do touch testfile$i;'
'done'.format(m_point))
ret, _, _ = g.run(self.clients[0], cmd)
self.assertEqual(ret, 0, "Failed to create files")
g.log.info("Successfully created files")
proc = open_file_fd(m_point, 2, self.clients[0],
start_range=301, end_range=400)
# Calculate file count for the mount-point
cmd = ("ls -lR {}/testfile* | wc -l".format(m_point))
ret, count_before, _ = g.run(self.clients[0], cmd)
self.assertEqual(ret, 0, "Failed to get file count")
g.log.info("File count before rebalance is:%s", count_before)
# Add bricks to the volume
ret = expand_volume(self.mnode, self.volname, self.servers,
self.all_servers_info)
self.assertTrue(ret, ("Failed to expand the volume %s",
self.volname))
g.log.info("Expanding volume is successful on "
"volume %s", self.volname)
# Trigger rebalance
ret, _, _ = rebalance_start(self.mnode, self.volname)
self.assertEqual(ret, 0, "Failed to start rebalance")
g.log.info("Rebalance is started")
# Wait for rebalance to complete
ret = wait_for_rebalance_to_complete(self.mnode, self.volname,
timeout=300)
self.assertTrue(ret, ("Rebalance failed on volume %s",
self.volname))
g.log.info("Rebalance is successful on "
"volume %s", self.volname)
# Close connection and check if write on open fd has completed
ret, _, _ = proc.async_communicate()
self.assertEqual(ret, 0, "Write on open fd"
" has not completed yet")
g.log.info("Write completed on open fd")
# Calculate file count for the mount-point
cmd = ("ls -lR {}/testfile* | wc -l".format(m_point))
ret, count_after, _ = g.run(self.clients[0], cmd)
self.assertEqual(ret, 0, "Failed to get file count")
g.log.info("File count after rebalance is:%s", count_after)
# Check if there is any data loss
self.assertEqual(int(count_before), int(count_after),
"The file count before and after"
" rebalance is not same."
" There is data loss.")
g.log.info("The file count before and after rebalance is same."
" No data loss occurred.")
# Check if rebalance has any failures
ret = get_rebalance_status(self.mnode, self.volname)
no_of_failures = ret['aggregate']['failures']
self.assertEqual(int(no_of_failures), 0,
"Failures in rebalance")
g.log.info("No failures in rebalance")
|