hdfs_ext_test.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "hdfspp_mini_dfs.h"
  19. #include "hdfspp/hdfs_ext.h"
  20. #include <cstring>
  21. #include <chrono>
  22. #include <exception>
  23. namespace hdfs {
  24. class HdfsExtTest: public ::testing::Test {
  25. public:
  26. MiniCluster cluster;
  27. };
  28. // Make sure we can set up a mini-cluster and connect to it
  29. TEST_F(HdfsExtTest, TestGetBlockLocations) {
  30. HdfsHandle connection = cluster.connect_c();
  31. EXPECT_NE(nullptr, connection.handle());
  32. hdfsBlockLocations * blocks = nullptr;
  33. // Free a null pointer
  34. int result = hdfsFreeBlockLocations(blocks);
  35. EXPECT_EQ(0, result);
  36. // Test non-extant files
  37. EXPECT_EQ(-1, hdfsGetBlockLocations(connection, "non_extant_file", &blocks)); // Should be an error
  38. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  39. // Test an extant file
  40. std::string filename = connection.newFile(1024);
  41. result = hdfsGetBlockLocations(connection, filename.c_str(), &blocks);
  42. EXPECT_EQ(0, result);
  43. EXPECT_EQ(1024, blocks->fileLength);
  44. EXPECT_EQ(1, blocks->num_blocks);
  45. EXPECT_EQ(0, blocks->isUnderConstruction);
  46. EXPECT_NE(0, blocks->isLastBlockComplete);
  47. EXPECT_EQ(1024, blocks->blocks->num_bytes);
  48. EXPECT_EQ(0, blocks->blocks->start_offset);
  49. EXPECT_EQ(1, blocks->blocks->num_locations);
  50. EXPECT_NE(nullptr, blocks->blocks->locations->hostname);
  51. EXPECT_NE(nullptr, blocks->blocks->locations->ip_address);
  52. EXPECT_NE(nullptr, blocks->blocks->locations->network_location);
  53. EXPECT_NE(0, blocks->blocks->locations->xfer_port);
  54. result = hdfsFreeBlockLocations(blocks);
  55. EXPECT_EQ(0, result);
  56. }
  57. // Writing a file to the filesystem and checking the used space
  58. TEST_F(HdfsExtTest, TestGetUsed) {
  59. using namespace std::chrono;
  60. HdfsHandle connection = cluster.connect_c();
  61. hdfsFS fs = connection.handle();
  62. EXPECT_NE(nullptr, fs);
  63. // File system's used space before writing
  64. tOffset used_before_write;
  65. EXPECT_GE(used_before_write = hdfsGetUsed(fs), 0);
  66. // Write to a file
  67. tOffset fileSize = 1024;
  68. std::string filename = connection.newFile(fileSize);
  69. //Need to run hdfsGetUsed() in a loop until the refreshInterval
  70. //is passed on the filesystem and the used space is updated
  71. //Time-out is 3 minutes
  72. tOffset used_after_write;
  73. tOffset difference;
  74. minutes beginTime = duration_cast<minutes>(
  75. system_clock::now().time_since_epoch());
  76. minutes currentTime;
  77. do{
  78. EXPECT_GE(used_after_write = hdfsGetUsed(fs), 0);
  79. difference = used_after_write - used_before_write;
  80. currentTime = duration_cast<minutes>(
  81. system_clock::now().time_since_epoch());
  82. } while (difference == 0 && currentTime.count() - beginTime.count() < 3);
  83. //There should be at least fileSize bytes added to the used space
  84. EXPECT_GT(difference, fileSize);
  85. //There could be additional metadata added to the used space,
  86. //but no more than double the fileSize
  87. EXPECT_LT(difference, fileSize * 2);
  88. }
  89. //Testing allow, disallow, create, and delete snapshot
  90. TEST_F(HdfsExtTest, TestSnapshotOperations) {
  91. HdfsHandle connection = cluster.connect_c();
  92. hdfsFS fs = connection.handle();
  93. EXPECT_NE(nullptr, fs);
  94. //argument 'path' is NULL
  95. EXPECT_EQ(-1, hdfsAllowSnapshot(fs, nullptr));
  96. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  97. EXPECT_EQ(-1, hdfsCreateSnapshot(fs, nullptr, "Bad"));
  98. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  99. EXPECT_EQ(-1, hdfsDeleteSnapshot(fs, nullptr, "Bad"));
  100. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  101. EXPECT_EQ(-1, hdfsRenameSnapshot(fs, nullptr, "Bad", "Bad"));
  102. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  103. EXPECT_EQ(-1, hdfsDisallowSnapshot(fs, nullptr));
  104. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  105. //argument 'name' is NULL for deletion
  106. EXPECT_EQ(-1, hdfsDeleteSnapshot(fs, "/dir/", nullptr));
  107. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  108. //Path not found
  109. std::string path = "/wrong/dir/";
  110. EXPECT_EQ(-1, hdfsAllowSnapshot(fs, path.c_str()));
  111. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  112. EXPECT_EQ(-1, hdfsCreateSnapshot(fs, path.c_str(), "Bad"));
  113. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  114. EXPECT_EQ(-1, hdfsDeleteSnapshot(fs, path.c_str(), "Bad"));
  115. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  116. EXPECT_EQ(-1, hdfsRenameSnapshot(fs, path.c_str(), "Bad", "Bad"));
  117. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  118. EXPECT_EQ(-1, hdfsDisallowSnapshot(fs, path.c_str()));
  119. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  120. //Not a directory
  121. path = connection.newFile(1024); //1024 byte file
  122. EXPECT_EQ(-1, hdfsAllowSnapshot(fs, path.c_str()));
  123. EXPECT_EQ((int) std::errc::not_a_directory, errno);
  124. EXPECT_EQ(-1, hdfsCreateSnapshot(fs, path.c_str(), "Bad"));
  125. EXPECT_EQ((int) std::errc::not_a_directory, errno);
  126. EXPECT_EQ(-1, hdfsDeleteSnapshot(fs, path.c_str(), "Bad"));
  127. EXPECT_EQ((int) std::errc::not_a_directory, errno);
  128. EXPECT_EQ(-1, hdfsRenameSnapshot(fs, path.c_str(), "Bad", "Bad"));
  129. EXPECT_EQ((int) std::errc::not_a_directory, errno);
  130. EXPECT_EQ(-1, hdfsDisallowSnapshot(fs, path.c_str()));
  131. EXPECT_EQ((int) std::errc::not_a_directory, errno);
  132. //Not snapshottable directory
  133. std::string dirName = connection.newDir();
  134. EXPECT_EQ(0, hdfsDisallowSnapshot(fs, dirName.c_str()));
  135. EXPECT_EQ(-1, hdfsCreateSnapshot(fs, dirName.c_str(), "Bad"));
  136. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  137. //Verify snapshot created
  138. EXPECT_EQ(0, hdfsAllowSnapshot(fs, dirName.c_str()));
  139. EXPECT_EQ(0, hdfsCreateSnapshot(fs, dirName.c_str(), "Good"));
  140. std::string snapDir = dirName + ".snapshot/";
  141. int size;
  142. hdfsFileInfo *file_infos;
  143. EXPECT_NE(nullptr, file_infos = hdfsListDirectory(fs, snapDir.c_str(), &size));
  144. EXPECT_EQ(1, size);
  145. EXPECT_STREQ("Good", file_infos[0].mName);
  146. hdfsFreeFileInfo(file_infos, 1);
  147. //Verify snapshot renamed
  148. EXPECT_EQ(0, hdfsRenameSnapshot(fs, dirName.c_str(), "Good", "Best"));
  149. //Verify snapshot deleted
  150. EXPECT_EQ(0, hdfsDeleteSnapshot(fs, dirName.c_str(), "Best"));
  151. EXPECT_EQ(nullptr, file_infos = hdfsListDirectory(fs, snapDir.c_str(), &size));
  152. EXPECT_EQ(0, size);
  153. hdfsFreeFileInfo(file_infos, 0);
  154. }
  155. //Testing creating directories
  156. TEST_F(HdfsExtTest, TestMkdirs) {
  157. HdfsHandle connection = cluster.connect_c();
  158. hdfsFS fs = connection.handle();
  159. EXPECT_NE(nullptr, fs);
  160. //Correct operation
  161. EXPECT_EQ(0, hdfsCreateDirectory(fs, "/myDir123"));
  162. //TODO Should return error if directory already exists?
  163. //EXPECT_EQ(-1, hdfsCreateDirectory(fs, "/myDir123"));
  164. //EXPECT_EQ((int) std::errc::file_exists, errno);
  165. //Creating directory on a path of the existing file
  166. std::string path = connection.newFile(1024); //1024 byte file
  167. EXPECT_EQ(-1, hdfsCreateDirectory(fs, path.c_str()));
  168. EXPECT_EQ((int) std::errc::file_exists, errno);
  169. }
  170. //Testing deleting files and directories
  171. TEST_F(HdfsExtTest, TestDelete) {
  172. HdfsHandle connection = cluster.connect_c();
  173. hdfsFS fs = connection.handle();
  174. EXPECT_NE(nullptr, fs);
  175. //Path not found
  176. EXPECT_EQ(-1, hdfsDelete(fs, "/wrong_path", 1));
  177. EXPECT_EQ((int) std::errc::no_such_file_or_directory, errno);
  178. EXPECT_EQ(0, hdfsCreateDirectory(fs, "/myDir"));
  179. std::string path = connection.newFile("/myDir", 1024); //1024 byte file
  180. //Non-recursive delete should fail on a non-empty directory
  181. //error ENOTEMPTY(39) for libhdfspp or 255 for libhdfs
  182. EXPECT_EQ(-1, hdfsDelete(fs, "/myDir", 0));
  183. EXPECT_EQ((int) std::errc::directory_not_empty, errno);
  184. //Correct operation
  185. EXPECT_EQ(0, hdfsDelete(fs, "/myDir", 1));
  186. }
  187. //Testing renaming files and directories
  188. TEST_F(HdfsExtTest, TestRename) {
  189. HdfsHandle connection = cluster.connect_c();
  190. hdfsFS fs = connection.handle();
  191. EXPECT_NE(nullptr, fs);
  192. //Creating directory with two files
  193. EXPECT_EQ(0, hdfsCreateDirectory(fs, "/myDir"));
  194. std::string file1 = connection.newFile("/myDir", 1024); //1024 byte file
  195. std::string file2 = connection.newFile("/myDir", 1024); //1024 byte file
  196. std::string file3 = connection.newFile(1024); //1024 byte file
  197. //Path not found
  198. EXPECT_EQ(-1, hdfsRename(fs, "/wrong_path", "/new_name"));
  199. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  200. //No parent directory in new path
  201. EXPECT_EQ(-1, hdfsRename(fs, file1.c_str(), "/wrong_parent/new_name"));
  202. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  203. //New name already exists in the folder
  204. EXPECT_EQ(-1, hdfsRename(fs, file1.c_str(), file2.c_str()));
  205. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  206. //Correct operation
  207. EXPECT_EQ(0, hdfsRename(fs, file1.c_str(), "/myDir/new_awesome_name"));
  208. EXPECT_EQ(0, hdfsRename(fs, file3.c_str(), "/myDir/another_file"));
  209. EXPECT_EQ(0, hdfsRename(fs, "/myDir", "/new_awesome_dir"));
  210. //Verification
  211. int numEntries;
  212. hdfsFileInfo * dirList = hdfsListDirectory(fs, "/new_awesome_dir", &numEntries);
  213. EXPECT_NE(nullptr, dirList);
  214. EXPECT_EQ(3, numEntries);
  215. hdfsFreeFileInfo(dirList, 3);
  216. }
  217. //Testing Chmod and Chown
  218. TEST_F(HdfsExtTest, TestChmodChown) {
  219. HdfsHandle connection = cluster.connect_c();
  220. hdfsFS fs = connection.handle();
  221. EXPECT_NE(nullptr, fs);
  222. //Path not found
  223. std::string path = "/wrong/dir/";
  224. EXPECT_EQ(-1, hdfsChmod(fs, path.c_str(), 0777));
  225. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  226. EXPECT_EQ(-1, hdfsChown(fs, path.c_str(), "foo", "bar"));
  227. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  228. //Wrong arguments
  229. path = connection.newFile(1024); //1024 byte file
  230. EXPECT_EQ(-1, hdfsChmod(fs, nullptr, 0777));
  231. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  232. EXPECT_EQ(-1, hdfsChmod(fs, path.c_str(), 07777));
  233. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  234. EXPECT_EQ(-1, hdfsChmod(fs, path.c_str(), -1));
  235. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  236. EXPECT_EQ(-1, hdfsChown(fs, nullptr, "foo", "bar"));
  237. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  238. //Permission denied
  239. HdfsHandle connection2 = cluster.connect_c("OtherGuy");
  240. hdfsFS fs2 = connection2.handle();
  241. EXPECT_EQ(-1, hdfsChmod(fs2, path.c_str(), 0123));
  242. EXPECT_EQ((int ) std::errc::permission_denied, errno);
  243. EXPECT_EQ(-1, hdfsChown(fs2, path.c_str(), "cool", "nice"));
  244. EXPECT_EQ((int ) std::errc::permission_denied, errno);
  245. //Verify Chmod and Chown worked
  246. EXPECT_EQ(0, hdfsChmod(fs, path.c_str(), 0123));
  247. EXPECT_EQ(0, hdfsChown(fs, path.c_str(), "cool", "nice"));
  248. hdfsFileInfo *file_info;
  249. EXPECT_NE(nullptr, file_info = hdfsGetPathInfo(fs, path.c_str()));
  250. EXPECT_EQ(0123, file_info->mPermissions);
  251. EXPECT_STREQ("cool", file_info->mOwner);
  252. EXPECT_STREQ("nice", file_info->mGroup);
  253. hdfsFreeFileInfo(file_info, 1);
  254. }
  255. //Testing EOF
  256. TEST_F(HdfsExtTest, TestEOF) {
  257. HdfsHandle connection = cluster.connect_c();
  258. hdfsFS fs = connection.handle();
  259. EXPECT_NE(nullptr, fs);
  260. //Write to a file
  261. errno = 0;
  262. int size = 256;
  263. std::string path = "/eofTest";
  264. hdfsFile file = hdfsOpenFile(fs, path.c_str(), O_WRONLY, 0, 0, 0);
  265. EXPECT_NE(nullptr, file);
  266. void * buf = malloc(size);
  267. memset(buf, ' ', size);
  268. EXPECT_EQ(size, hdfsWrite(fs, file, buf, size));
  269. free(buf);
  270. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  271. //libhdfs file operations work, but sometimes sets errno ENOENT : 2
  272. //Test normal reading (no EOF)
  273. char buffer[300];
  274. file = hdfsOpenFile(fs, path.c_str(), O_RDONLY, 0, 0, 0);
  275. EXPECT_EQ(size, hdfsPread(fs, file, 0, buffer, sizeof(buffer)));
  276. //Read executes correctly, but causes a warning (captured in HDFS-10595)
  277. //and sets errno to EINPROGRESS 115 : Operation now in progress
  278. //Test reading at offset past the EOF
  279. EXPECT_EQ(-1, hdfsPread(fs, file, sizeof(buffer), buffer, sizeof(buffer)));
  280. EXPECT_EQ(Status::kInvalidOffset, errno);
  281. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  282. }
  283. //Testing hdfsExists
  284. TEST_F(HdfsExtTest, TestExists) {
  285. HdfsHandle connection = cluster.connect_c();
  286. hdfsFS fs = connection.handle();
  287. EXPECT_NE(nullptr, fs);
  288. //Path not found
  289. EXPECT_EQ(-1, hdfsExists(fs, "/wrong/dir/"));
  290. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  291. //Correct operation
  292. std::string pathDir = "/testExistsDir";
  293. EXPECT_EQ(0, hdfsCreateDirectory(fs, pathDir.c_str()));
  294. EXPECT_EQ(0, hdfsExists(fs, pathDir.c_str()));
  295. std::string pathFile = connection.newFile(pathDir.c_str(), 1024);
  296. EXPECT_EQ(0, hdfsExists(fs, pathFile.c_str()));
  297. //Permission denied
  298. EXPECT_EQ(0, hdfsChmod(fs, pathDir.c_str(), 0700));
  299. HdfsHandle connection2 = cluster.connect_c("OtherGuy");
  300. hdfsFS fs2 = connection2.handle();
  301. EXPECT_EQ(-1, hdfsExists(fs2, pathFile.c_str()));
  302. EXPECT_EQ((int ) std::errc::permission_denied, errno);
  303. }
  304. //Testing Replication and Time modifications
  305. TEST_F(HdfsExtTest, TestReplAndTime) {
  306. HdfsHandle connection = cluster.connect_c();
  307. hdfsFS fs = connection.handle();
  308. EXPECT_NE(nullptr, fs);
  309. std::string path = "/wrong/dir/";
  310. //Path not found
  311. EXPECT_EQ(-1, hdfsSetReplication(fs, path.c_str(), 3));
  312. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  313. EXPECT_EQ(-1, hdfsUtime(fs, path.c_str(), 1000000, 1000000));
  314. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  315. //Correct operation
  316. path = connection.newFile(1024);
  317. EXPECT_EQ(0, hdfsSetReplication(fs, path.c_str(), 7));
  318. EXPECT_EQ(0, hdfsUtime(fs, path.c_str(), 123456789, 987654321));
  319. hdfsFileInfo *file_info;
  320. EXPECT_NE(nullptr, file_info = hdfsGetPathInfo(fs, path.c_str()));
  321. EXPECT_EQ(7, file_info->mReplication);
  322. EXPECT_EQ(123456789, file_info->mLastMod);
  323. EXPECT_EQ(987654321, file_info->mLastAccess);
  324. hdfsFreeFileInfo(file_info, 1);
  325. //Wrong arguments
  326. EXPECT_EQ(-1, hdfsSetReplication(fs, path.c_str(), 0));
  327. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  328. EXPECT_EQ(-1, hdfsSetReplication(fs, path.c_str(), 513));
  329. EXPECT_EQ((int ) std::errc::invalid_argument, errno);
  330. //Permission denied
  331. EXPECT_EQ(0, hdfsChmod(fs, path.c_str(), 0700));
  332. HdfsHandle connection2 = cluster.connect_c("OtherGuy");
  333. hdfsFS fs2 = connection2.handle();
  334. EXPECT_EQ(-1, hdfsSetReplication(fs2, path.c_str(), 3));
  335. EXPECT_EQ((int ) std::errc::permission_denied, errno);
  336. EXPECT_EQ(-1, hdfsUtime(fs2, path.c_str(), 111111111, 222222222));
  337. EXPECT_EQ((int ) std::errc::permission_denied, errno);
  338. }
  339. //Testing getting default block size at path
  340. TEST_F(HdfsExtTest, TestDefaultBlockSize) {
  341. HdfsHandle connection = cluster.connect_c();
  342. hdfsFS fs = connection.handle();
  343. EXPECT_NE(nullptr, fs);
  344. //Correct operation (existing path)
  345. std::string path = connection.newFile(1024);
  346. long block_size = hdfsGetDefaultBlockSizeAtPath(fs, path.c_str());
  347. EXPECT_GT(block_size, 0);
  348. hdfsFileInfo *file_info;
  349. EXPECT_NE(nullptr, file_info = hdfsGetPathInfo(fs, path.c_str()));
  350. EXPECT_EQ(block_size, file_info->mBlockSize);
  351. hdfsFreeFileInfo(file_info, 1);
  352. //Non-existing path
  353. path = "/wrong/dir/";
  354. EXPECT_GT(hdfsGetDefaultBlockSizeAtPath(fs, path.c_str()), 0);
  355. //No path specified
  356. EXPECT_GT(hdfsGetDefaultBlockSize(fs), 0);
  357. }
  358. //Testing getting hosts
  359. TEST_F(HdfsExtTest, TestHosts) {
  360. HdfsHandle connection = cluster.connect_c();
  361. hdfsFS fs = connection.handle();
  362. EXPECT_NE(nullptr, fs);
  363. char *** hosts = nullptr;
  364. // Free a null pointer
  365. hdfsFreeHosts(hosts);
  366. EXPECT_EQ(0, errno);
  367. // Test non-existent files
  368. EXPECT_EQ(nullptr, hdfsGetHosts(fs, "/wrong/file/", 0, std::numeric_limits<int64_t>::max()));
  369. EXPECT_EQ((int ) std::errc::no_such_file_or_directory, errno);
  370. // Test an existent file
  371. std::string filename = connection.newFile(1024);
  372. EXPECT_NE(nullptr, hosts = hdfsGetHosts(fs, filename.c_str(), 0, std::numeric_limits<int64_t>::max()));
  373. //Make sure there is at least one host
  374. EXPECT_NE(nullptr, *hosts);
  375. EXPECT_NE(nullptr, **hosts);
  376. hdfsFreeHosts(hosts);
  377. EXPECT_EQ(0, errno);
  378. //Test invalid arguments
  379. EXPECT_EQ(nullptr, hdfsGetHosts(fs, filename.c_str(), 0, std::numeric_limits<int64_t>::max()+1));
  380. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  381. //Test invalid arguments
  382. EXPECT_EQ(nullptr, hdfsGetHosts(fs, filename.c_str(), std::numeric_limits<int64_t>::max()+1, std::numeric_limits<int64_t>::max()));
  383. EXPECT_EQ((int) std::errc::invalid_argument, errno);
  384. }
  385. //Testing read statistics
  386. TEST_F(HdfsExtTest, TestReadStats) {
  387. HdfsHandle connection = cluster.connect_c();
  388. hdfsFS fs = connection.handle();
  389. EXPECT_NE(nullptr, fs);
  390. struct hdfsReadStatistics *stats;
  391. //Write to a file
  392. int size = 256;
  393. std::string path = "/readStatTest";
  394. hdfsFile file = hdfsOpenFile(fs, path.c_str(), O_WRONLY, 0, 0, 0);
  395. EXPECT_NE(nullptr, file);
  396. void * buf = malloc(size);
  397. bzero(buf, size);
  398. EXPECT_EQ(size, hdfsWrite(fs, file, buf, size));
  399. free(buf);
  400. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  401. //test before reading
  402. file = hdfsOpenFile(fs, path.c_str(), O_RDONLY, 0, 0, 0);
  403. EXPECT_EQ(0, hdfsFileGetReadStatistics(file, &stats));
  404. EXPECT_EQ(0, stats->totalBytesRead);
  405. hdfsFileFreeReadStatistics(stats);
  406. //test after reading
  407. char buffer[123];
  408. //Read executes correctly, but causes a warning (captured in HDFS-10595)
  409. EXPECT_EQ(sizeof(buffer), hdfsRead(fs, file, buffer, sizeof(buffer)));
  410. EXPECT_EQ(0, hdfsFileGetReadStatistics(file, &stats));
  411. EXPECT_EQ(sizeof(buffer), stats->totalBytesRead);
  412. EXPECT_EQ(sizeof(buffer), stats->totalLocalBytesRead);
  413. EXPECT_EQ(0, hdfsReadStatisticsGetRemoteBytesRead(stats));
  414. hdfsFileFreeReadStatistics(stats);
  415. //test after clearing
  416. EXPECT_EQ(0, hdfsFileClearReadStatistics(file));
  417. EXPECT_EQ(0, hdfsFileGetReadStatistics(file, &stats));
  418. EXPECT_EQ(0, stats->totalBytesRead);
  419. hdfsFileFreeReadStatistics(stats);
  420. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  421. EXPECT_EQ(0, errno);
  422. }
  423. //Testing working directory
  424. TEST_F(HdfsExtTest, TestWorkingDirectory) {
  425. HdfsHandle connection = cluster.connect_c();
  426. hdfsFS fs = connection.handle();
  427. EXPECT_NE(nullptr, fs);
  428. //Correct operation of setter and getter
  429. std::string pathDir = "/testWorkDir/";
  430. EXPECT_EQ(0, hdfsCreateDirectory(fs, pathDir.c_str()));
  431. std::string pathFile = connection.newFile(pathDir.c_str(), 1024);
  432. EXPECT_EQ(0, hdfsSetWorkingDirectory(fs, pathDir.c_str()));
  433. char array[100];
  434. EXPECT_STREQ(pathDir.c_str(), hdfsGetWorkingDirectory(fs, array, 100));
  435. //Get relative path
  436. std::size_t slashPos = pathFile.find_last_of("/");
  437. std::string fileName = pathFile.substr(slashPos + 1);
  438. //Testing various functions with relative path:
  439. //hdfsGetDefaultBlockSizeAtPath
  440. EXPECT_GT(hdfsGetDefaultBlockSizeAtPath(fs, fileName.c_str()), 0);
  441. //hdfsSetReplication
  442. EXPECT_EQ(0, hdfsSetReplication(fs, fileName.c_str(), 7));
  443. //hdfsUtime
  444. EXPECT_EQ(0, hdfsUtime(fs, fileName.c_str(), 123456789, 987654321));
  445. //hdfsExists
  446. EXPECT_EQ(0, hdfsExists(fs, fileName.c_str()));
  447. //hdfsGetPathInfo
  448. hdfsFileInfo *file_info;
  449. EXPECT_NE(nullptr, file_info = hdfsGetPathInfo(fs, fileName.c_str()));
  450. hdfsFreeFileInfo(file_info, 1);
  451. //hdfsOpenFile
  452. hdfsFile file;
  453. file = hdfsOpenFile(fs, fileName.c_str(), O_RDONLY, 0, 0, 0);
  454. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  455. //hdfsCreateDirectory
  456. EXPECT_EQ(0, hdfsCreateDirectory(fs, "newDir"));
  457. //add another file
  458. std::string fileName2 = connection.newFile(pathDir + "/newDir", 1024);
  459. //hdfsListDirectory
  460. int numEntries;
  461. hdfsFileInfo * dirList;
  462. EXPECT_NE(nullptr, dirList = hdfsListDirectory(fs, "newDir", &numEntries));
  463. EXPECT_EQ(1, numEntries);
  464. hdfsFreeFileInfo(dirList, 1);
  465. //hdfsChmod
  466. EXPECT_EQ(0, hdfsChmod(fs, fileName.c_str(), 0777));
  467. //hdfsChown
  468. EXPECT_EQ(0, hdfsChown(fs, fileName.c_str(), "cool", "nice"));
  469. //hdfsDisallowSnapshot
  470. EXPECT_EQ(0, hdfsDisallowSnapshot(fs, "newDir"));
  471. //hdfsAllowSnapshot
  472. EXPECT_EQ(0, hdfsAllowSnapshot(fs, "newDir"));
  473. //hdfsCreateSnapshot
  474. EXPECT_EQ(0, hdfsCreateSnapshot(fs, "newDir", "Some"));
  475. //hdfsDeleteSnapshot
  476. EXPECT_EQ(0, hdfsDeleteSnapshot(fs, "newDir", "Some"));
  477. //hdfsGetBlockLocations
  478. hdfsBlockLocations * blocks = nullptr;
  479. EXPECT_EQ(0, hdfsGetBlockLocations(connection, fileName.c_str(), &blocks));
  480. hdfsFreeBlockLocations(blocks);
  481. //hdfsGetHosts
  482. char *** hosts;
  483. EXPECT_NE(nullptr, hosts = hdfsGetHosts(fs, fileName.c_str(), 0, std::numeric_limits<int64_t>::max()));
  484. hdfsFreeHosts(hosts);
  485. //hdfsRename
  486. EXPECT_EQ(0, hdfsRename(fs, fileName.c_str(), "new_file_name"));
  487. //hdfsDelete
  488. EXPECT_EQ(0, hdfsDelete(fs, "new_file_name", 0));
  489. }
  490. // Flags used to test event handlers
  491. static int connect_callback_invoked = 0;
  492. int basic_fs_callback(const char *event, const char *cluster, int64_t value, int64_t cookie) {
  493. (void)cluster;
  494. (void)value;
  495. if(::strstr(FS_NN_CONNECT_EVENT, event) && cookie == 0xFFF0) {
  496. connect_callback_invoked = 1;
  497. }
  498. return LIBHDFSPP_EVENT_OK;
  499. }
  500. // Make sure event handler gets called during connect
  501. TEST_F(HdfsExtTest, TestConnectEvent) {
  502. connect_callback_invoked = 0;
  503. hdfsPreAttachFSMonitor(basic_fs_callback, 0xFFF0);
  504. HdfsHandle connection = cluster.connect_c();
  505. hdfsFS fs = connection.handle();
  506. EXPECT_NE(nullptr, fs);
  507. EXPECT_EQ(connect_callback_invoked, 1);
  508. }
  509. int throwing_fs_callback(const char *event, const char *cluster, int64_t value, int64_t cookie) {
  510. (void)cluster;
  511. (void)value;
  512. if(::strstr(FS_NN_CONNECT_EVENT, event) && cookie == 0xFFF1) {
  513. connect_callback_invoked = 1;
  514. throw std::runtime_error("Throwing in callbacks is a bad thing.");
  515. }
  516. return LIBHDFSPP_EVENT_OK;
  517. }
  518. // Make sure throwing in the connect event handler doesn't prevent connection
  519. TEST_F(HdfsExtTest, TestConnectEventThrow) {
  520. connect_callback_invoked = 0;
  521. hdfsPreAttachFSMonitor(throwing_fs_callback, 0xFFF1);
  522. HdfsHandle connection = cluster.connect_c();
  523. hdfsFS fs = connection.handle();
  524. EXPECT_NE(nullptr, fs);
  525. EXPECT_EQ(connect_callback_invoked, 1);
  526. }
  527. int char_throwing_fs_callback(const char *event, const char *cluster, int64_t value, int64_t cookie) {
  528. (void)cluster;
  529. (void)value;
  530. if(::strstr(FS_NN_CONNECT_EVENT, event) && cookie == 0xFFF2) {
  531. connect_callback_invoked = 1;
  532. throw "Throwing non std::exceptions in callbacks is even worse.";
  533. }
  534. return LIBHDFSPP_EVENT_OK;
  535. }
  536. TEST_F(HdfsExtTest, TestConnectEventThrowChar) {
  537. connect_callback_invoked = 0;
  538. hdfsPreAttachFSMonitor(char_throwing_fs_callback, 0xFFF2);
  539. HdfsHandle connection = cluster.connect_c();
  540. hdfsFS fs = connection.handle();
  541. EXPECT_NE(nullptr, fs);
  542. EXPECT_EQ(connect_callback_invoked, 1);
  543. }
  544. // Make sure throwing in the read event handler doesn't prevent reads
  545. int read_handler_invokation_count = 0;
  546. int basic_read_event_handler(const char *event, const char *cluster, const char *file,
  547. int64_t value, int64_t cookie)
  548. {
  549. (void)cluster;
  550. (void)file;
  551. (void)value;
  552. if(::strstr(FILE_DN_READ_EVENT, event) && cookie == 0xFFF3) {
  553. read_handler_invokation_count += 1;
  554. }
  555. return LIBHDFSPP_EVENT_OK;
  556. }
  557. // Testing that read handler is called.
  558. // Note: This is counting calls to async_read rather than hdfsPread.
  559. // Typically a call to hdfs(P)Read that doesn't span blocks/packets
  560. // invokes async_read 6 times; 4 more than required (improving that
  561. // in HDFS-11266).
  562. TEST_F(HdfsExtTest, TestReadEvent) {
  563. read_handler_invokation_count = 0;
  564. hdfsPreAttachFileMonitor(basic_read_event_handler, 0xFFF3);
  565. HdfsHandle connection = cluster.connect_c();
  566. hdfsFS fs = connection.handle();
  567. EXPECT_NE(nullptr, fs);
  568. //Write to a file
  569. errno = 0;
  570. int size = 256;
  571. std::string path = "/readEventTest";
  572. hdfsFile file = hdfsOpenFile(fs, path.c_str(), O_WRONLY, 0, 0, 0);
  573. EXPECT_NE(nullptr, file);
  574. void * buf = malloc(size);
  575. memset(buf, ' ', size);
  576. EXPECT_EQ(size, hdfsWrite(fs, file, buf, size));
  577. free(buf);
  578. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  579. //Test that read counters are getting incremented
  580. char buffer[300];
  581. file = hdfsOpenFile(fs, path.c_str(), O_RDONLY, 0, 0, 0);
  582. EXPECT_EQ(size, hdfsPread(fs, file, 0, buffer, sizeof(buffer)));
  583. EXPECT_EQ(read_handler_invokation_count, 6);
  584. EXPECT_EQ(size, hdfsPread(fs, file, 0, buffer, sizeof(buffer)));
  585. EXPECT_EQ(read_handler_invokation_count, 12);
  586. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  587. }
  588. int throwing_read_event_handler(const char *event, const char *cluster, const char *file,
  589. int64_t value, int64_t cookie)
  590. {
  591. (void)cluster;
  592. (void)file;
  593. (void)value;
  594. if(::strstr(FILE_DN_READ_EVENT, event) && cookie == 0xFFF4) {
  595. read_handler_invokation_count += 1;
  596. throw std::runtime_error("Throwing here is a bad idea, but shouldn't break reads");
  597. }
  598. return LIBHDFSPP_EVENT_OK;
  599. }
  600. // Testing that reads can be done when event handler throws.
  601. TEST_F(HdfsExtTest, TestReadEventThrow) {
  602. read_handler_invokation_count = 0;
  603. hdfsPreAttachFileMonitor(throwing_read_event_handler, 0xFFF4);
  604. HdfsHandle connection = cluster.connect_c();
  605. hdfsFS fs = connection.handle();
  606. EXPECT_NE(nullptr, fs);
  607. //Write to a file
  608. errno = 0;
  609. int size = 256;
  610. std::string path = "/readEventTest";
  611. hdfsFile file = hdfsOpenFile(fs, path.c_str(), O_WRONLY, 0, 0, 0);
  612. EXPECT_NE(nullptr, file);
  613. void * buf = malloc(size);
  614. memset(buf, ' ', size);
  615. EXPECT_EQ(size, hdfsWrite(fs, file, buf, size));
  616. free(buf);
  617. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  618. //Test that read counters are getting incremented
  619. char buffer[300];
  620. file = hdfsOpenFile(fs, path.c_str(), O_RDONLY, 0, 0, 0);
  621. EXPECT_EQ(size, hdfsPread(fs, file, 0, buffer, sizeof(buffer)));
  622. EXPECT_EQ(read_handler_invokation_count, 6);
  623. EXPECT_EQ(size, hdfsPread(fs, file, 0, buffer, sizeof(buffer)));
  624. EXPECT_EQ(read_handler_invokation_count, 12);
  625. EXPECT_EQ(0, hdfsCloseFile(fs, file));
  626. }
  627. } // end namespace hdfs
  628. int main(int argc, char *argv[]) {
  629. // The following line must be executed to initialize Google Mock
  630. // (and Google Test) before running the tests.
  631. ::testing::InitGoogleMock(&argc, argv);
  632. int exit_code = RUN_ALL_TESTS();
  633. google::protobuf::ShutdownProtobufLibrary();
  634. return exit_code;
  635. }