def _validate_error_in_mount_log(self, pattern, exp_pre=True): """ Validate type of error from mount log on setting quota """ assert_method = self.assertTrue assert_msg = ('Fail: Not able to validate presence of "{}" ' 'in mount log'.format(pattern)) if not exp_pre: assert_method = self.assertFalse assert_msg = ('Fail: Not able to validate absence of "{}" ' 'in mount log'.format(pattern)) ret = search_pattern_in_file(self.client, pattern, self.logpath, self.bp_text + str(self.bp_count - 2), self.bp_text + str(self.bp_count - 1)) assert_method(ret, assert_msg) # Validate against `quota list` command if 'quota' in pattern.lower(): dir_path = '/dir/dir1' ret = quota_fetch_list(self.mnode, self.volname) self.assertIsNotNone( ret.get(dir_path), 'Not able to get quota list for the path {}'.format(dir_path)) ret = ret.get(dir_path) verified = False if ret['sl_exceeded'] is exp_pre and ret['hl_exceeded'] is exp_pre: verified = True self.assertTrue( verified, 'Failed to validate Quota list command against ' 'soft and hard limits')
def quota_validate(mnode, volname, path, **kwargs): """ Validate if the hard limit, soft limit, usage match the expected values. If any of the arguments are None, they are not verified. Args: mnode (str) : Node on which command has to be executed. volname (str) : volume name. path (str) : Path to be verified. kwargs hard_limit(int) : hard limit is verified with this value. soft_limit_percent(int) : soft limit (in %) is verified with this value used_space(int) : if set, usage as displayed in quota list is verified with expected value. avail_space(int) : if set, usage as displayed in quota list is verified with expected value. sl_exceeded(bool) : expected value of soft limit flag. hl_exceeded(bool) : expected value of hard limit flag. """ if kwargs is None: g.log.error("No arguments given for validation") return False quotalist = quota_fetch_list(mnode, volname, path) if path not in quotalist: g.log.error("Path not found (script issue) path: %s", path) return False else: listinfo = quotalist[path] ret = True for key, value in kwargs.items(): if key and listinfo[key] != value: g.log.error("%s = %s does not match with expected value %s", key, str(listinfo[key]), str(value)) ret = False return ret
def test_subdir_with_quota_limit(self): # pylint: disable=too-many-statements """ Mount the volume Create 2 subdir on mount point dir1-> /level1/subdir1 dir2->/dlevel1/dlevel2/dlevel3/subdir2 Auth allow - Client1(/level1/subdir1), Client2(/dlevel1/dlevel2/dlevel3/subdir2) Mount the subdir1 on client 1 and subdir2 on client2 Enable Quota Verify Quota is enabled on volume Set quota limit as 1GB and 2GB on both subdirs respectively Perform a quota list operation Perform IO's on both subdir until quota limit is almost hit for subdir1 Again Perform a quota list operation Run IO's on Client 1.This should fail Run IO's on Client2.This should pass """ # Create deep subdirectories subdir1 and subdir2 on mount point ret = mkdir(self.mounts[0].client_system, "%s/level1/subdir1" % self.mounts[0].mountpoint, parents=True) self.assertTrue( ret, ("Failed to create directory '/level1/subdir1' on" "volume %s from client %s" % (self.mounts[0].volname, self.mounts[0].client_system))) ret = mkdir(self.mounts[0].client_system, "%s/dlevel1/dlevel2/dlevel3/subdir2" % self.mounts[0].mountpoint, parents=True) self.assertTrue( ret, ("Failed to create directory " "'/dlevel1/dlevel2/dlevel3/subdir2' on" "volume %s from client %s" % (self.mounts[0].volname, self.mounts[0].client_system))) # unmount volume ret = self.unmount_volume(self.mounts) self.assertTrue(ret, "Volumes Unmount failed") g.log.info("Volumes Unmounted successfully") # Set authentication on the subdirectory subdir1 # and subdir2 g.log.info( 'Setting authentication on directories subdir1 and subdir2' 'for client %s and %s', self.clients[0], self.clients[1]) ret = set_auth_allow( self.volname, self.mnode, { '/level1/subdir1': [self.clients[0]], '/dlevel1/dlevel2/dlevel3/subdir2': [self.clients[1]] }) self.assertTrue( ret, 'Failed to set Authentication on volume %s' % self.volume) # Creating mount list for subdirectories self.subdir_mounts = [ copy.deepcopy(self.mounts[0]), copy.deepcopy(self.mounts[1]) ] self.subdir_mounts[0].volname = "%s/level1/subdir1" % self.volname self.subdir_mounts[1].volname = ("%s/dlevel1/dlevel2/dlevel3/subdir2" % self.volname) # Mount Subdirectory "subdir1" on client 1 and "subdir2" on client 2 for mount_obj in self.subdir_mounts: ret = mount_obj.mount() self.assertTrue( ret, ("Failed to mount %s on client" " %s" % (mount_obj.volname, mount_obj.client_system))) g.log.info("Successfully mounted %s on client %s", mount_obj.volname, mount_obj.client_system) g.log.info("Successfully mounted subdirectories on client1" "and clients 2") # Enable quota on volume g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the volume " "%s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Check if quota is enabled g.log.info("Validate Quota is enabled on the volume %s", self.volname) ret = is_quota_enabled(self.mnode, self.volname) self.assertTrue( ret, ("Quota is not enabled on the volume %s", self.volname)) g.log.info("Successfully Validated quota is enabled on volume %s", self.volname) # Setting up path to set quota limit path1 = "/level1/subdir1" path2 = "/dlevel1/dlevel2/dlevel3/subdir2" # Set Quota limit on the subdirectory "subdir1" g.log.info("Set Quota Limit on the path %s of the volume %s", path1, self.volname) ret, _, _ = quota_limit_usage(self.mnode, self.volname, path1, limit="1GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " " the volume %s", path1, self.volname)) g.log.info( "Successfully set the Quota limit on %s of the volume " "%s", path1, self.volname) # Set Quota limit on the subdirectory "subdir2" g.log.info("Set Quota Limit on the path %s of the volume %s", path2, self.volname) ret, _, _ = quota_limit_usage(self.mnode, self.volname, path2, limit="2GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " " the volume %s", path2, self.volname)) g.log.info( "Successfully set the Quota limit on %s of the volume " "%s", path2, self.volname) # Get Quota List on the volume g.log.info("Get Quota list on the volume %s", self.volname) quota_list = quota_fetch_list(self.mnode, self.volname) self.assertIsNotNone(quota_list, ("Failed to get the quota list " "of the volume %s", self.volname)) # Check for subdir1 path in quota list self.assertIn( path1, quota_list.keys(), ("%s not part of the quota list %s even if " "it is set on the volume %s", path1, quota_list, self.volname)) # Check for subdir2 path in quota list self.assertIn( path2, quota_list.keys(), ("%s not part of the quota list %s even if " "it is set on the volume %s", path2, quota_list, self.volname)) g.log.info("Successfully listed quota list %s of the " "volume %s", quota_list, self.volname) # Create near to 1GB of data on both subdir mounts for mount_object in self.subdir_mounts: g.log.info("Creating Files on %s:%s", mount_object.client_system, mount_object.mountpoint) cmd = ("cd %s ; for i in `seq 1 1023` ;" "do dd if=/dev/urandom of=file$i bs=1M " "count=1;done" % (mount_object.mountpoint)) ret, _, _ = g.run(mount_object.client_system, cmd) self.assertEqual(ret, 0, "Failed to create files on mountpoint") g.log.info("Files created successfully on mountpoint") # Again Get Quota List on the volume g.log.info("Get Quota list on the volume %s", self.volname) quota_list = quota_fetch_list(self.mnode, self.volname) self.assertIsNotNone(quota_list, ("Failed to get the quota list " "of the volume %s", self.volname)) # Check for subdir1 path in quota list self.assertIn( path1, quota_list.keys(), ("%s not part of the quota list %s even if " "it is set on the volume %s", path1, quota_list, self.volname)) # Check for subdir2 path in quota list self.assertIn( path2, quota_list.keys(), ("%s not part of the quota list %s even if " "it is set on the volume %s", path2, quota_list, self.volname)) g.log.info("Successfully listed quota list %s of the " "volume %s", quota_list, self.volname) # Again run IO's to check if quota limit is adhere for subdir1 # Start IO's on subdir1 g.log.info("Creating Files on %s:%s", self.clients[0], self.subdir_mounts[0].mountpoint) cmd = ("cd %s ; for i in `seq 1024 1500` ;" "do dd if=/dev/urandom of=file$i bs=1M " "count=1;done" % (self.subdir_mounts[0].mountpoint)) ret, _, _ = g.run(self.clients[0], cmd) if ret == 0: raise ExecutionError("IO was expected to Fail." "But it got passed") else: g.log.info( "IO's failed as expected on %s:%s as quota " "limit reached already", self.clients[0], self.subdir_mounts[0].mountpoint) # Start IO's on subdir2 g.log.info("Creating Files on %s:%s", self.clients[1], self.subdir_mounts[1].mountpoint) cmd = ("cd %s ; for i in `seq 1024 1500` ;" "do dd if=/dev/urandom of=file$i bs=1M " "count=1;done" % (self.subdir_mounts[1].mountpoint)) ret, _, _ = g.run(self.clients[1], cmd) self.assertEqual(ret, 0, ("Failed to create files on %s" % self.clients[1])) g.log.info("Files created successfully on %s:%s", self.clients[1], self.subdir_mounts[1].mountpoint)
def test_quota_list_path_values(self): """ Verifying directory quota list functionality where giving the quota list command with and without the path should return the same output. * Enable quota * Set limit of 2 GB on / * Create data inside the volume * Execute a quota list command with and without path where both outputs should be same """ # Enable Quota g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the volume " "%s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Path to set quota limit path = "/" # Set Quota limit on the root of the volume g.log.info("Set Quota Limit on the path %s of the volume %s", path, self.volname) ret, _, _ = quota_limit_usage(self.mnode, self.volname, path=path, limit="2GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " " the volume %s", path, self.volname)) g.log.info("Successfully set the Quota limit on %s of the volume " "%s", path, self.volname) # Starting IO on the mounts for mount_object in self.mounts: g.log.info("Creating Files on %s:%s", mount_object.client_system, mount_object.mountpoint) cmd = ("cd %s ; mkdir foo ; cd foo ; for i in `seq 1 100` ;" "do dd if=/dev/urandom of=file$i bs=20M " "count=1;done" % (mount_object.mountpoint)) ret, _, _ = g.run(mount_object.client_system, cmd) self.assertEqual(ret, 0, "Failed to create files on mountpoint") g.log.info("Files created successfully on mountpoint") # Get Quota list without specifying the path g.log.info("Get Quota list for the volume %s", self.volname) quota_list1 = quota_fetch_list(self.mnode, self.volname, path=None) self.assertIsNotNone(quota_list1, ("Failed to get the quota list for " "the volume %s", self.volname)) self.assertIn(path, quota_list1.keys(), ("%s not part of the ""quota list %s even if " "it is set on the volume %s", path, quota_list1, self.volname)) g.log.info("Successfully listed quota list %s of the " "volume %s", quota_list1, self.volname) # Get Quota List with path mentioned in the command g.log.info("Get Quota list for path %s of the volume %s", path, self.volname) quota_list2 = quota_fetch_list(self.mnode, self.volname, path=path) self.assertIsNotNone(quota_list2, ("Failed to get the quota list for " "path %s of the volume %s", path, self.volname)) self.assertIn(path, quota_list2.keys(), ("%s not part of the ""quota list %s even if " "it is set on the volume %s", path, quota_list2, self.volname)) g.log.info("Successfully listed path %s in the quota list %s of the " "volume %s", path, quota_list2, self.volname) # Validate both outputs of the list commands with and without paths g.log.info("Validating the output of quota list command with path and " "without path is the same for volume %s.", self.volname) self.assertEqual(quota_list1, quota_list2, ("The output of quota list for volume " "%s is different as compared among " "command with path and command without " "path.", self.volname)) g.log.info("Successfully validated both outputs of quota list command " "with and without path are the same in volume " "%s.", self.volname)
def test_quota_enable_disable_enable_when_io_in_progress(self): """Enable, Disable and Re-enable Quota on the volume when IO is in progress. """ # Enable Quota g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the volume %s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Check if quota is enabled g.log.info("Validate Quota is enabled on the volume %s", self.volname) ret = is_quota_enabled(self.mnode, self.volname) self.assertTrue(ret, ("Quota is not enabled on the volume %s", self.volname)) g.log.info("Successfully Validated quota is enabled on volume %s", self.volname) # Path to set quota limit path = "/" # Set Quota limit on the root of the volume g.log.info("Set Quota Limit on the path %s of the volume %s", path, self.volname) ret, _, _ = quota_limit_usage(self.mnode, self.volname, path=path, limit="1GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " " the volume %s", path, self.volname)) g.log.info("Successfully set the Quota limit on %s of the volume %s", path, self.volname) # quota_fetch_list g.log.info("Get Quota list for path %s of the volume %s", path, self.volname) quota_list = quota_fetch_list(self.mnode, self.volname, path=path) self.assertIsNotNone(quota_list, ("Failed to get the quota list for " "path %s of the volume %s", path, self.volname)) self.assertIn(path, quota_list.keys(), ("%s not part of the ""quota list %s even if " "it is set on the volume %s", path, quota_list, self.volname)) g.log.info("Successfully listed path %s in the quota list %s of the " "volume %s", path, quota_list, self.volname) # Disable quota g.log.info("Disable quota on the volume %s", self.volname) ret, _, _ = quota_disable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to disable quota on the volume %s", self.volname)) g.log.info("Successfully disabled quota on the volume %s", self.volname) # Check if quota is still enabled (expected : Disabled) g.log.info("Validate Quota is enabled on the volume %s", self.volname) ret = is_quota_enabled(self.mnode, self.volname) self.assertFalse(ret, ("Quota is still enabled on the volume %s " "(expected: Disable) ", self.volname)) g.log.info("Successfully Validated quota is disabled on volume %s", self.volname) # Enable Quota g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the volume %s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Check if quota is enabled g.log.info("Validate Quota is enabled on the volume %s", self.volname) ret = is_quota_enabled(self.mnode, self.volname) self.assertTrue(ret, ("Quota is not enabled on the volume %s", self.volname)) g.log.info("Successfully Validated quota is enabled on volume %s", self.volname) # quota_fetch_list g.log.info("Get Quota list for path %s of the volume %s", path, self.volname) quota_list = quota_fetch_list(self.mnode, self.volname, path=path) self.assertIsNotNone(quota_list, ("Failed to get the quota list for " "path %s of the volume %s", path, self.volname)) self.assertIn(path, quota_list.keys(), ("%s not part of the quota list %s even if " "it is set on the volume %s", path, quota_list, self.volname)) g.log.info("Successfully listed path %s in the quota list %s of the " "volume %s", path, quota_list, self.volname) # Validate IO ret = validate_io_procs(self.all_mounts_procs, self.mounts) self.io_validation_complete = True self.assertTrue(ret, "IO failed on some of the clients") # List all files and dirs created g.log.info("List all files and directories:") ret = list_all_files_and_dirs_mounts(self.mounts) self.assertTrue(ret, "Failed to list all files and dirs") g.log.info("Listing all files and directories is successful")
def test_quota_single_brick_volume(self): """ Verifying directory quota functionality on a single brick volume. * Create a volume with single brick (1x1) start and mount it * Enable quota on the volume * Set a limit of 1GB on this volume * Create some directories and files in the mount point * Execute a quota list command """ # Enable Quota g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the " "volume %s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Path to set quota limit path = "/" # Set Quota limit on the root of the volume g.log.info("Set Quota Limit on the path %s of the volume %s", path, self.volname) ret, _, _ = quota_limit_usage(self.mnode, self.volname, path=path, limit="1GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " "the volume %s", path, self.volname)) g.log.info("Successfully set the Quota limit on %s of the volume %s", path, self.volname) # Starting IO on the mounts all_mounts_procs = [] count = 1 for mount_obj in self.mounts: g.log.info("Starting IO on %s:%s", mount_obj.client_system, mount_obj.mountpoint) cmd = ("/usr/bin/env python %s create_deep_dirs_with_files " "--dirname-start-num %d " "--dir-depth 2 " "--dir-length 20 " "--max-num-of-dirs 5 " "--num-of-files 5 %s" % ( self.script_upload_path, count, mount_obj.mountpoint)) proc = g.run_async(mount_obj.client_system, cmd, user=mount_obj.user) all_mounts_procs.append(proc) count = count + 10 # Validate IO g.log.info("Validating IO's") ret = validate_io_procs(all_mounts_procs, self.mounts) self.assertTrue(ret, "IO failed on some of the clients") g.log.info("Successfully validated all io's") # Get Quota list on Volume g.log.info("Get Quota list for the volume %s", self.volname) quota_list1 = quota_fetch_list(self.mnode, self.volname) self.assertIsNotNone(quota_list1, ("Failed to get the quota list for " "the volume %s", self.volname)) self.assertIn(path, quota_list1.keys(), ("%s not part of the ""quota list %s even if " "it is set on the volume %s", path, quota_list1, self.volname)) g.log.info("Successfully listed quota list %s of the " "volume %s", quota_list1, self.volname) # List all files and dirs created g.log.info("List all files and directories:") ret = list_all_files_and_dirs_mounts(self.mounts) self.assertTrue(ret, "Failed to list all files and dirs") g.log.info("Listing all files and directories is successful")
def test_no_dir(self): """ * Enable quota on the volume * Set the quota on the non-existing directory * Create the directory as above and set limit * Validate the quota on the volume * Delete the directory * Validate the quota on volume * Recreate the directory * Validate the quota on volume * Check for volume status for all processes being online. """ # Enable Quota g.log.info("Enabling quota on the volume %s", self.volname) ret, _, _ = quota_enable(self.mnode, self.volname) self.assertEqual(ret, 0, ("Failed to enable quota on the volume %s", self.volname)) g.log.info("Successfully enabled quota on the volume %s", self.volname) # Non existent path to set quota limit path = "/foo" # Set Quota limit on /foo of the volume g.log.info("Set Quota Limit on the path %s of the volume %s", path, self.volname) ret, _, err = quota_limit_usage(self.mnode, self.volname, path=path, limit="1GB") self.assertIn("No such file or directory", err, "Quota limit set " "on path /foo which does not exist") mount_obj = self.mounts[0] mount_dir = mount_obj.mountpoint client = mount_obj.client_system # Create the directory on which limit was tried to be set ret = mkdir(client, "%s/foo" % (mount_dir)) self.assertTrue(ret, ("Failed to create dir under %s-%s", client, mount_dir)) g.log.info("Directory 'foo' created successfully") # Set Quota limit on /foo of the volume g.log.info("Set Quota Limit on the path %s of the volume %s", path, self.volname) ret, _, err = quota_limit_usage(self.mnode, self.volname, path=path, limit="1GB") self.assertEqual(ret, 0, ("Failed to set quota limit on path %s of " "the volume %s", path, self.volname)) g.log.info("Successfully set the Quota limit on %s of the volume %s", path, self.volname) # Validate quota list g.log.info("Get Quota list for foo and see if hardlimit is 1GB") ret = quota_validate(self.mnode, self.volname, path=path, hard_limit=1073741824) self.assertTrue(ret, "Quota validate Failed for dir foo") # Delete the directory ret = rmdir(client, "%s/foo" % (mount_dir), force=True) self.assertTrue(ret, ("Failed to delete dir /foo")) g.log.info("Successfully deleted /foo") # Validate quota list g.log.info("Get empty quota list") quota_list1 = quota_fetch_list(self.mnode, self.volname, path=None) self.assertIsNone(quota_list1, ("unexpected quota list entries found")) g.log.info("Successfully validated quota limit usage for the " "deleted directory foo") # Recreate the same deleted directory ret = mkdir(client, "%s/foo" % (mount_dir)) self.assertTrue(ret, ("Failed to create dir under %s-%s", client, mount_dir)) g.log.info("Directory 'foo' created successfully") # Validate quota list g.log.info("Get Quota list for foo and see if hardlimit is N/A") ret = quota_validate(self.mnode, self.volname, path=path, hard_limit='N/A') self.assertTrue(ret, "Quota validate Failed for dir foo") g.log.info("Successfully validated quota limit usage for the " "recreated directory foo") # Verify volume's all process are online g.log.info("Volume %s: Verifying that all process are online", self.volname) ret = verify_all_process_of_volume_are_online(self.mnode, self.volname) self.assertTrue(ret, ("Volume %s : All process are not online ", self.volname)) g.log.info("Volume %s: All process are online", self.volname)