19821f1d3SAlan Somers /*- 29821f1d3SAlan Somers * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 39821f1d3SAlan Somers * 49821f1d3SAlan Somers * Copyright (c) 2019 The FreeBSD Foundation 59821f1d3SAlan Somers * 69821f1d3SAlan Somers * This software was developed by BFF Storage Systems, LLC under sponsorship 79821f1d3SAlan Somers * from the FreeBSD Foundation. 89821f1d3SAlan Somers * 99821f1d3SAlan Somers * Redistribution and use in source and binary forms, with or without 109821f1d3SAlan Somers * modification, are permitted provided that the following conditions 119821f1d3SAlan Somers * are met: 129821f1d3SAlan Somers * 1. Redistributions of source code must retain the above copyright 139821f1d3SAlan Somers * notice, this list of conditions and the following disclaimer. 149821f1d3SAlan Somers * 2. Redistributions in binary form must reproduce the above copyright 159821f1d3SAlan Somers * notice, this list of conditions and the following disclaimer in the 169821f1d3SAlan Somers * documentation and/or other materials provided with the distribution. 179821f1d3SAlan Somers * 189821f1d3SAlan Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 199821f1d3SAlan Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 209821f1d3SAlan Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 219821f1d3SAlan Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 229821f1d3SAlan Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 239821f1d3SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 249821f1d3SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 259821f1d3SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 269821f1d3SAlan Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 279821f1d3SAlan Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 289821f1d3SAlan Somers * SUCH DAMAGE. 299821f1d3SAlan Somers */ 309821f1d3SAlan Somers 319821f1d3SAlan Somers extern "C" { 329821f1d3SAlan Somers #include <fcntl.h> 339821f1d3SAlan Somers } 349821f1d3SAlan Somers 359821f1d3SAlan Somers #include "mockfs.hh" 369821f1d3SAlan Somers #include "utils.hh" 379821f1d3SAlan Somers 389821f1d3SAlan Somers using namespace testing; 399821f1d3SAlan Somers 409821f1d3SAlan Somers class Rmdir: public FuseTest { 419821f1d3SAlan Somers public: 42*6124fd71SAlan Somers void expect_getattr(uint64_t ino, mode_t mode) 43*6124fd71SAlan Somers { 44*6124fd71SAlan Somers EXPECT_CALL(*m_mock, process( 45*6124fd71SAlan Somers ResultOf([=](auto in) { 46*6124fd71SAlan Somers return (in->header.opcode == FUSE_GETATTR && 47*6124fd71SAlan Somers in->header.nodeid == ino); 48*6124fd71SAlan Somers }, Eq(true)), 49*6124fd71SAlan Somers _) 50*6124fd71SAlan Somers ).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto out) { 51*6124fd71SAlan Somers SET_OUT_HEADER_LEN(out, attr); 52*6124fd71SAlan Somers out->body.attr.attr.ino = ino; // Must match nodeid 53*6124fd71SAlan Somers out->body.attr.attr.mode = mode; 54*6124fd71SAlan Somers out->body.attr.attr_valid = UINT64_MAX; 55*6124fd71SAlan Somers }))); 56*6124fd71SAlan Somers } 57*6124fd71SAlan Somers 589821f1d3SAlan Somers void expect_lookup(const char *relpath, uint64_t ino) 599821f1d3SAlan Somers { 609821f1d3SAlan Somers EXPECT_LOOKUP(1, relpath) 619821f1d3SAlan Somers .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { 629821f1d3SAlan Somers SET_OUT_HEADER_LEN(out, entry); 639821f1d3SAlan Somers out->body.entry.attr.mode = S_IFDIR | 0755; 649821f1d3SAlan Somers out->body.entry.nodeid = ino; 659821f1d3SAlan Somers out->body.entry.attr.nlink = 2; 669821f1d3SAlan Somers }))); 679821f1d3SAlan Somers } 689821f1d3SAlan Somers }; 699821f1d3SAlan Somers 709821f1d3SAlan Somers TEST_F(Rmdir, enotempty) 719821f1d3SAlan Somers { 729821f1d3SAlan Somers const char FULLPATH[] = "mountpoint/some_dir"; 739821f1d3SAlan Somers const char RELPATH[] = "some_dir"; 749821f1d3SAlan Somers uint64_t ino = 42; 759821f1d3SAlan Somers 76*6124fd71SAlan Somers expect_getattr(1, S_IFDIR | 0755); 779821f1d3SAlan Somers expect_lookup(RELPATH, ino); 789821f1d3SAlan Somers EXPECT_CALL(*m_mock, process( 799821f1d3SAlan Somers ResultOf([=](auto in) { 809821f1d3SAlan Somers return (in->header.opcode == FUSE_RMDIR && 819821f1d3SAlan Somers 0 == strcmp(RELPATH, in->body.rmdir) && 829821f1d3SAlan Somers in->header.nodeid == 1); 839821f1d3SAlan Somers }, Eq(true)), 849821f1d3SAlan Somers _) 859821f1d3SAlan Somers ).WillOnce(Invoke(ReturnErrno(ENOTEMPTY))); 869821f1d3SAlan Somers 879821f1d3SAlan Somers ASSERT_NE(0, rmdir(FULLPATH)); 889821f1d3SAlan Somers ASSERT_EQ(ENOTEMPTY, errno); 899821f1d3SAlan Somers } 909821f1d3SAlan Somers 919821f1d3SAlan Somers TEST_F(Rmdir, ok) 929821f1d3SAlan Somers { 939821f1d3SAlan Somers const char FULLPATH[] = "mountpoint/some_dir"; 949821f1d3SAlan Somers const char RELPATH[] = "some_dir"; 959821f1d3SAlan Somers uint64_t ino = 42; 969821f1d3SAlan Somers 97*6124fd71SAlan Somers expect_getattr(1, S_IFDIR | 0755); 989821f1d3SAlan Somers expect_lookup(RELPATH, ino); 999821f1d3SAlan Somers EXPECT_CALL(*m_mock, process( 1009821f1d3SAlan Somers ResultOf([=](auto in) { 1019821f1d3SAlan Somers return (in->header.opcode == FUSE_RMDIR && 1029821f1d3SAlan Somers 0 == strcmp(RELPATH, in->body.rmdir) && 1039821f1d3SAlan Somers in->header.nodeid == 1); 1049821f1d3SAlan Somers }, Eq(true)), 1059821f1d3SAlan Somers _) 1069821f1d3SAlan Somers ).WillOnce(Invoke(ReturnErrno(0))); 1079821f1d3SAlan Somers 1089821f1d3SAlan Somers ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); 1099821f1d3SAlan Somers } 110