TEST_F(TestFileCache, WriteAndReadBack) { // Set up something for FileCache to read in. char data_fn[] = "/tmp/hhvm_unit_test-testdata.XXXXXX"; int data_fd = mkstemp(data_fn); ASSERT_GT(data_fd, 0); FILE* f = fdopen(data_fd, "w"); ASSERT_TRUE(f != nullptr); fprintf(f, "%s", kTestData); fclose(f); // Set up a cache and put this data file in it. FileCache fc; fc.write("_unit_test_one_", data_fn); fc.write("_unit_test_two_"); fc.write("/__invalid__/path/with/directories"); std::string temp_dir; ASSERT_TRUE(makeTempDir(&temp_dir)); std::string cache_fn(temp_dir); cache_fn.append("/cache.dump"); // Flush to disk. fc.save(cache_fn.c_str()); // Read back into another cache. FileCache fc2; fc2.loadMmap(cache_fn.c_str()); EXPECT_TRUE(fc2.fileExists("_unit_test_one_")); int read_len; bool compressed = false; const char* read_data = fc2.read("_unit_test_one_", read_len, compressed); EXPECT_STREQ(kTestData, read_data); EXPECT_EQ(fc2.fileSize("_unit_test_one_", false), strlen(kTestData)); EXPECT_TRUE(fc2.fileExists("_unit_test_two_")); EXPECT_FALSE(fc2.fileExists("_unit_test_three_")); EXPECT_TRUE(fc2.dirExists("/__invalid__")); EXPECT_TRUE(fc2.dirExists("/__invalid__/path")); EXPECT_TRUE(fc2.dirExists("/__invalid__/path/with")); EXPECT_TRUE(fc2.fileExists("/__invalid__/path/with/directories")); // -1 is a magic value... here it means "it's a PHP file"... EXPECT_EQ(fc2.fileSize("unit_test_two_", false), -1); // ... and here it means "this thing does not exist". EXPECT_EQ(fc2.fileSize("unit_test_three_", false), -1); fc2.dump(); // Clean up the mess. ASSERT_EQ(unlink(cache_fn.c_str()), 0); ASSERT_EQ(rmdir(temp_dir.c_str()), 0); ASSERT_EQ(unlink(data_fn), 0); }
// As above, but using loadMmap instead (which doesn't do on-demand). TEST_F(TestFileCache, HighlyCompressibleDataMmapOLD) { FileCache::UseNewCache = false; char data_fn[] = "/tmp/hhvm_unit_test-testdata.XXXXXX"; int data_fd = mkstemp(data_fn); ASSERT_GT(data_fd, 0); FILE* f = fdopen(data_fd, "w"); ASSERT_TRUE(f != nullptr); string test_path = "/path/to/data"; string test_data; for (int i = 0; i < 10; ++i) { test_data.append("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); } fprintf(f, "%s", test_data.c_str()); fclose(f); FileCache fc; fc.write(test_path.c_str(), data_fn); // Flush to disk. char cache_fn[] = "/tmp/hhvm_unit_test.cache.XXXXXX"; close(mkstemp(cache_fn)); fc.save(cache_fn); // Read back into another cache (onDemandUncompress is not an option). FileCache fc2; fc2.loadMmap(cache_fn, 1); fc2.dump(); ASSERT_TRUE(fc2.fileExists(test_path.c_str())); int read_len; bool compressed = false; // "I want uncompressed data" const char* read_data = fc2.read(test_path.c_str(), read_len, compressed); // FileCache::read() takes compressed as a non-const reference (!) // and changes the value according to what it found... // This means "you just read a blob of compressed data"... EXPECT_TRUE(compressed); // ... so these can't match. EXPECT_NE(test_data, read_data); EXPECT_NE(test_data.length(), read_len); // But this always gets the uncompressed size no matter what. EXPECT_EQ(test_data.length(), fc2.fileSize(test_path.c_str(), false)); // So now let's actually ask for compressed data this time. compressed = true; read_data = fc2.read(test_path.c_str(), read_len, compressed); // Same conditions should hold. EXPECT_TRUE(compressed); EXPECT_NE(test_data, read_data); EXPECT_EQ(test_data.length(), fc2.fileSize(test_path.c_str(), false)); // Clean up the mess. ASSERT_EQ(unlink(cache_fn), 0); ASSERT_EQ(unlink(data_fn), 0); }
TEST_F(TestFileCache, HighlyCompressibleData) { char data_fn[] = "/tmp/hhvm_unit_test-testdata.XXXXXX"; int data_fd = mkstemp(data_fn); ASSERT_GT(data_fd, 0); FILE* f = fdopen(data_fd, "w"); ASSERT_TRUE(f != nullptr); std::string test_path = "/path/to/data"; std::string test_data; for (int i = 0; i < 10; ++i) { test_data.append("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); } fprintf(f, "%s", test_data.c_str()); fclose(f); FileCache fc; fc.write(test_path.c_str(), data_fn); // Flush to disk. std::string temp_dir; ASSERT_TRUE(makeTempDir(&temp_dir)); std::string cache_fn(temp_dir); cache_fn.append("/cache.dump"); fc.save(cache_fn.c_str()); // Read back into another cache. int read_len; bool compressed; const char* read_data; FileCache fc3; fc3.loadMmap(cache_fn.c_str()); fc3.dump(); ASSERT_TRUE(fc3.fileExists(test_path.c_str())); // Ask for uncompressed data (a holdover from the original API). compressed = false; read_data = fc3.read(test_path.c_str(), read_len, compressed); // FileCache::read() takes compressed as a non-const reference (!) // and changes the value according to what it found... // ... so this means "I just gave you compressed data". EXPECT_TRUE(compressed); // ... so these can't match. EXPECT_NE(test_data, read_data); EXPECT_NE(test_data.length(), read_len); // But this always gets the uncompressed size no matter what. EXPECT_EQ(test_data.length(), fc3.fileSize(test_path.c_str(), false)); // So now let's actually ask for compressed data this time. compressed = true; read_data = fc3.read(test_path.c_str(), read_len, compressed); // Same conditions should hold. EXPECT_TRUE(compressed); EXPECT_NE(test_data, read_data); EXPECT_EQ(test_data.length(), fc3.fileSize(test_path.c_str(), false)); // Clean up the mess. ASSERT_EQ(unlink(cache_fn.c_str()), 0); ASSERT_EQ(rmdir(temp_dir.c_str()), 0); ASSERT_EQ(unlink(data_fn), 0); }
TEST_F(TestFileCache, WriteAndReadBackOLD) { FileCache::UseNewCache = false; // Set up something for FileCache to read in. char data_fn[] = "/tmp/hhvm_unit_test-testdata.XXXXXX"; int data_fd = mkstemp(data_fn); ASSERT_GT(data_fd, 0); FILE* f = fdopen(data_fd, "w"); ASSERT_TRUE(f != nullptr); fprintf(f, "%s", kTestData); fclose(f); // Set up a cache and put this data file in it. FileCache fc; fc.write("_unit_test_one_", data_fn); fc.write("_unit_test_two_", false); fc.write("/__invalid__/path/with/directories", true); // Flush to disk. char cache_fn[] = "/tmp/hhvm_unit_test.cache.XXXXXX"; close(mkstemp(cache_fn)); fc.save(cache_fn); // Sniff around the on-disk temp file. FileCache ondisk; EXPECT_EQ(ondisk.getVersion(cache_fn), 1); // Read back into another cache. FileCache fc2; fc2.load(cache_fn, false, 1); EXPECT_TRUE(fc2.fileExists("_unit_test_one_")); int read_len; bool compressed = false; const char* read_data = fc2.read("_unit_test_one_", read_len, compressed); EXPECT_STREQ(kTestData, read_data); EXPECT_EQ(fc2.fileSize("_unit_test_one_", false), strlen(kTestData)); EXPECT_TRUE(fc2.fileExists("_unit_test_two_")); EXPECT_FALSE(fc2.fileExists("_unit_test_three_")); EXPECT_TRUE(fc2.dirExists("/__invalid__")); EXPECT_TRUE(fc2.dirExists("/__invalid__/path")); EXPECT_TRUE(fc2.dirExists("/__invalid__/path/with")); EXPECT_TRUE(fc2.fileExists("/__invalid__/path/with/directories")); // -1 is a magic value... here it means "it's a PHP file"... EXPECT_EQ(fc2.fileSize("unit_test_two_", false), -1); // ... and here it means "this thing does not exist". EXPECT_EQ(fc2.fileSize("unit_test_three_", false), -1); fc2.dump(); // Clean up the mess. ASSERT_EQ(unlink(cache_fn), 0); ASSERT_EQ(unlink(data_fn), 0); }