greenplumn CFileTest 源码
greenplumn CFileTest 代码
文件路径:/src/backend/gporca/libgpos/server/src/unittest/gpos/io/CFileTest.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 EMC Corp.
//
// @filename:
// CFileTest.cpp
//
// @doc:
// Tests for CFileWriter and CFileReader
//---------------------------------------------------------------------------
#include "unittest/gpos/io/CFileTest.h"
#include "gpos/assert.h"
#include "gpos/error/CMessage.h"
#include "gpos/io/CFileReader.h"
#include "gpos/io/CFileWriter.h"
#include "gpos/io/ioutils.h"
#include "gpos/string/CStringStatic.h"
#include "gpos/task/CAutoTraceFlag.h"
#include "gpos/test/CUnittest.h"
using namespace gpos;
//---------------------------------------------------------------------------
// @function:
// CFileTest::EresUnittest
//
// @doc:
// Driver for unittests
//---------------------------------------------------------------------------
GPOS_RESULT
CFileTest::EresUnittest()
{
CUnittest rgut[] = {
GPOS_UNITTEST_FUNC(CFileTest::EresUnittest_Invalid),
GPOS_UNITTEST_FUNC(CFileTest::EresUnittest_FileContent),
GPOS_UNITTEST_FUNC(CFileTest::EresUnittest_InconsistentSize),
};
return CUnittest::EresExecute(rgut, GPOS_ARRAY_SIZE(rgut));
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::EresUnittest_Invalid
//
// @doc:
// Test for open files with invalid operations
//
//---------------------------------------------------------------------------
GPOS_RESULT
CFileTest::EresUnittest_Invalid()
{
CHAR szTmpDir[GPOS_FILE_NAME_BUF_SIZE];
CHAR szTmpFile[GPOS_FILE_NAME_BUF_SIZE];
const ULONG ulWrPerms = S_IWUSR | S_IRGRP | S_IROTH;
const ULONG ulRdPerms = S_IRUSR | S_IRGRP | S_IROTH;
// make a unique temporary file name
Unittest_MkTmpFile(szTmpDir, szTmpFile);
GPOS_TRY
{
// open a nonexistent file by CFileReader,
// it will catch an exception
CFileReader rd1;
Unittest_CheckError(&rd1, &CFileReader::Open, (const CHAR *) szTmpFile,
ulRdPerms, CException::ExmiIOError);
// create, or truncate the file only permit to write
CFileWriter wr;
wr.Open(szTmpFile, ulWrPerms);
// close file
wr.Close();
// open a write only file by CFileReader,
// it will catch an exception
CFileReader rd2;
Unittest_CheckError(&rd2, &CFileReader::Open, (const CHAR *) szTmpFile,
ulRdPerms, CException::ExmiIOError);
}
GPOS_CATCH_EX(ex)
{
// delete tmp file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
GPOS_RETHROW(ex);
}
GPOS_CATCH_END;
// delete tmp file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::EresUnittest_FileContent
//
// @doc:
// Test for write data, and read the written data
//
//---------------------------------------------------------------------------
GPOS_RESULT
CFileTest::EresUnittest_FileContent()
{
CHAR szTmpDir[GPOS_FILE_NAME_BUF_SIZE];
CHAR szTmpFile[GPOS_FILE_NAME_BUF_SIZE];
const ULONG ulWrPerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
const ULONG ulRdPerms = S_IRUSR | S_IRGRP | S_IROTH;
const CHAR szData[] = "Test file content for CFileTest_file\n";
const INT iLineNum = 100;
const ULONG ulLineLength = GPOS_ARRAY_SIZE(szData);
CFileReader rd;
CFileWriterInternal wr;
// make a unique temporary file name
Unittest_MkTmpFile(szTmpDir, szTmpFile);
GPOS_TRY
{
// open file for writing by CFileWriter
wr.Open(szTmpFile, ulWrPerms);
// write file line by line
for (INT i = 0; i < iLineNum; i++)
{
wr.Write((BYTE *) szData, ulLineLength);
}
// test file size
GPOS_ASSERT((wr.FileSize() == (ulLineLength * iLineNum)) &&
(wr.UllSizeInternal() == wr.FileSize()));
// close file
wr.Close();
// read data written to file above line by line
rd.Open(szTmpFile, ulRdPerms);
CHAR szRdBuf[ulLineLength];
CHAR szRdData[ulLineLength];
#ifdef GPOS_DEBUG
ULONG_PTR ulpRdLen = 0;
#endif // GPOS_DEBUG
CStringStatic strRdData(szRdData, GPOS_ARRAY_SIZE(szRdData));
// read file content line by line,
// and test if it is equal to what is written
for (INT i = 0; i < iLineNum; i++)
{
#ifdef GPOS_DEBUG
ulpRdLen = rd.ReadBytesToBuffer((BYTE *) szRdBuf, ulLineLength);
#endif // GPOS_DEBUG
strRdData.AppendBuffer((const CHAR *) szRdBuf);
GPOS_ASSERT(strRdData.Equals((CHAR *) szData));
GPOS_ASSERT(ulpRdLen == ulLineLength);
strRdData.Reset();
}
GPOS_ASSERT(rd.FileReadSize() == (ulLineLength * iLineNum));
// when the EOF is reached, read again will return zero
GPOS_ASSERT(0 == rd.ReadBytesToBuffer((BYTE *) szRdBuf, ulLineLength));
//close file
rd.Close();
}
GPOS_CATCH_EX(ex)
{
// delete tmp file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
GPOS_RETHROW(ex);
}
GPOS_CATCH_END;
// delete temporary file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::EresUnittest_InconsistentSize
//
// @doc:
// Test for write and read file with given length
// not equal to buffer size
//
//---------------------------------------------------------------------------
GPOS_RESULT
CFileTest::EresUnittest_InconsistentSize()
{
CHAR szTmpDir[GPOS_FILE_NAME_BUF_SIZE];
CHAR szTmpFile[GPOS_FILE_NAME_BUF_SIZE];
// make a unique temporary file name
Unittest_MkTmpFile(szTmpDir, szTmpFile);
GPOS_TRY
{
// write data with inconsistent size with write buffer
Unittest_WriteInconsistentSize(szTmpFile);
// read data with inconsistent size with read buffer
Unittest_ReadInconsistentSize(szTmpFile);
}
GPOS_CATCH_EX(ex)
{
// delete tmp file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
GPOS_RETHROW(ex);
}
GPOS_CATCH_END;
// delete tmp file and dir
Unittest_DeleteTmpDir(szTmpDir, szTmpFile);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::Unittest_MkTmpFile
//
// @doc:
// Make a unique temporary dir and file
//
//---------------------------------------------------------------------------
void
CFileTest::Unittest_MkTmpFile(CHAR *szTmpDir, CHAR *szTmpFile)
{
GPOS_ASSERT(nullptr != szTmpDir);
GPOS_ASSERT(nullptr != szTmpFile);
CHAR szDir[] = "/tmp/CFileTest.XXXXXX";
const CHAR szFile[] = "/CFileTest_file.txt";
// create unique temporary directory name under /tmp
ioutils::CreateTempDir(szDir);
// copy the temporary directory name into szTmpDir
CStringStatic strTmpDir(szTmpDir, GPOS_FILE_NAME_BUF_SIZE, szDir);
CStringStatic strTmpFile(szTmpFile, GPOS_FILE_NAME_BUF_SIZE);
// unique temporary file name
strTmpFile.AppendFormat("%s%s", szDir, szFile);
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::Unittest_DeleteTmpDir
//
// @doc:
// Delete test files and directory
//
//---------------------------------------------------------------------------
void
CFileTest::Unittest_DeleteTmpDir(const CHAR *szDir, const CHAR *szFile)
{
GPOS_ASSERT(nullptr != szDir);
GPOS_ASSERT(nullptr != szFile);
if (ioutils::PathExists(szFile))
{
// delete temporary file
ioutils::Unlink(szFile);
}
if (ioutils::PathExists(szDir))
{
// delete temporary dir
ioutils::RemoveDir(szDir);
}
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::Unittest_CheckError
//
// @doc:
// Check error for write, read and open
//
//---------------------------------------------------------------------------
template <typename T, typename R, typename ARG1, typename ARG2>
void
CFileTest::Unittest_CheckError(T *pt, R (T::*pfunc)(ARG1, ARG2), ARG1 argFirst,
ARG2 argSec, CException::ExMinor exmi)
{
GPOS_ASSERT(nullptr != pt);
GPOS_ASSERT(nullptr != pfunc);
GPOS_TRY
{
(pt->*pfunc)(argFirst, argSec);
}
GPOS_CATCH_EX(ex)
{
if (!GPOS_MATCH_EX(ex, CException::ExmaSystem, (ULONG) exmi))
{
GPOS_RETHROW(ex);
}
GPOS_RESET_EX;
}
GPOS_CATCH_END;
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::Unittest_WriteInconsistentSize
//
// @doc:
// Write data with inconsistent size with write buffer
//
//---------------------------------------------------------------------------
void
CFileTest::Unittest_WriteInconsistentSize(const CHAR *szTmpFile)
{
GPOS_ASSERT(nullptr != szTmpFile);
const ULONG ulWdPerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
const BYTE szData[] = "Test file content for CFileTest_file\n";
const ULONG length = GPOS_ARRAY_SIZE(szData);
const ULONG ulShortfall = 5;
ULONG ulExpectSize = length - ulShortfall;
CFileWriterInternal wr;
wr.Open(szTmpFile, ulWdPerms);
// try to write data with length smaller than buffer size
wr.Write(szData, ulExpectSize);
CFileWriterInternal wrInternal;
// test file size
GPOS_ASSERT(ulExpectSize == wr.FileSize());
GPOS_ASSERT(ulExpectSize == wr.UllSizeInternal());
// try to write data with length larger than buffer size
ulExpectSize += (length + ulShortfall);
wr.Write(szData, length + ulShortfall);
// test file size
GPOS_ASSERT(ulExpectSize == wr.FileSize());
GPOS_ASSERT(wr.UllSizeInternal() == wr.FileSize());
wr.Close();
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::Unittest_ReadInconsistentSize
//
// @doc:
// Read data with inconsistent size with read buffer
//
//---------------------------------------------------------------------------
void
CFileTest::Unittest_ReadInconsistentSize(const CHAR *szTmpFile)
{
GPOS_ASSERT(nullptr != szTmpFile);
const ULONG ulWrPerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
const ULONG ulRdPerms = S_IRUSR | S_IRGRP | S_IROTH;
const BYTE szData[] = "Test file content for CFileTest_file\n";
const ULONG length = GPOS_ARRAY_SIZE(szData);
const ULONG ulShortfall = 5;
CFileWriter wr;
// truncate file to zero, an then write specific data for reading
wr.Open(szTmpFile, ulWrPerms);
// write two lines
wr.Write(szData, length);
wr.Write(szData, length);
// close file
wr.Close();
CFileReader rd;
// read buffer is oversized, because below we attempt to read past the end of
// the file
CHAR szRdBuf[length + ulShortfall];
// open file by reader
rd.Open(szTmpFile, ulRdPerms);
// read data with length smaller than read buffer size
#ifdef GPOS_DEBUG
ULONG_PTR ulpRdSize =
rd.ReadBytesToBuffer((BYTE *) szRdBuf, length - ulShortfall);
#endif // GPOS_DEBUG
szRdBuf[length - ulShortfall] = CHAR_EOS;
CHAR strBuf[length];
CStringStatic strRdData(strBuf, GPOS_ARRAY_SIZE(strBuf));
strRdData.AppendBuffer((const CHAR *) szRdBuf);
CHAR szExpectData[] = "Test file content for CFileTest_f";
#ifdef GPOS_DEBUG
ULONG ulExpectSize = length - ulShortfall;
#endif // GPOS_DEBUG
// test read data, and read size
GPOS_ASSERT(ulExpectSize == ulpRdSize);
GPOS_ASSERT(ulExpectSize == rd.FileReadSize());
BOOL fEqual GPOS_ASSERTS_ONLY = strRdData.Equals(szExpectData);
GPOS_ASSERT(fEqual);
// close file
rd.Close();
// try to read more data than the read buffer size
rd.Open(szTmpFile, ulRdPerms);
#ifdef GPOS_DEBUG
ulExpectSize = length + ulShortfall;
ulpRdSize = rd.ReadBytesToBuffer((BYTE *) szRdBuf, ulExpectSize);
#endif // GPOS_DEBUG
strRdData.Reset();
strRdData.AppendBuffer((const CHAR *) szRdBuf);
// test read size, and read data
GPOS_ASSERT(ulpRdSize == ulExpectSize);
GPOS_ASSERT(strRdData.Equals((const CHAR *) szData));
// close file
rd.Close();
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::CFileWriterInternal::UllSizeInternal
//
// @doc:
// Get file size by descriptor
//
//---------------------------------------------------------------------------
ULLONG
CFileTest::CFileWriterInternal::UllSizeInternal() const
{
return ioutils::FileSize(GetFileDescriptor());
}
//---------------------------------------------------------------------------
// @function:
// CFileTest::CFileWriterInternal:: ~CFileWriterInternal
//
// @doc:
// Dtor
//
//---------------------------------------------------------------------------
CFileTest::CFileWriterInternal::~CFileWriterInternal() = default;
// EOF
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦