X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/d61960d9244340956a27f4ca46aecd15cc75e18b..99fdd8034b4a5cdb0100a33d0b3d5e26079c1695:/test/libapt/fileutl_test.cc?ds=sidebyside diff --git a/test/libapt/fileutl_test.cc b/test/libapt/fileutl_test.cc index a2c303768..67bd850a1 100644 --- a/test/libapt/fileutl_test.cc +++ b/test/libapt/fileutl_test.cc @@ -4,7 +4,9 @@ #include #include #include +#include +#include #include #include #include @@ -82,6 +84,18 @@ static void TestFileFd(mode_t const a_umask, mode_t const ExpectedFilePermission EXPECT_N_STR(expect, readback); EXPECT_EQ(test.size(), f.Tell()); } + // Non-zero backwards seek + { + APT_INIT_READBACK + char const * const expect = "is"; + EXPECT_EQ(test.size(), f.Tell()); + EXPECT_TRUE(f.Seek(5)); + EXPECT_TRUE(f.Read(readback, strlen(expect))); + EXPECT_FALSE(f.Failed()); + EXPECT_FALSE(f.Eof()); + EXPECT_N_STR(expect, readback); + EXPECT_EQ(7, f.Tell()); + } { APT_INIT_READBACK EXPECT_TRUE(f.Seek(0)); @@ -150,26 +164,34 @@ static void TestFileFd(mode_t const a_umask, mode_t const ExpectedFilePermission static void TestFileFd(unsigned int const filemode) { - std::vector compressors = APT::Configuration::getCompressors(); - - // testing the (un)compress via pipe, as the 'real' compressors are usually built in via libraries - compressors.push_back(APT::Configuration::Compressor("rev", ".reversed", "rev", NULL, NULL, 42)); - //compressors.push_back(APT::Configuration::Compressor("cat", ".ident", "cat", NULL, NULL, 42)); - - for (std::vector::const_iterator c = compressors.begin(); c != compressors.end(); ++c) + auto const compressors = APT::Configuration::getCompressors(); + EXPECT_EQ(7, compressors.size()); + bool atLeastOneWasTested = false; + for (auto const &c: compressors) { if ((filemode & FileFd::ReadWrite) == FileFd::ReadWrite && - (c->Name.empty() != true && c->Binary.empty() != true)) + (c.Name.empty() != true && c.Binary.empty() != true)) continue; - TestFileFd(0002, 0664, filemode, *c); - TestFileFd(0022, 0644, filemode, *c); - TestFileFd(0077, 0600, filemode, *c); - TestFileFd(0026, 0640, filemode, *c); + atLeastOneWasTested = true; + TestFileFd(0002, 0664, filemode, c); + TestFileFd(0022, 0644, filemode, c); + TestFileFd(0077, 0600, filemode, c); + TestFileFd(0026, 0640, filemode, c); } + EXPECT_TRUE(atLeastOneWasTested); } TEST(FileUtlTest, FileFD) { + // testing the (un)compress via pipe, as the 'real' compressors are usually built in via libraries + _config->Set("APT::Compressor::rev::Name", "rev"); + _config->Set("APT::Compressor::rev::Extension", ".reversed"); + _config->Set("APT::Compressor::rev::Binary", "rev"); + _config->Set("APT::Compressor::rev::Cost", 10); + auto const compressors = APT::Configuration::getCompressors(false); + EXPECT_EQ(7, compressors.size()); + EXPECT_TRUE(std::any_of(compressors.begin(), compressors.end(), [](APT::Configuration::Compressor const &c) { return c.Name == "rev"; })); + std::string const startdir = SafeGetCWD(); EXPECT_FALSE(startdir.empty()); std::string tempdir; @@ -194,7 +216,7 @@ TEST(FileUtlTest, Glob) { std::vector files; // normal match - files = Glob("*akefile"); + files = Glob("*MakeLists.txt"); EXPECT_EQ(1, files.size()); // not there @@ -222,9 +244,13 @@ TEST(FileUtlTest, GetTempDir) setenv("TMPDIR", "/not-there-no-really-not", 1); EXPECT_EQ("/tmp", GetTempDir()); - // here but not accessible for non-roots - setenv("TMPDIR", "/usr", 1); - EXPECT_EQ("/tmp", GetTempDir()); + // root can access everything, so /usr will be accepted + if (geteuid() != 0) + { + // here but not accessible for non-roots + setenv("TMPDIR", "/usr", 1); + EXPECT_EQ("/tmp", GetTempDir()); + } // files are no good for tmpdirs, too setenv("TMPDIR", "/dev/null", 1); @@ -290,11 +316,76 @@ TEST(FileUtlTest, Popen) TEST(FileUtlTest, flAbsPath) { std::string cwd = SafeGetCWD(); - int res = chdir("/bin/"); + int res = chdir("/etc/"); EXPECT_EQ(res, 0); - std::string p = flAbsPath("ls"); - EXPECT_EQ(p, "/bin/ls"); + std::string p = flAbsPath("passwd"); + EXPECT_EQ(p, "/etc/passwd"); res = chdir(cwd.c_str()); EXPECT_EQ(res, 0); } + +static void TestDevNullFileFd(unsigned int const filemode) +{ + SCOPED_TRACE(filemode); + FileFd f("/dev/null", filemode); + EXPECT_FALSE(f.Failed()); + EXPECT_TRUE(f.IsOpen()); + EXPECT_TRUE(f.IsOpen()); + + std::string test = "This is a test!\n"; + EXPECT_TRUE(f.Write(test.c_str(), test.size())); + EXPECT_TRUE(f.IsOpen()); + EXPECT_FALSE(f.Failed()); + + f.Close(); + EXPECT_FALSE(f.IsOpen()); + EXPECT_FALSE(f.Failed()); +} +TEST(FileUtlTest, WorkingWithDevNull) +{ + TestDevNullFileFd(FileFd::WriteOnly | FileFd::Create); + TestDevNullFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Empty); + TestDevNullFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive); + TestDevNullFileFd(FileFd::WriteOnly | FileFd::Atomic); + TestDevNullFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Atomic); + // short-hands for ReadWrite with these modes + TestDevNullFileFd(FileFd::WriteEmpty); + TestDevNullFileFd(FileFd::WriteAny); + TestDevNullFileFd(FileFd::WriteTemp); + TestDevNullFileFd(FileFd::WriteAtomic); +} +constexpr char const * const TESTSTRING = "This is a test"; +static void TestFailingAtomicKeepsFile(char const * const label, std::string const &filename) +{ + SCOPED_TRACE(label); + EXPECT_TRUE(FileExists(filename)); + FileFd fd; + EXPECT_TRUE(fd.Open(filename, FileFd::ReadOnly)); + char buffer[50]; + EXPECT_NE(nullptr, fd.ReadLine(buffer, sizeof(buffer))); + EXPECT_STREQ(TESTSTRING, buffer); +} +TEST(FileUtlTest, FailingAtomic) +{ + FileFd fd; + std::string filename; + createTemporaryFile("failingatomic", fd, &filename, TESTSTRING); + TestFailingAtomicKeepsFile("init", filename); + + FileFd f; + EXPECT_TRUE(f.Open(filename, FileFd::ReadWrite | FileFd::Atomic)); + f.EraseOnFailure(); + EXPECT_FALSE(f.Failed()); + EXPECT_TRUE(f.IsOpen()); + TestFailingAtomicKeepsFile("before-fail", filename); + EXPECT_TRUE(f.Write("Bad file write", 10)); + f.OpFail(); + EXPECT_TRUE(f.Failed()); + TestFailingAtomicKeepsFile("after-fail", filename); + EXPECT_TRUE(f.Close()); + TestFailingAtomicKeepsFile("closed", filename); + + if (filename.empty() == false) + unlink(filename.c_str()); +}