123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- #include "file.h"
- #include "fs.h"
- #include "tempfile.h"
- #include <library/cpp/testing/unittest/registar.h>
- #include <util/stream/file.h>
- #include <util/generic/yexception.h>
- class TFileTest: public TTestBase {
- UNIT_TEST_SUITE(TFileTest);
- UNIT_TEST(TestOpen);
- UNIT_TEST(TestOpenSync);
- UNIT_TEST(TestRW);
- UNIT_TEST(TestReWrite);
- UNIT_TEST(TestAppend);
- UNIT_TEST(TestLinkTo);
- UNIT_TEST(TestResize);
- UNIT_TEST(TestLocale);
- UNIT_TEST(TestFlush);
- UNIT_TEST(TestFlushSpecialFile);
- UNIT_TEST(TestRawRead);
- UNIT_TEST(TestRead);
- UNIT_TEST(TestRawPread);
- UNIT_TEST(TestPread);
- UNIT_TEST(TestCache);
- UNIT_TEST_SUITE_END();
- public:
- void TestOpen();
- void TestOpenSync();
- void TestRW();
- void TestLocale();
- void TestFlush();
- void TestFlushSpecialFile();
- void TestRawRead();
- void TestRead();
- void TestRawPread();
- void TestPread();
- void TestCache();
- inline void TestLinkTo() {
- TTempFile tmp1("tmp1");
- TTempFile tmp2("tmp2");
- {
- TFile f1(tmp1.Name(), OpenAlways | WrOnly);
- TFile f2(tmp2.Name(), OpenAlways | WrOnly);
- f1.LinkTo(f2);
- f1.Write("12345", 5);
- f2.Write("67890", 5);
- }
- UNIT_ASSERT_EQUAL(TUnbufferedFileInput(tmp2.Name()).ReadAll(), "1234567890");
- }
- inline void TestAppend() {
- TTempFile tmp("tmp");
- {
- TFile f(tmp.Name(), OpenAlways | WrOnly);
- f.Write("12345678", 8);
- }
- {
- TFile f(tmp.Name(), OpenAlways | WrOnly | ForAppend);
- f.Write("67", 2);
- f.Write("89", 2);
- }
- UNIT_ASSERT_EQUAL(TUnbufferedFileInput(tmp.Name()).ReadAll(), "123456786789");
- }
- inline void TestReWrite() {
- TTempFile tmp("tmp");
- {
- TFile f(tmp.Name(), OpenAlways | WrOnly);
- f.Write("12345678", 8);
- }
- {
- TFile f(tmp.Name(), OpenAlways | WrOnly);
- f.Write("6789", 4);
- }
- UNIT_ASSERT_EQUAL(TUnbufferedFileInput(tmp.Name()).ReadAll(), "67895678");
- }
- inline void TestResize() {
- TTempFile tmp("tmp");
- {
- TFile file(tmp.Name(), OpenAlways | WrOnly);
- file.Write("1234567", 7);
- file.Seek(3, sSet);
- file.Resize(5);
- UNIT_ASSERT_EQUAL(file.GetLength(), 5);
- UNIT_ASSERT_EQUAL(file.GetPosition(), 3);
- file.Resize(12);
- UNIT_ASSERT_EQUAL(file.GetLength(), 12);
- UNIT_ASSERT_EQUAL(file.GetPosition(), 3);
- }
- const TString data = TUnbufferedFileInput(tmp.Name()).ReadAll();
- UNIT_ASSERT_EQUAL(data.length(), 12);
- UNIT_ASSERT(data.StartsWith("12345"));
- }
- };
- UNIT_TEST_SUITE_REGISTRATION(TFileTest);
- void TFileTest::TestOpen() {
- TString res;
- TFile f1;
- try {
- TFile f2("f1.txt", OpenExisting);
- } catch (const yexception& e) {
- res = e.what();
- }
- UNIT_ASSERT(!res.empty());
- res.remove();
- try {
- TFile f2("f1.txt", OpenAlways);
- f1 = f2;
- } catch (const yexception& e) {
- res = e.what();
- }
- UNIT_ASSERT(res.empty());
- UNIT_ASSERT(f1.IsOpen());
- UNIT_ASSERT_VALUES_EQUAL(f1.GetName(), "f1.txt");
- UNIT_ASSERT_VALUES_EQUAL(f1.GetLength(), 0);
- try {
- TFile f2("f1.txt", CreateNew);
- } catch (const yexception& e) {
- res = e.what();
- }
- UNIT_ASSERT(!res.empty());
- res.remove();
- f1.Close();
- UNIT_ASSERT(unlink("f1.txt") == 0);
- }
- void TFileTest::TestOpenSync() {
- TFile f1("f1.txt", CreateNew | Sync);
- UNIT_ASSERT(f1.IsOpen());
- f1.Close();
- UNIT_ASSERT(!f1.IsOpen());
- UNIT_ASSERT(unlink("f1.txt") == 0);
- }
- void TFileTest::TestRW() {
- TFile f1("f1.txt", CreateNew);
- UNIT_ASSERT(f1.IsOpen());
- UNIT_ASSERT_VALUES_EQUAL(f1.GetName(), "f1.txt");
- UNIT_ASSERT_VALUES_EQUAL(f1.GetLength(), 0);
- ui32 d[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- f1.Write(&d, sizeof(ui32) * 10);
- UNIT_ASSERT_VALUES_EQUAL(f1.GetLength(), 40);
- UNIT_ASSERT_VALUES_EQUAL(f1.GetPosition(), 40);
- UNIT_ASSERT_VALUES_EQUAL(f1.Seek(12, sSet), 12);
- f1.Flush();
- ui32 v;
- f1.Load(&v, sizeof(v));
- UNIT_ASSERT_VALUES_EQUAL(v, 3u);
- UNIT_ASSERT_VALUES_EQUAL(f1.GetPosition(), 16);
- TFile f2 = f1;
- UNIT_ASSERT(f2.IsOpen());
- UNIT_ASSERT_VALUES_EQUAL(f2.GetName(), "f1.txt");
- UNIT_ASSERT_VALUES_EQUAL(f2.GetPosition(), 16);
- UNIT_ASSERT_VALUES_EQUAL(f2.GetLength(), 40);
- f2.Write(&v, sizeof(v));
- UNIT_ASSERT_VALUES_EQUAL(f1.GetPosition(), 20);
- UNIT_ASSERT_VALUES_EQUAL(f1.Seek(-4, sCur), 16);
- v = 0;
- f1.Load(&v, sizeof(v));
- UNIT_ASSERT_VALUES_EQUAL(v, 3u);
- f1.Close();
- UNIT_ASSERT(!f1.IsOpen());
- UNIT_ASSERT(!f2.IsOpen());
- UNIT_ASSERT(unlink("f1.txt") == 0);
- }
- #ifdef _unix_
- #include <locale.h>
- #endif
- void TFileTest::TestLocale() {
- #ifdef _unix_
- const char* loc = setlocale(LC_CTYPE, nullptr);
- setlocale(LC_CTYPE, "ru_RU.UTF-8");
- #endif
- TFile f("Имя.txt", CreateNew);
- UNIT_ASSERT(f.IsOpen());
- UNIT_ASSERT_VALUES_EQUAL(f.GetName(), "Имя.txt");
- UNIT_ASSERT_VALUES_EQUAL(f.GetLength(), 0);
- f.Close();
- UNIT_ASSERT(NFs::Remove("Имя.txt"));
- #ifdef _unix_
- setlocale(LC_CTYPE, loc);
- #endif
- }
- void TFileTest::TestFlush() {
- TTempFile tmp("tmp");
- {
- TFile f(tmp.Name(), OpenAlways | WrOnly);
- f.Flush();
- f.FlushData();
- f.Close();
- UNIT_ASSERT_EXCEPTION(f.Flush(), TFileError);
- UNIT_ASSERT_EXCEPTION(f.FlushData(), TFileError);
- }
- }
- void TFileTest::TestFlushSpecialFile() {
- #ifdef _unix_
- TFile devNull("/dev/null", WrOnly);
- devNull.FlushData();
- devNull.Flush();
- devNull.Close();
- #endif
- }
- void TFileTest::TestRawRead() {
- TTempFile tmp("tmp");
- {
- TFile file(tmp.Name(), OpenAlways | WrOnly);
- file.Write("1234567", 7);
- file.Flush();
- file.Close();
- }
- {
- TFile file(tmp.Name(), OpenExisting | RdOnly);
- char buf[7];
- i32 reallyRead = file.RawRead(buf, 7);
- Y_ENSURE(0 <= reallyRead && reallyRead <= 7);
- Y_ENSURE(TStringBuf(buf, reallyRead) == TStringBuf("1234567").Head(reallyRead));
- }
- }
- void TFileTest::TestRead() {
- TTempFile tmp("tmp");
- {
- TFile file(tmp.Name(), OpenAlways | WrOnly);
- file.Write("1234567", 7);
- file.Flush();
- file.Close();
- }
- {
- TFile file(tmp.Name(), OpenExisting | RdOnly);
- char buf[7];
- Y_ENSURE(file.Read(buf, 7) == 7);
- Y_ENSURE(TStringBuf(buf, 7) == "1234567");
- memset(buf, 0, sizeof(buf));
- file.Seek(0, sSet);
- Y_ENSURE(file.Read(buf, 123) == 7);
- Y_ENSURE(TStringBuf(buf, 7) == "1234567");
- }
- }
- void TFileTest::TestRawPread() {
- TTempFile tmp("tmp");
- {
- TFile file(tmp.Name(), OpenAlways | WrOnly);
- file.Write("1234567", 7);
- file.Flush();
- file.Close();
- }
- {
- TFile file(tmp.Name(), OpenExisting | RdOnly);
- char buf[7];
- i32 reallyRead = file.RawPread(buf, 3, 1);
- Y_ENSURE(0 <= reallyRead && reallyRead <= 3);
- Y_ENSURE(TStringBuf(buf, reallyRead) == TStringBuf("234").Head(reallyRead));
- memset(buf, 0, sizeof(buf));
- reallyRead = file.RawPread(buf, 2, 5);
- Y_ENSURE(0 <= reallyRead && reallyRead <= 2);
- Y_ENSURE(TStringBuf(buf, reallyRead) == TStringBuf("67").Head(reallyRead));
- }
- }
- void TFileTest::TestPread() {
- TTempFile tmp("tmp");
- {
- TFile file(tmp.Name(), OpenAlways | WrOnly);
- file.Write("1234567", 7);
- file.Flush();
- file.Close();
- }
- {
- TFile file(tmp.Name(), OpenExisting | RdOnly);
- char buf[7];
- Y_ENSURE(file.Pread(buf, 3, 1) == 3);
- Y_ENSURE(TStringBuf(buf, 3) == "234");
- memset(buf, 0, sizeof(buf));
- Y_ENSURE(file.Pread(buf, 2, 5) == 2);
- Y_ENSURE(TStringBuf(buf, 2) == "67");
- }
- }
- #ifdef _linux_
- #include <sys/statfs.h>
- #endif
- #ifndef TMPFS_MAGIC
- #define TMPFS_MAGIC 0x01021994
- #endif
- void TFileTest::TestCache(){
- #ifdef _linux_
- {// create file in /tmp, current dir could be tmpfs which does not support fadvise
- TFile file(MakeTempName("/tmp"), OpenAlways | Transient | RdWr | NoReadAhead);
- struct statfs fs;
- if (!fstatfs(file.GetHandle(), &fs) && fs.f_type == TMPFS_MAGIC) {
- return;
- }
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 0);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(0, 0), 0);
- file.Resize(7);
- file.PrefetchCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 7);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(3, 2), 2);
- file.FlushCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 7);
- file.EvictCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 0);
- file.PrefetchCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 7);
- file.Resize(12345);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 4096);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(4096, 0), 0);
- file.PrefetchCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 12345);
- file.FlushCache();
- file.EvictCache();
- UNIT_ASSERT_LE(file.CountCache(), 0);
- file.Resize(33333333);
- file.PrefetchCache(11111111, 11111111);
- UNIT_ASSERT_GE(file.CountCache(), 11111111);
- UNIT_ASSERT_LE(file.CountCache(0, 11111111), 1111111);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(11111111, 11111111), 11111111);
- UNIT_ASSERT_LE(file.CountCache(22222222, 11111111), 1111111);
- file.FlushCache(11111111, 11111111);
- UNIT_ASSERT_GE(file.CountCache(), 11111111);
- // first and last incomplete pages could stay in cache
- file.EvictCache(11111111, 11111111);
- UNIT_ASSERT_LT(file.CountCache(11111111, 11111111), 4096 * 2);
- file.EvictCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), 0);
- }
- #else
- {TFile file(MakeTempName(), OpenAlways | Transient | RdWr);
- file.Resize(12345);
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(), -1);
- file.PrefetchCache();
- file.FlushCache();
- file.EvictCache();
- UNIT_ASSERT_VALUES_EQUAL(file.CountCache(0, 12345), -1);
- }
- #endif
- }
- Y_UNIT_TEST_SUITE(TTestFileHandle) {
- Y_UNIT_TEST(MoveAssignment) {
- TTempFile tmp("tmp");
- {
- TFileHandle file1(tmp.Name(), OpenAlways | WrOnly);
- file1.Write("1", 1);
- TFileHandle file2;
- file2 = std::move(file1);
- Y_ENSURE(!file1.IsOpen());
- Y_ENSURE(file2.IsOpen());
- file2.Write("2", 1);
- }
- {
- TFileHandle file(tmp.Name(), OpenExisting | RdOnly);
- char buf[2];
- Y_ENSURE(file.Read(buf, 2) == 2);
- Y_ENSURE(TStringBuf(buf, 2) == "12");
- }
- }
- } // Y_UNIT_TEST_SUITE(TTestFileHandle)
- Y_UNIT_TEST_SUITE(TTestDecodeOpenMode) {
- Y_UNIT_TEST(It) {
- UNIT_ASSERT_VALUES_EQUAL("0", DecodeOpenMode(0));
- UNIT_ASSERT_VALUES_EQUAL("RdOnly", DecodeOpenMode(RdOnly));
- UNIT_ASSERT_VALUES_EQUAL("RdWr", DecodeOpenMode(RdWr));
- UNIT_ASSERT_VALUES_EQUAL("WrOnly|ForAppend", DecodeOpenMode(WrOnly | ForAppend));
- UNIT_ASSERT_VALUES_EQUAL("RdWr|CreateAlways|CreateNew|ForAppend|Transient|CloseOnExec|Temp|Sync|Direct|DirectAligned|Seq|NoReuse|NoReadAhead|AX|AR|AW|AWOther|0xF8888000", DecodeOpenMode(0xFFFFFFFF));
- }
- } // Y_UNIT_TEST_SUITE(TTestDecodeOpenMode)
|