Mini Shell
#include <TestSupport.h>
#include <ProcessManagement/Spawn.h>
#include <Utils/FileChangeChecker.h>
#include <SystemTools/SystemTime.h>
#include <unistd.h>
using namespace Passenger;
using namespace std;
namespace tut {
struct FileChangeCheckerTest: public TestBase {
FileChangeCheckerTest() {
}
~FileChangeCheckerTest() {
unlink("test.txt");
unlink("test2.txt");
SystemTime::release();
}
};
DEFINE_TEST_GROUP(FileChangeCheckerTest);
TEST_METHOD(1) {
// If a file is checked for the first time, then it
// returns whether the file exists.
FileChangeChecker checker(10);
touchFile("test.txt");
ensure(checker.changed("test.txt"));
ensure(!checker.changed("test2.txt"));
}
TEST_METHOD(2) {
// If a file is checked for the first time, and its
// directory is not accessible, then false is returned.
if (geteuid() != 0) {
// Root can read everything so no point in
// testing if we're running as root.
FileChangeChecker checker(10);
TempDir d("test.tmp");
touchFile("test.tmp/test.txt");
runShellCommand("chmod a= test.tmp");
ensure(!checker.changed("test.tmp/test.txt"));
// Should still be false.
ensure(!checker.changed("test.tmp/test.txt"));
// Now make it accessible again...
runShellCommand("chmod u=rwx test.tmp");
ensure(checker.changed("test.tmp/test.txt"));
}
}
TEST_METHOD(3) {
// File is not changed if it didn't exist and
// still doesn't exist.
FileChangeChecker checker(10);
checker.changed("test.txt");
ensure("test.txt not changed", !checker.changed("test.txt"));
checker.changed("test2.txt");
ensure("test2.txt not changed", !checker.changed("test2.txt"));
}
TEST_METHOD(4) {
// File is not changed if its ctime and mtime didn't change.
FileChangeChecker checker(10);
touchFile("test.txt");
checker.changed("test.txt");
ensure(!checker.changed("test.txt"));
touchFile("test2.txt");
checker.changed("test2.txt");
ensure(!checker.changed("test2.txt"));
}
TEST_METHOD(5) {
// File is changed if it didn't exist but has now been created.
FileChangeChecker checker(10);
checker.changed("test.txt");
checker.changed("test2.txt");
touchFile("test.txt");
touchFile("test2.txt");
ensure(checker.changed("test.txt"));
ensure(checker.changed("test2.txt"));
}
TEST_METHOD(6) {
// File is not changed if existed and has now been deleted.
FileChangeChecker checker(10);
touchFile("test.txt");
checker.changed("test.txt");
unlink("test.txt");
ensure("test.txt is not considered changed if it has been deleted",
!checker.changed("test.txt"));
touchFile("test2.txt");
checker.changed("test2.txt");
unlink("test2.txt");
ensure("test2.txt is not considered changed if it has been deleted",
!checker.changed("test2.txt"));
}
TEST_METHOD(7) {
// File is changed if its mtime changed.
FileChangeChecker checker(1);
touchFile("test.txt", 5);
checker.changed("test.txt");
touchFile("test.txt", 10);
ensure("First check: changed", checker.changed("test.txt"));
ensure("Second check: unchanged", !checker.changed("test.txt"));
touchFile("test2.txt", 5);
checker.changed("test2.txt");
touchFile("test2.txt", 10);
ensure("First check test2.txt: changed", checker.changed("test2.txt"));
ensure("Second check test2.txt: unchanged", !checker.changed("test2.txt"));
}
TEST_METHOD(8) {
// If a file is not checked for the first time and its
// information is still in the cache, but the directory
// in which the file lives is now suddenly inaccessible,
// then false is returned.
if (geteuid() != 0) {
// Root can read everything so no point in
// testing if we're running as root.
FileChangeChecker checker(10);
TempDir d("test.tmp");
touchFile("test.tmp/test.txt", 1);
checker.changed("test.tmp/test.txt");
touchFile("test.tmp/test.txt", 2);
runShellCommand("chmod a= test.tmp");
ensure("First check returns false", !checker.changed("test.tmp/test.txt"));
// Now make it accessible again...
runShellCommand("chmod u=rwx test.tmp");
ensure("Second check returns true", checker.changed("test.tmp/test.txt"));
}
}
TEST_METHOD(9) {
// Throttling works.
SystemTime::force(5);
FileChangeChecker checker(1);
checker.changed("test.txt", 3);
touchFile("test.txt");
ensure(!checker.changed("test.txt", 3));
SystemTime::force(6);
ensure(!checker.changed("test.txt", 3));
SystemTime::force(8);
ensure(checker.changed("test.txt", 3));
ensure(!checker.changed("test.txt", 3));
}
TEST_METHOD(10) {
// Test scenario involving multiple files.
FileChangeChecker checker(10);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
touchFile("test2.txt", 1);
ensure(!checker.changed("test.txt"));
ensure(checker.changed("test2.txt"));
ensure(!checker.changed("test3.txt"));
touchFile("test.txt", 2);
touchFile("test3.txt", 3);
ensure(checker.changed("test.txt"));
ensure(!checker.changed("test2.txt"));
ensure(checker.changed("test3.txt"));
}
TEST_METHOD(11) {
// Different filenames are treated as different files.
FileChangeChecker checker(10);
checker.changed("test.txt");
checker.changed("./test.txt");
touchFile("test.txt", 1);
ensure(checker.changed("test.txt"));
ensure(checker.changed("./test.txt"));
}
TEST_METHOD(12) {
if (geteuid() != 0) {
// Root can read everything so no point in
// testing if we're running as root.
FileChangeChecker checker(10);
TempDir d("test.tmp");
touchFile("test.tmp/test.txt", 1);
checker.changed("test.tmp/test.txt");
touchFile("test.tmp/test.txt", 2);
runShellCommand("chmod a= test.tmp");
ensure("(1)", !checker.changed("test.tmp/test.txt"));
runShellCommand("chmod u=rwx test.tmp");
ensure("(2)", checker.changed("test.tmp/test.txt"));
}
}
TEST_METHOD(13) {
// Size limitation works.
FileChangeChecker checker(2);
touchFile("test.txt", 1);
touchFile("test2.txt", 2);
touchFile("test3.txt", 3);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
// test.txt is now removed from the file list.
unlink("test.txt");
unlink("test2.txt");
unlink("test3.txt");
ensure("test2.txt is still in the file list", checker.knows("test2.txt"));
ensure("test2.txt is not considered changed", !checker.changed("test2.txt"));
ensure("test3.txt is still in the file list", checker.knows("test3.txt"));
ensure("test3.txt is not considered changed", !checker.changed("test3.txt"));
ensure("test.txt is removed from the file list", !checker.knows("test.txt"));
}
TEST_METHOD(14) {
// Increasing the file list size dynamically works.
FileChangeChecker checker(2);
touchFile("test.txt", 1);
touchFile("test2.txt", 2);
touchFile("test3.txt", 3);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
// test.txt is now removed from the file list.
checker.setMaxSize(3);
unlink("test.txt");
unlink("test2.txt");
unlink("test3.txt");
ensure("test.txt is removed from the file list", !checker.knows("test.txt"));
// The above changed() call should not remove test2.txt from the file list.
ensure("test2.txt is still in the file list", checker.knows("test2.txt"));
ensure("test3.txt is still in the file list", checker.knows("test3.txt"));
checker.changed("test.txt");
checker.changed("test4.txt");
ensure("test2.txt is removed from the file list, again", !checker.knows("test2.txt"));
}
TEST_METHOD(16) {
// Decreasing the file list size dynamically works, and will
// remove the oldest entries.
FileChangeChecker checker(4);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
checker.changed("test4.txt");
checker.setMaxSize(2);
ensure(!checker.knows("test.txt"));
ensure(!checker.knows("test2.txt"));
ensure(checker.knows("test3.txt"));
ensure(checker.knows("test4.txt"));
checker.changed("test.txt");
ensure(!checker.knows("test3.txt"));
}
TEST_METHOD(17) {
// An initial maxSize of 0 makes the file list's size unlimited.
FileChangeChecker checker(0);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
checker.changed("test4.txt");
ensure(checker.knows("test.txt"));
ensure(checker.knows("test2.txt"));
ensure(checker.knows("test3.txt"));
ensure(checker.knows("test4.txt"));
}
TEST_METHOD(18) {
// Dynamically setting the file list size to 0 makes
// the file list's size unlimited.
FileChangeChecker checker(2);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.setMaxSize(0);
checker.changed("test3.txt");
checker.changed("test4.txt");
ensure(checker.knows("test.txt"));
ensure(checker.knows("test2.txt"));
ensure(checker.knows("test3.txt"));
ensure(checker.knows("test4.txt"));
}
TEST_METHOD(19) {
// Changing the file list size dynamically from 0 to non-0 works;
// it removes the oldest entries, if necessary.
FileChangeChecker checker(0);
checker.changed("test.txt");
checker.changed("test2.txt");
checker.changed("test3.txt");
checker.changed("test4.txt");
checker.changed("test5.txt");
checker.setMaxSize(2);
ensure(!checker.knows("test.txt"));
ensure(!checker.knows("test2.txt"));
ensure(!checker.knows("test3.txt"));
ensure(checker.knows("test4.txt"));
ensure(checker.knows("test5.txt"));
}
}
Zerion Mini Shell 1.0