mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add function generating array of iovec with different FUSE structs
This commit adds a function in the newly created fuse_util library, which accepts a variable number of arguments and data structures. Fixes #3609
This commit is contained in:
@@ -12,6 +12,7 @@ cc_binary(
|
||||
deps = [
|
||||
gtest,
|
||||
":fuse_base",
|
||||
"//test/util:fuse_util",
|
||||
"//test/util:test_main",
|
||||
"//test/util:test_util",
|
||||
],
|
||||
@@ -24,6 +25,7 @@ cc_library(
|
||||
hdrs = ["fuse_base.h"],
|
||||
deps = [
|
||||
gtest,
|
||||
"//test/util:fuse_util",
|
||||
"//test/util:posix_error",
|
||||
"//test/util:temp_path",
|
||||
"//test/util:test_util",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/util/fuse_util.h"
|
||||
#include "test/util/posix_error.h"
|
||||
#include "test/util/temp_path.h"
|
||||
#include "test/util/test_util.h"
|
||||
@@ -137,7 +138,6 @@ PosixError FuseTest::ServerConsumeFuseInit() {
|
||||
RETURN_ERROR_IF_SYSCALL_FAIL(
|
||||
RetryEINTR(read)(dev_fd_, buf.data(), buf.size()));
|
||||
|
||||
struct iovec iov_out[2];
|
||||
struct fuse_out_header out_header = {
|
||||
.len = sizeof(struct fuse_out_header) + sizeof(struct fuse_init_out),
|
||||
.error = 0,
|
||||
@@ -148,12 +148,10 @@ PosixError FuseTest::ServerConsumeFuseInit() {
|
||||
struct fuse_init_out out_payload = {
|
||||
.major = 7,
|
||||
};
|
||||
iov_out[0].iov_len = sizeof(out_header);
|
||||
iov_out[0].iov_base = &out_header;
|
||||
iov_out[1].iov_len = sizeof(out_payload);
|
||||
iov_out[1].iov_base = &out_payload;
|
||||
auto iov_out = FuseGenerateIovecs(out_header, out_payload);
|
||||
|
||||
RETURN_ERROR_IF_SYSCALL_FAIL(RetryEINTR(writev)(dev_fd_, iov_out, 2));
|
||||
RETURN_ERROR_IF_SYSCALL_FAIL(
|
||||
RetryEINTR(writev)(dev_fd_, iov_out.data(), iov_out.size()));
|
||||
return NoError();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/fuse/linux/fuse_base.h"
|
||||
#include "test/util/fuse_util.h"
|
||||
#include "test/util/test_util.h"
|
||||
|
||||
namespace gvisor {
|
||||
@@ -43,16 +44,10 @@ class StatTest : public FuseTest {
|
||||
|
||||
TEST_F(StatTest, StatNormal) {
|
||||
// Set up fixture.
|
||||
std::vector<struct iovec> iov_in(2);
|
||||
std::vector<struct iovec> iov_out(2);
|
||||
mode_t expected_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
struct timespec atime = {.tv_sec = 1595436289, .tv_nsec = 134150844};
|
||||
struct timespec mtime = {.tv_sec = 1595436290, .tv_nsec = 134150845};
|
||||
struct timespec ctime = {.tv_sec = 1595436291, .tv_nsec = 134150846};
|
||||
struct fuse_out_header out_header = {
|
||||
.len = sizeof(struct fuse_out_header) + sizeof(struct fuse_attr_out),
|
||||
.error = 0,
|
||||
};
|
||||
struct fuse_attr attr = {
|
||||
.ino = 1,
|
||||
.size = 512,
|
||||
@@ -70,14 +65,13 @@ TEST_F(StatTest, StatNormal) {
|
||||
.rdev = 12,
|
||||
.blksize = 4096,
|
||||
};
|
||||
struct fuse_out_header out_header = {
|
||||
.len = sizeof(struct fuse_out_header) + sizeof(struct fuse_attr_out),
|
||||
};
|
||||
struct fuse_attr_out out_payload = {
|
||||
.attr = attr,
|
||||
};
|
||||
iov_out[0].iov_len = sizeof(out_header);
|
||||
iov_out[0].iov_base = &out_header;
|
||||
iov_out[1].iov_len = sizeof(out_payload);
|
||||
iov_out[1].iov_base = &out_payload;
|
||||
|
||||
auto iov_out = FuseGenerateIovecs(out_header, out_payload);
|
||||
SetServerResponse(FUSE_GETATTR, iov_out);
|
||||
|
||||
// Do integration test.
|
||||
@@ -104,10 +98,7 @@ TEST_F(StatTest, StatNormal) {
|
||||
// Check FUSE request.
|
||||
struct fuse_in_header in_header;
|
||||
struct fuse_getattr_in in_payload;
|
||||
iov_in[0].iov_len = sizeof(in_header);
|
||||
iov_in[0].iov_base = &in_header;
|
||||
iov_in[1].iov_len = sizeof(in_payload);
|
||||
iov_in[1].iov_base = &in_payload;
|
||||
auto iov_in = FuseGenerateIovecs(in_header, in_payload);
|
||||
|
||||
GetServerActualRequest(iov_in);
|
||||
EXPECT_EQ(in_header.opcode, FUSE_GETATTR);
|
||||
@@ -117,14 +108,11 @@ TEST_F(StatTest, StatNormal) {
|
||||
|
||||
TEST_F(StatTest, StatNotFound) {
|
||||
// Set up fixture.
|
||||
std::vector<struct iovec> iov_in(2);
|
||||
std::vector<struct iovec> iov_out(1);
|
||||
struct fuse_out_header out_header = {
|
||||
.len = sizeof(struct fuse_out_header),
|
||||
.error = -ENOENT,
|
||||
};
|
||||
iov_out[0].iov_len = sizeof(out_header);
|
||||
iov_out[0].iov_base = &out_header;
|
||||
auto iov_out = FuseGenerateIovecs(out_header);
|
||||
SetServerResponse(FUSE_GETATTR, iov_out);
|
||||
|
||||
// Do integration test.
|
||||
@@ -135,10 +123,7 @@ TEST_F(StatTest, StatNotFound) {
|
||||
// Check FUSE request.
|
||||
struct fuse_in_header in_header;
|
||||
struct fuse_getattr_in in_payload;
|
||||
iov_in[0].iov_len = sizeof(in_header);
|
||||
iov_in[0].iov_base = &in_header;
|
||||
iov_in[1].iov_len = sizeof(in_payload);
|
||||
iov_in[1].iov_base = &in_payload;
|
||||
auto iov_in = FuseGenerateIovecs(in_header, in_payload);
|
||||
|
||||
GetServerActualRequest(iov_in);
|
||||
EXPECT_EQ(in_header.opcode, FUSE_GETATTR);
|
||||
|
||||
@@ -45,6 +45,12 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fuse_util",
|
||||
testonly = 1,
|
||||
hdrs = ["fuse_util.h"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "proc_util",
|
||||
testonly = 1,
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GVISOR_TEST_UTIL_FUSE_UTIL_H_
|
||||
#define GVISOR_TEST_UTIL_FUSE_UTIL_H_
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gvisor {
|
||||
namespace testing {
|
||||
|
||||
// The fundamental generation function with a single argument. If passed by
|
||||
// std::string or std::vector<char>, it will call specialized versions as
|
||||
// implemented below.
|
||||
template <typename T>
|
||||
std::vector<struct iovec> FuseGenerateIovecs(T &first) {
|
||||
return {(struct iovec){.iov_base = &first, .iov_len = sizeof(first)}};
|
||||
}
|
||||
|
||||
// If an argument is of type std::string, it must be used in read-only scenario.
|
||||
// Because we are setting up iovec, which contains the original address of a
|
||||
// data structure, we have to drop const qualification. Usually used with
|
||||
// variable-length payload data.
|
||||
template <typename T = std::string>
|
||||
std::vector<struct iovec> FuseGenerateIovecs(std::string &first) {
|
||||
// Pad one byte for null-terminate c-string.
|
||||
return {(struct iovec){.iov_base = const_cast<char *>(first.c_str()),
|
||||
.iov_len = first.size() + 1}};
|
||||
}
|
||||
|
||||
// If an argument is of type std::vector<char>, it must be used in write-only
|
||||
// scenario and the size of the variable must be greater than or equal to the
|
||||
// size of the expected data. Usually used with variable-length payload data.
|
||||
template <typename T = std::vector<char>>
|
||||
std::vector<struct iovec> FuseGenerateIovecs(std::vector<char> &first) {
|
||||
return {(struct iovec){.iov_base = first.data(), .iov_len = first.size()}};
|
||||
}
|
||||
|
||||
// A helper function to set up an array of iovec struct for testing purpose.
|
||||
// Use variadic class template to generalize different numbers and different
|
||||
// types of FUSE structs.
|
||||
template <typename T, typename... Types>
|
||||
std::vector<struct iovec> FuseGenerateIovecs(T &first, Types &...args) {
|
||||
auto first_iovec = FuseGenerateIovecs(first);
|
||||
auto iovecs = FuseGenerateIovecs(args...);
|
||||
first_iovec.insert(std::end(first_iovec), std::begin(iovecs),
|
||||
std::end(iovecs));
|
||||
return first_iovec;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace gvisor
|
||||
#endif // GVISOR_TEST_UTIL_FUSE_UTIL_H_
|
||||
Reference in New Issue
Block a user