From dafb5ac9173fb0a679a65dd748b862cc88385d2a Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 5 Jul 2020 21:19:00 +0200 Subject: [PATCH] fixed matcher; added tests to read large files --- test/webfuse/fs_check/main.c | 26 ++++++++ test/webfuse/mocks/getattr_matcher.hpp | 1 + test/webfuse/mocks/open_matcher.hpp | 1 + test/webfuse/mocks/readdir_matcher.hpp | 1 + test/webfuse/test_client.cc | 84 ++++++++++++++++++++++++-- test/webfuse/test_server.cc | 62 ++++++++++++++++++- test/webfuse/test_util/file.cc | 8 +++ test/webfuse/test_util/file.hpp | 1 + 8 files changed, 179 insertions(+), 5 deletions(-) diff --git a/test/webfuse/fs_check/main.c b/test/webfuse/fs_check/main.c index 55d24c4..f8e9555 100644 --- a/test/webfuse/fs_check/main.c +++ b/test/webfuse/fs_check/main.c @@ -70,6 +70,7 @@ static bool print_usage( "\thas_size - checks, if has the size given in \n" "\thas_subdir - checks, if contains the sub directory given in \n" "\thas_contents - checks, if has the contents given in \n" + "\tread_all - checks, if alls contents of can be read\n" ); return command->success; @@ -159,6 +160,30 @@ static bool has_contents( return result; } + +static bool read_all( + struct command * command) +{ + bool result = false; + + struct stat info; + int rc = stat(command->file, &info); + if (0 != rc) { return false; } + size_t length = info.st_size; + + char * buffer = malloc(length); + FILE * file = fopen(command->file, "rb"); + { + ssize_t count = fread(buffer, 1, length, file); + fclose(file); + + result = (count == (ssize_t) length); + } + + free(buffer); + return result; +} + static bool get_command( struct command * command, char const * name) @@ -175,6 +200,7 @@ static bool get_command( {"has_size" , &has_size , true}, {"has_subdir" , &has_subdir , true}, {"has_contents", &has_contents, true}, + {"read_all" , &read_all , false}, {NULL, NULL, false} }; diff --git a/test/webfuse/mocks/getattr_matcher.hpp b/test/webfuse/mocks/getattr_matcher.hpp index 71094c7..c1f6cbb 100644 --- a/test/webfuse/mocks/getattr_matcher.hpp +++ b/test/webfuse/mocks/getattr_matcher.hpp @@ -26,6 +26,7 @@ MATCHER_P(GetAttr, inode, "") { *result_listener << "inode mismatch: expected" << inode << " but was " << json_integer_value(inode_); + return false; } return true; diff --git a/test/webfuse/mocks/open_matcher.hpp b/test/webfuse/mocks/open_matcher.hpp index 462792e..1bc7bf4 100644 --- a/test/webfuse/mocks/open_matcher.hpp +++ b/test/webfuse/mocks/open_matcher.hpp @@ -26,6 +26,7 @@ MATCHER_P(Open, inode, "") { *result_listener << "inode mismatch: expected" << inode << " but was " << json_integer_value(inode_); + return false; } return true; diff --git a/test/webfuse/mocks/readdir_matcher.hpp b/test/webfuse/mocks/readdir_matcher.hpp index ad2c2ab..6c8134f 100644 --- a/test/webfuse/mocks/readdir_matcher.hpp +++ b/test/webfuse/mocks/readdir_matcher.hpp @@ -26,6 +26,7 @@ MATCHER_P(ReadDir, inode, "") { *result_listener << "inode mismatch: expected" << inode << " but was " << json_integer_value(inode_); + return false; } return true; diff --git a/test/webfuse/test_client.cc b/test/webfuse/test_client.cc index fe559e8..15d92b7 100644 --- a/test/webfuse/test_client.cc +++ b/test/webfuse/test_client.cc @@ -549,7 +549,7 @@ TEST(AdapterClient, LookupFile) ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); } -TEST(AdapterClient, ReadLargeFile) +TEST(AdapterClient, ReadFile) { MockInvokationHander handler; WsServer server(handler, WF_PROTOCOL_NAME_PROVIDER_SERVER); @@ -558,9 +558,11 @@ TEST(AdapterClient, ReadLargeFile) EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber()) .WillRepeatedly(Throw(std::runtime_error("unknown"))); EXPECT_CALL(handler, Invoke(StrEq("lookup"), Lookup(1, "a.file"))).Times(1) - .WillOnce(Return("{\"inode\": 2, \"mode\": 420, \"type\": \"file\", \"size\": 4096}")); + .WillOnce(Return("{\"inode\": 2, \"mode\": 420, \"type\": \"file\", \"size\": 8192}")); EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber()) .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"dir\"}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(2))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"file\", \"size\": 8192}")); EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1) .WillOnce(Return("{\"handle\": 42}")); EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber()) @@ -568,7 +570,7 @@ TEST(AdapterClient, ReadLargeFile) int offset = json_integer_value(json_array_get(params, 3)); int length = json_integer_value(json_array_get(params, 4)); - int remaining = (offset < 4096) ? 4096 - offset : 0; + int remaining = (offset < 8192) ? 8192 - offset : 0; int count = (length < remaining) ? length : remaining; std::string data = std::string(count, '*'); @@ -615,9 +617,83 @@ TEST(AdapterClient, ReadLargeFile) std::string base_dir = client.GetDir(); ASSERT_TRUE(File(base_dir).isDirectory()); File file(base_dir + "/a.file"); - std::string contents(4096, '*'); + std::string contents(8192, '*'); ASSERT_TRUE(file.hasContents(contents)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); } + +TEST(AdapterClient, ReadLargeFile) +{ + MockInvokationHander handler; + WsServer server(handler, WF_PROTOCOL_NAME_PROVIDER_SERVER); + EXPECT_CALL(handler, Invoke(StrEq("add_filesystem"),_)).Times(1) + .WillOnce(Return("{\"id\": \"test\"}")); + EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber()) + .WillRepeatedly(Throw(std::runtime_error("unknown"))); + EXPECT_CALL(handler, Invoke(StrEq("lookup"), Lookup(1, "a.file"))).Times(1) + .WillOnce(Return("{\"inode\": 2, \"mode\": 420, \"type\": \"file\", \"size\": 102400}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"dir\"}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(2))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"file\", \"size\": 102400}")); + EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1) + .WillOnce(Return("{\"handle\": 42}")); + EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber()) + .WillRepeatedly(Invoke([](char const *, json_t * params) { + int offset = json_integer_value(json_array_get(params, 3)); + int length = json_integer_value(json_array_get(params, 4)); + + int remaining = (offset < 102400) ? 102400 - offset : 0; + int count = (length < remaining) ? length : remaining; + + std::string data = std::string(count, '*'); + + json_t * result = json_object(); + json_object_set_new(result, "data", json_string(data.c_str())); + json_object_set_new(result, "format", json_string("identity")); + json_object_set_new(result, "count", json_integer(count)); + + char * result_text = json_dumps(result, 0); + std::string result_str = result_text; + free(result_text); + json_decref(result); + + return result_str; + })); + EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1)); + + MockAdapterClientCallback callback; + EXPECT_CALL(callback, Invoke(_, _, _)).Times(AnyNumber()); + + std::promise connected; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { connected.set_value(); })); + + std::promise disconnected; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { disconnected.set_value(); })); + + std::promise called; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_FILESYSTEM_ADDED, nullptr)).Times(1) + .WillOnce(Invoke([&called] (wf_client *, int, void *) mutable { + called.set_value(); + })); + + AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl()); + + client.Connect(); + ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); + + client.AddFileSystem(); + ASSERT_EQ(std::future_status::ready, called.get_future().wait_for(TIMEOUT)); + + std::string base_dir = client.GetDir(); + ASSERT_TRUE(File(base_dir).isDirectory()); + File file(base_dir + "/a.file"); + ASSERT_TRUE(file.readAll()); + + client.Disconnect(); + ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); +} \ No newline at end of file diff --git a/test/webfuse/test_server.cc b/test/webfuse/test_server.cc index 500b380..85aba28 100644 --- a/test/webfuse/test_server.cc +++ b/test/webfuse/test_server.cc @@ -316,7 +316,7 @@ TEST(server, read) ASSERT_TRUE(disconnected); } -TEST(server, read_large_file) +TEST(server, read_large_file_contents) { Server server; MockInvokationHander handler; @@ -325,6 +325,8 @@ TEST(server, read_large_file) .WillOnce(Return("{\"inode\": 2, \"mode\": 420, \"type\": \"file\", \"size\": 4096}")); EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber()) .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"dir\"}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(2))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"file\", \"size\": 4096}")); EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1) .WillOnce(Return("{\"handle\": 42}")); EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber()) @@ -374,6 +376,64 @@ TEST(server, read_large_file) ASSERT_TRUE(disconnected); } +TEST(server, read_large_file) +{ + Server server; + MockInvokationHander handler; + EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber()); + EXPECT_CALL(handler, Invoke(StrEq("lookup"), Lookup(1, "a.file"))).Times(1) + .WillOnce(Return("{\"inode\": 2, \"mode\": 420, \"type\": \"file\", \"size\": 1024000}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"dir\"}")); + EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(2))).Times(AnyNumber()) + .WillRepeatedly(Return("{\"mode\": 420, \"type\": \"file\", \"size\": 1024000}")); + EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1) + .WillOnce(Return("{\"handle\": 42}")); + EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber()) + .WillRepeatedly(Invoke([](char const *, json_t * params) { + int offset = json_integer_value(json_array_get(params, 3)); + int length = json_integer_value(json_array_get(params, 4)); + + int remaining = (offset < 1024000) ? 1024000 - offset : 0; + int count = (length < remaining) ? length : remaining; + + std::string data = std::string(count, '*'); + + json_t * result = json_object(); + json_object_set_new(result, "data", json_string(data.c_str())); + json_object_set_new(result, "format", json_string("identity")); + json_object_set_new(result, "count", json_integer(count)); + + char * result_text = json_dumps(result, 0); + std::string result_str = result_text; + free(result_text); + json_decref(result); + + return result_str; + })); + EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1)); + WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT); + + auto connected = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER); + ASSERT_TRUE(connected); + + std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}"); + json_t * response = json_loads(response_text.c_str(), 0, nullptr); + ASSERT_TRUE(json_is_object(response)); + json_t * result = json_object_get(response, "result"); + ASSERT_TRUE(json_is_object(result)); + json_t * id = json_object_get(response, "id"); + ASSERT_EQ(42, json_integer_value(id)); + json_decref(response); + + std::string base_dir = server.GetBaseDir(); + ASSERT_TRUE(File(base_dir).isDirectory()); + File file(base_dir + "/test/a.file"); + ASSERT_TRUE(file.readAll()); + + auto disconnected = client.Disconnect(); + ASSERT_TRUE(disconnected); +} TEST(server, readdir) { diff --git a/test/webfuse/test_util/file.cc b/test/webfuse/test_util/file.cc index 1ec16b5..c186e27 100644 --- a/test/webfuse/test_util/file.cc +++ b/test/webfuse/test_util/file.cc @@ -82,4 +82,12 @@ bool File::hasContents(std::string const & contents) return invoke(command.str()); } +bool File::readAll() +{ + std::stringstream command; + command << "./fs_check -c read_all -f " << path_; + + return invoke(command.str()); +} + } \ No newline at end of file diff --git a/test/webfuse/test_util/file.hpp b/test/webfuse/test_util/file.hpp index e36e6ce..b5ec95f 100644 --- a/test/webfuse/test_util/file.hpp +++ b/test/webfuse/test_util/file.hpp @@ -17,6 +17,7 @@ public: bool hasSize(size_t size); bool hasSubdirectory(std::string const & subdir); bool hasContents(std::string const & contents); + bool readAll(); private: std::string path_; };