commit - 8f317ea03ee469ccab83292584802c52a352ca3e
commit + 7669b92b9f35561c838abf6f2ea1162f219d2afc
blob - 4e83909a70508facb8bc6578a4973f500f3b25da
blob + 218df0d6e740a53293ed9e6279ada706563aa26d
--- .gitignore
+++ .gitignore
cert/
vostok/vostok
tests/test_parse_url
+tests/test_open_file
**/*.swp
**/*.o
blob - af85dcda59bfbc4d7701ab57ec7cf8aaf715b581
blob + d209b7c61c4cebf765b97b2a42a5b6ffd81b706b
--- tests/Makefile
+++ tests/Makefile
CXXFLAGS += -I../vostok
-tests: test_parse_url
+tests: test_parse_url test_open_file
./test_parse_url
+ ./test_open_file
test_parse_url: test_parse_url.cc ../vostok/parse_url.cc ../vostok/parse_url.h
${CXX} ${CXXFLAGS} test_parse_url.cc ../vostok/parse_url.cc -o test_parse_url
+test_open_file: test_open_file.cc ../vostok/open_file.cc ../vostok/open_file.h
+ ${CXX} ${CXXFLAGS} test_open_file.cc ../vostok/open_file.cc -o test_open_file
+
clean:
- rm -f test_parse_url
+ rm -f test_parse_url test_open_file
blob - /dev/null
blob + cea622f498bd0f077d52e69efb29a893e6b0bdb7 (mode 644)
--- /dev/null
+++ tests/test_open_file.cc
+#include <string.h>
+#include <iostream>
+#include <sstream>
+#include <time.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "open_file.h"
+#include "tests.h"
+
+
+namespace vostok
+{
+namespace error
+{
+std::ostream dev_null{nullptr};
+std::ostream &g_log = dev_null;
+}
+
+TEST_START(test_open_file)
+ std::ostringstream ss;
+ ss << "/tmp/test_open_file." << getpid() << "." << time(nullptr);
+ IS_TRUE_ERRNO(mkdir(ss.str().c_str(), S_IRWXU) != -1, "Create directory " << ss.str().c_str());
+
+ const unique_fd dir{open(ss.str().c_str(), O_RDONLY | O_DIRECTORY)};
+ IS_TRUE_ERRNO(dir, "Open directory " << ss.str().c_str());
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "", opened_file) == file_not_found and !opened_file);
+ IS_TRUE(open_file(dir.get(), "non-existent-file", opened_file) == file_not_found and !opened_file);
+ IS_TRUE(open_file(dir.get(), "non-existent-dir/file", opened_file) == file_not_found and !opened_file);
+ }
+
+ const unique_fd index_gmi{openat(dir.get(), "index.gmi", O_RDONLY | O_CREAT | O_EXCL, S_IRWXU)};
+ IS_TRUE_ERRNO(index_gmi, "Create file " << ss.str().c_str() << "/index.gmi");
+ struct stat sb1{};
+ IS_TRUE_ERRNO(fstat(index_gmi.get(), &sb1) != -1, "Stat file " << ss.str().c_str() << "/index.gmi");
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "", opened_file) == file_opened and opened_file);
+ struct stat sb2{};
+ IS_TRUE_ERRNO(fstat(opened_file.get(), &sb2) != -1, "Stat file " << ss.str().c_str() << "/index.gmi");
+ IS_TRUE((sb1.st_dev == sb2.st_dev) && (sb1.st_ino == sb2.st_ino));
+ }
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "index.gmi", opened_file) == file_opened and opened_file);
+ struct stat sb2{};
+ IS_TRUE_ERRNO(fstat(opened_file.get(), &sb2) != -1, "Stat file " << ss.str().c_str() << "/index.gmi");
+ IS_TRUE((sb1.st_dev == sb2.st_dev) && (sb1.st_ino == sb2.st_ino));
+ }
+
+ IS_TRUE_ERRNO(mkdirat(dir.get(), "subdir", S_IRWXU) != -1, "Create directory " << ss.str().c_str() << "/subdir");
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "subdir", opened_file) == file_not_found and !opened_file);
+ IS_TRUE(open_file(dir.get(), "subdir/", opened_file) == file_not_found and !opened_file);
+ }
+ const unique_fd subdir{openat(dir.get(), "subdir", O_RDONLY | O_DIRECTORY)};
+ IS_TRUE_ERRNO(subdir, "Open directory " << ss.str().c_str() << "/subdir");
+
+ const unique_fd sub_index_gmi{openat(subdir.get(), "index.gmi", O_RDONLY | O_CREAT | O_EXCL, S_IRWXU)};
+ IS_TRUE_ERRNO(sub_index_gmi, "Create file " << ss.str().c_str() << "/subdir/index.gmi");
+ IS_TRUE_ERRNO(fstat(sub_index_gmi.get(), &sb1) != -1, "Stat file " << ss.str().c_str() << "/subdir/index.gmi");
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "subdir", opened_file) == file_opened and opened_file);
+ struct stat sb2{};
+ IS_TRUE_ERRNO(fstat(opened_file.get(), &sb2) != -1, "Stat file " << ss.str().c_str() << "/subdir/index.gmi");
+ IS_TRUE((sb1.st_dev == sb2.st_dev) && (sb1.st_ino == sb2.st_ino));
+ }
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "subdir/", opened_file) == file_opened and opened_file);
+ struct stat sb2{};
+ IS_TRUE_ERRNO(fstat(opened_file.get(), &sb2) != -1, "Stat file " << ss.str().c_str() << "/subdir/index.gmi");
+ IS_TRUE((sb1.st_dev == sb2.st_dev) && (sb1.st_ino == sb2.st_ino));
+ }
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "subdir/index.gmi", opened_file) == file_opened and opened_file);
+ struct stat sb2{};
+ IS_TRUE_ERRNO(fstat(opened_file.get(), &sb2) != -1, "Stat file " << ss.str().c_str() << "/subdir/index.gmi");
+ IS_TRUE((sb1.st_dev == sb2.st_dev) && (sb1.st_ino == sb2.st_ino));
+ }
+
+ const unique_fd eperm{openat(subdir.get(), "EPERM.gmi", O_RDONLY | O_CREAT | O_EXCL, 0)};
+ IS_TRUE_ERRNO(eperm, "Create file " << ss.str().c_str() << "/subdir/index.gmi");
+
+ {
+ unique_fd opened_file{};
+ IS_TRUE(open_file(dir.get(), "subdir/EPERM.gmi", opened_file) == file_opening_error and !opened_file);
+ }
+
+ IS_TRUE_ERRNO(unlinkat(subdir.get(), "EPERM.gmi", 0) != -1, "Remove file " << ss.str().c_str() << "/subdir/EPERM.gmi");
+ IS_TRUE_ERRNO(unlinkat(subdir.get(), "index.gmi", 0) != -1, "Remove file " << ss.str().c_str() << "/subdir/index.gmi");
+ IS_TRUE_ERRNO(unlinkat(dir.get(), "subdir", AT_REMOVEDIR) != -1, "Remove directory " << ss.str().c_str() << "/subdir");
+ IS_TRUE_ERRNO(unlinkat(dir.get(), "index.gmi", 0) != -1, "Remove file " << ss.str().c_str() << "/index.gmi");
+ IS_TRUE_ERRNO(rmdir(ss.str().c_str()) != -1, "Remove directory " << ss.str().c_str());
+TEST_END()
+} // namespace vostok
+
+
+extern "C"
+int
+main(int, char **)
+{
+ return vostok::test_open_file();
+}
blob - e48bd425a7637201b650636bd242e1ed7409bdcd
blob + f63e7b699fe5770773ae17075b21503eec03a33c
--- tests/tests.h
+++ tests/tests.h
#pragma once
-#define TEST_START(name) \
-int name() \
-{ \
- int ret = 0;
+#define TEST_START(name) int name() {
#define IS_TRUE(x) \
if(!(x)) \
{ \
- std::cout<<__FUNCTION__<<" failed on line "<<__LINE__<<std::endl;\
- ret=1;\
+ std::cout<<__FUNCTION__<<" failed on line "<<std::dec<<__LINE__<<std::endl;\
+ return 1;\
}
+#define IS_TRUE_ERRNO(x, desc) \
+ if (!(x)) { \
+ const auto error_code = errno; \
+ std::cout<<__FUNCTION__<<" "<< desc <<" failed on line "<<std::dec<<__LINE__<<": "<<strerror(error_code)<<std::endl; \
+ return 1; \
+ }
+
+
#define TEST_END() \
- if(ret == 0) \
- std::cout << __FUNCTION__ << " successfully passed!" << std::endl; \
- return ret; \
+ std::cout << __FUNCTION__ << " successfully passed!" << std::endl; \
+ return 0; \
}