def access_file(self, wekafs_alternate_path):
            def _access(path, filename, flag):
                return os.access(path + '/' + filename, flag)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            flag = choose([os.R_OK, os.W_OK, os.X_OK])
            self.validate_same_behavior_on_both_paths(_access,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      flag=flag)
        def remove_dir(self, wekafs_alternate_path):
            def _rmdir(path, dirname):
                os.rmdir(path + '/' + dirname)
                return dirname

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            del_dir = self.validate_same_behavior_on_both_paths(
                _rmdir, wekafs_alternate_path, dirname=filename)
            if del_dir:
                self.dir_contents.pop(del_dir)
        def remove_file(self, wekafs_alternate_path):
            def _rm(path, filename):
                os.remove(path + '/' + filename)
                return filename

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            del_file = self.validate_same_behavior_on_both_paths(
                _rm, wekafs_alternate_path, filename=filename)
            if del_file:
                self.dir_contents.pop(del_file)
        def chmod_file(self, wekafs_alternate_path):
            def _chmod(path, filename, value):
                os.chmod(path + '/' + filename, value)
                return (filename, value)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            value = randint(0, 0o777)
            self.validate_same_behavior_on_both_paths(_chmod,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      value=value)
        def create_file(self, wekafs_alternate_path):
            def _mknod(path, filename):
                os.mknod(path + '/' + filename)
                return filename

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            new_file = self.validate_same_behavior_on_both_paths(
                _mknod, wekafs_alternate_path, filename=filename)
            if new_file:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + new_file).st_ino
                self.dir_contents[new_file] = wekafs_inode
        def create_link(self, wekafs_alternate_path):
            def _link(path, filename, linkname):
                os.link(path + '/' + filename, path + '/' + linkname)
                return linkname

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            new_link = self.validate_same_behavior_on_both_paths(
                _link,
                wekafs_alternate_path,
                filename=filename,
                linkname=random_filename())
            if new_link:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + new_link).st_ino
                self.dir_contents[new_link] = wekafs_inode
        def open_read_write_close(self, wekafs_alternate_path):
            def _open(path, filename, buf):
                @contextmanager
                def opened_file(filename):
                    fd = os.open(filename, flags=os.O_RDWR)
                    yield fd
                    os.close(fd)

                with opened_file(filename) as fd:
                    os.read(fd, 100)
                    os.write(fd, buf)
                return (filename, buf)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            buf = random_buf(100)
            self.validate_same_behavior_on_both_paths(_open,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      buf=buf)
        def stat_file(self, wekafs_alternate_path):
            def _stat(path, filename):
                stats = os.stat(path + '/' + filename)
                mode = stats.st_mode
                # atime, mtime and ctime might differ by a few nanoseconds
                # inode and device will be different between the 2 filesystems
                # directory's nlink is different between wekafs and posix (see WEKAPP-76966)
                # directory's size is unspecified
                # this only leaves the 'mode' stat
                return mode

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            ret = self.validate_same_behavior_on_both_paths(
                _stat, wekafs_alternate_path, filename=filename)
            if ret:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + filename).st_ino
                assert wekafs_inode == self.dir_contents[filename]
    def choose_action(self):
        possible_actions = []

        def list_dir(self, wekafs_alternate_path):
            wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
            wekafs_res = os.listdir(self.localfs_path)
            logger.debug('listdir according to wekafs: %s' % wekafs_res)
            localfs_res = os.listdir(wekafs_path)
            logger.debug('listdir according to localfs: %s' % localfs_res)
            assert set(wekafs_res) == set(
                localfs_res
            ), 'Inconsistency between wekafs and localfs. see debug logs for info'
            return wekafs_res

        possible_actions.append(list_dir)

        def create_file(self, wekafs_alternate_path):
            def _mknod(path, filename):
                os.mknod(path + '/' + filename)
                return filename

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            new_file = self.validate_same_behavior_on_both_paths(
                _mknod, wekafs_alternate_path, filename=filename)
            if new_file:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + new_file).st_ino
                self.dir_contents[new_file] = wekafs_inode

        possible_actions.append(create_file)

        def remove_file(self, wekafs_alternate_path):
            def _rm(path, filename):
                os.remove(path + '/' + filename)
                return filename

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            del_file = self.validate_same_behavior_on_both_paths(
                _rm, wekafs_alternate_path, filename=filename)
            if del_file:
                self.dir_contents.pop(del_file)

        possible_actions.append(remove_file)

        def create_dir(self, wekafs_alternate_path):
            def _mkdir(path, dirname):
                os.mkdir(path + '/' + dirname)
                return dirname

            dirname = choose([k for (k, v) in self.dir_contents.items()] +
                             [random_filename()])
            new_dir = self.validate_same_behavior_on_both_paths(
                _mkdir, wekafs_alternate_path, dirname=dirname)
            if new_dir:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + new_dir).st_ino
                self.dir_contents[new_dir] = wekafs_inode

        possible_actions.append(create_dir)

        def remove_dir(self, wekafs_alternate_path):
            def _rmdir(path, dirname):
                os.rmdir(path + '/' + dirname)
                return dirname

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            del_dir = self.validate_same_behavior_on_both_paths(
                _rmdir, wekafs_alternate_path, dirname=filename)
            if del_dir:
                self.dir_contents.pop(del_dir)

        possible_actions.append(remove_dir)

        def create_link(self, wekafs_alternate_path):
            def _link(path, filename, linkname):
                os.link(path + '/' + filename, path + '/' + linkname)
                return linkname

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            new_link = self.validate_same_behavior_on_both_paths(
                _link,
                wekafs_alternate_path,
                filename=filename,
                linkname=random_filename())
            if new_link:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + new_link).st_ino
                self.dir_contents[new_link] = wekafs_inode

        possible_actions.append(create_link)

        def stat_file(self, wekafs_alternate_path):
            def _stat(path, filename):
                stats = os.stat(path + '/' + filename)
                mode = stats.st_mode
                # atime, mtime and ctime might differ by a few nanoseconds
                # inode and device will be different between the 2 filesystems
                # directory's nlink is different between wekafs and posix (see WEKAPP-76966)
                # directory's size is unspecified
                # this only leaves the 'mode' stat
                return mode

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            ret = self.validate_same_behavior_on_both_paths(
                _stat, wekafs_alternate_path, filename=filename)
            if ret:
                # this means there was no exception
                wekafs_path = self.wekafs_alternate_path if wekafs_alternate_path else self.wekafs_path
                wekafs_inode = os.stat(wekafs_path + '/' + filename).st_ino
                assert wekafs_inode == self.dir_contents[filename]

        possible_actions.append(stat_file)

        def access_file(self, wekafs_alternate_path):
            def _access(path, filename, flag):
                return os.access(path + '/' + filename, flag)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            flag = choose([os.R_OK, os.W_OK, os.X_OK])
            self.validate_same_behavior_on_both_paths(_access,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      flag=flag)

        possible_actions.append(access_file)

        def chmod_file(self, wekafs_alternate_path):
            def _chmod(path, filename, value):
                os.chmod(path + '/' + filename, value)
                return (filename, value)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            value = randint(0, 0o777)
            self.validate_same_behavior_on_both_paths(_chmod,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      value=value)

        possible_actions.append(chmod_file)

        def open_read_write_close(self, wekafs_alternate_path):
            def _open(path, filename, buf):
                @contextmanager
                def opened_file(filename):
                    fd = os.open(filename, flags=os.O_RDWR)
                    yield fd
                    os.close(fd)

                with opened_file(filename) as fd:
                    os.read(fd, 100)
                    os.write(fd, buf)
                return (filename, buf)

            filename = choose([k for (k, v) in self.dir_contents.items()] +
                              [random_filename()])
            buf = random_buf(100)
            self.validate_same_behavior_on_both_paths(_open,
                                                      wekafs_alternate_path,
                                                      filename=filename,
                                                      buf=buf)

        possible_actions.append(open_read_write_close)

        chosen_action = choose(possible_actions)
        return chosen_action