xref: /freebsd/tests/sys/fs/fusefs/rmdir.cc (revision 6124fd7106b5933a50a4539b3d898cc00516e9a9)
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