8 #include <gtest/gtest.h>
9 #include <boost/filesystem/fstream.hpp>
10 #include <boost/filesystem.hpp>
14 #include <qi/path.hpp>
15 #include <qi/application.hpp>
16 #include <qi/type/dynamicobjectbuilder.hpp>
17 #include <testsession/testsessionpair.hpp>
18 #include <testsession/testsession.hpp>
28 : PATH(
qi::os::mktmpdir(
"qiCoreTestFile"))
33 boost::system::error_code err;
34 const auto path = boost::filesystem::system_complete(PATH);
35 boost::filesystem::remove_all(
path, err);
38 qiLogError() <<
"Failed to remove temporary directory '" << PATH <<
"' : " << err.message();
41 }
const TEMPORARY_DIR;
43 const qi::Path SMALL_TEST_FILE_PATH{TEMPORARY_DIR.PATH /
"\xED\x95\x9C/testfile.data"};
44 qi::Path BIG_TEST_FILE_PATH;
46 const std::string TESTFILE_CONTENT =
"abcdefghijklmnopqrstuvwxyz";
47 const std::streamoff TESTFILE_PARTIAL_BEGIN_POSITION = 23;
48 const std::streamoff TESTFILE_PARTIAL_SIZE = 3;
50 const std::streamoff TESTFILE_MIDDLE_BEGIN_POSITION = TESTFILE_CONTENT.size() / 3;
51 const std::streamoff TESTFILE_MIDDLE_SIZE = TESTFILE_CONTENT.size() / 3;
53 void makeSmallTestFile()
55 boost::filesystem::remove(SMALL_TEST_FILE_PATH);
56 boost::filesystem::create_directories(SMALL_TEST_FILE_PATH.parent());
57 boost::filesystem::ofstream fileOutput(SMALL_TEST_FILE_PATH, std::ios::out | std::ios::binary);
58 assert(fileOutput.is_open());
59 fileOutput << TESTFILE_CONTENT;
63 void checkIsTestFileContent(
const qi::Buffer& buffer, std::streamoff beginOffset, std::streamsize bytesCount)
65 EXPECT_EQ(
static_cast<std::streamsize
>(buffer.size()), bytesCount);
66 for (
size_t idx = 0; idx < buffer.totalSize(); ++idx)
68 EXPECT_EQ(
static_cast<const char*
>(buffer.data())[idx], TESTFILE_CONTENT[beginOffset + idx]);
72 void checkIsTestFileMiddleContent(
const qi::Buffer& buffer)
74 return checkIsTestFileContent(buffer, TESTFILE_MIDDLE_BEGIN_POSITION, TESTFILE_MIDDLE_SIZE);
77 void checkIsTestFilePartialContent(
const qi::Buffer& buffer)
79 return checkIsTestFileContent(buffer, TESTFILE_PARTIAL_BEGIN_POSITION, TESTFILE_PARTIAL_SIZE);
82 void checkIsTestFileContent(
const qi::Buffer& buffer)
84 for (
size_t idx = 0; idx < buffer.totalSize(); ++idx)
86 EXPECT_EQ(
static_cast<const char*
>(buffer.data())[idx], TESTFILE_CONTENT[idx]);
90 void checkIsTestFileContent(
qi::File& file)
92 ASSERT_TRUE(file.
isOpen());
93 EXPECT_EQ(
static_cast<std::streamsize
>(TESTFILE_CONTENT.size()), file.
size());
95 const qi::Buffer allFileData = file.
read(file.
size());
96 EXPECT_EQ(TESTFILE_CONTENT.size(), allFileData.totalSize());
97 checkIsTestFileContent(allFileData);
103 ASSERT_TRUE(leftFile.
isOpen());
104 ASSERT_TRUE(rightFile.
isOpen());
105 ASSERT_EQ(leftFile.
size(), rightFile.
size());
106 static const std::streamsize BYTES_STEP = 1024 * 64;
108 for (std::streamoff byteOffset = 0;
109 byteOffset < static_cast<std::streamoff>(rightFile.
size());
110 byteOffset += BYTES_STEP)
112 qi::Buffer leftBytes = leftFile.
read(byteOffset, BYTES_STEP);
113 qi::Buffer rightBytes = rightFile.
read(byteOffset, BYTES_STEP);
114 EXPECT_GE(BYTES_STEP,
static_cast<std::streamsize
>(leftBytes.totalSize()));
115 EXPECT_GE(BYTES_STEP,
static_cast<std::streamsize
>(rightBytes.totalSize()));
116 EXPECT_EQ(leftBytes.totalSize(), rightBytes.totalSize());
118 ASSERT_TRUE(std::equal(
static_cast<char*
>(leftBytes.data()),
119 static_cast<char*
>(leftBytes.data()) + leftBytes.totalSize(),
120 static_cast<char*
>(rightBytes.data())));
125 TEST(TestFile, cannotReadUnknownFile)
134 TEST(TestFile, cannotReadClosedFile)
137 EXPECT_TRUE(file->isOpen());
140 EXPECT_FALSE(file->isOpen());
141 EXPECT_EQ(0, file->size());
157 EXPECT_TRUE(testFile->isOpen());
158 EXPECT_EQ(std::streamsize(TESTFILE_CONTENT.size()), testFile->size());
160 static const size_t COUNT_BYTES_TO_READ = 20;
162 qi::Buffer buffer = testFile->read(COUNT_BYTES_TO_READ);
163 ASSERT_EQ(COUNT_BYTES_TO_READ, buffer.totalSize());
164 checkIsTestFileContent(buffer);
167 TEST(TestFile, cannotReadPastEnd)
170 EXPECT_TRUE(testFile->isOpen());
171 EXPECT_EQ(std::streamsize(TESTFILE_CONTENT.size()), testFile->size());
173 testFile->read(testFile->size());
174 qi::Buffer buffer = testFile->read(1);
175 EXPECT_EQ(0u, buffer.totalSize());
181 EXPECT_TRUE(testFile->isOpen());
182 EXPECT_EQ(std::streamsize(TESTFILE_CONTENT.size()), testFile->size());
184 static const qi::Path LOCAL_COPY_PATH(
"if_this_is_not_removed_test_file_failed.txt");
185 boost::filesystem::remove(LOCAL_COPY_PATH);
190 EXPECT_TRUE(copiedFile->isOpen());
191 checkSameFilesContent(*testFile, *copiedFile);
193 boost::filesystem::remove(LOCAL_COPY_PATH);
201 EXPECT_TRUE(testFile->isOpen());
205 std::atomic<bool> printProgressHaveBeenCalled(
false);
208 printProgressHaveBeenCalled =
true;
209 qiLogInfo() <<
"#### File Transfer Progress = " << (progress * 100.0) <<
"%";
212 class Test_ReadRemoteFile :
public ::testing::Test
217 qi::DynamicObjectBuilder objectBuilder;
218 objectBuilder.advertiseMethod(
"getTestFile", &getTestFile);
219 service = objectBuilder.object();
221 qi::SessionPtr serverSession = sessionPair.server();
222 serverSession->registerService(
"service", service);
227 qi::AnyObject service = sessionPair.client()->service(
"service").value();
229 EXPECT_TRUE(testFile->isRemote());
234 TestSessionPair sessionPair;
235 qi::AnyObject service;
239 TEST_F(Test_ReadRemoteFile, isLocalOrRemote)
243 EXPECT_FALSE(testFile->isRemote());
246 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
247 EXPECT_TRUE(testFile->isRemote());
253 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
255 static const size_t COUNT_BYTES_TO_READ = 20;
257 qi::Buffer buffer = testFile->read(COUNT_BYTES_TO_READ);
258 ASSERT_EQ(COUNT_BYTES_TO_READ, buffer.totalSize());
259 checkIsTestFileContent(buffer);
264 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
266 static const size_t COUNT_BYTES_TO_READ_PER_CYCLE = 10;
269 qi::Buffer cycleBuffer;
272 cycleBuffer = testFile->read(COUNT_BYTES_TO_READ_PER_CYCLE);
273 buffer.write(cycleBuffer.data(), cycleBuffer.totalSize());
274 if (cycleBuffer.totalSize() < COUNT_BYTES_TO_READ_PER_CYCLE)
278 EXPECT_EQ(TESTFILE_CONTENT.size(), buffer.totalSize());
279 checkIsTestFileContent(buffer);
284 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
286 const std::streamsize fileSize = testFile->size();
287 EXPECT_EQ(std::streamsize(TESTFILE_CONTENT.size()), fileSize);
289 qi::Buffer buffer = testFile->read(fileSize);
290 EXPECT_EQ(TESTFILE_CONTENT.size(), buffer.totalSize());
291 checkIsTestFileContent(buffer);
294 TEST_F(Test_ReadRemoteFile, filetransfert)
296 static const qi::Path LOCAL_PATH_TO_RECEIVE_FILE_IN = TEMPORARY_DIR.PATH /
"file.data";
297 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
300 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
302 copyToLocal(testFile, LOCAL_PATH_TO_RECEIVE_FILE_IN);
306 EXPECT_TRUE(localFileCopy->isOpen());
307 checkIsTestFileContent(*localFileCopy);
310 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
313 TEST_F(Test_ReadRemoteFile, readInTheMiddle)
315 qi::FilePtr testFile = clientAcquireTestFile(SMALL_TEST_FILE_PATH);
317 qi::Buffer bufferPartial = testFile->read(TESTFILE_PARTIAL_BEGIN_POSITION, TESTFILE_PARTIAL_SIZE);
318 checkIsTestFilePartialContent(bufferPartial);
320 qi::Buffer bufferMiddle = testFile->read(TESTFILE_MIDDLE_BEGIN_POSITION, TESTFILE_MIDDLE_SIZE);
321 checkIsTestFileMiddleContent(bufferMiddle);
324 TEST_F(Test_ReadRemoteFile, bigFiletransfert)
326 static const qi::Path LOCAL_PATH_TO_RECEIVE_FILE_IN = TEMPORARY_DIR.PATH /
"bigfile.data";
327 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
330 qi::FilePtr testFile = clientAcquireTestFile(BIG_TEST_FILE_PATH);
332 qi::FileCopyToLocal fileCopy{testFile, LOCAL_PATH_TO_RECEIVE_FILE_IN};
334 fileCopy.start().wait();
336 EXPECT_TRUE(printProgressHaveBeenCalled.load());
341 checkSameFilesContent(*originalFile, *localFileCopy);
344 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
347 TEST_F(Test_ReadRemoteFile, cancelFileTransfer)
349 static const qi::Path LOCAL_PATH_TO_RECEIVE_FILE_IN = TEMPORARY_DIR.PATH /
"bigfile.data";
350 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
353 qi::FilePtr testFile = clientAcquireTestFile(BIG_TEST_FILE_PATH);
355 qi::FileCopyToLocal fileOp{ testFile, LOCAL_PATH_TO_RECEIVE_FILE_IN };
356 auto fileOpNotifier = fileOp.notifier();
360 fileOpNotifier->waitForFinished().cancel();
363 qi::Future<void> copyOpFt = fileOp.start();
365 EXPECT_TRUE(copyOpFt.isCanceled());
368 EXPECT_FALSE(boost::filesystem::exists(LOCAL_PATH_TO_RECEIVE_FILE_IN));
369 boost::filesystem::remove(LOCAL_PATH_TO_RECEIVE_FILE_IN);
372 int main(
int argc,
char** argv)
374 ::TestMode::forceTestMode(TestMode::Mode_SD);
375 ::testing::InitGoogleTest(&argc, argv);
376 qi::Application
app(argc, argv);
377 BIG_TEST_FILE_PATH = qi::path::findLib(
"qi");
379 const int result = RUN_ALL_TESTS();