bool TestRunner::truncateTest( IDBDataFile::Types filetype ) { logMsg( INFO, "truncateTest" ); reset(); m_file = IDBDataFile::open(filetype, m_fname.c_str(), "a", m_open_opts); if( !m_file ) { ostringstream errstr; errstr << "Unable to open " << m_fname << " for writing"; logMsg( ERROR, errstr.str() ); return false; } // choose a random block to truncate at struct drand48_data d48data; srand48_r(0xdeadbeef, &d48data); long int blk_num; lrand48_r( &d48data, &blk_num); blk_num = blk_num % m_opts.numblocks; // always leave at least one block if( blk_num == 0 ) blk_num = 1; int rc = m_file->truncate(blk_num * BLK_SIZE); if( (filetype != IDBDataFile::HDFS) && rc) { logMsg( ERROR, "truncate failed!" ); return false; } else if ( (filetype == IDBDataFile::HDFS) && !rc ) { logMsg( ERROR, "truncate is supposed to fail for HDFS files!" ); return false; } else if( (filetype == IDBDataFile::HDFS) ) { // this is the "success" case for HDFS we didn't expect to truncate so reset blk_num blk_num = m_opts.numblocks; } off64_t fsize = m_file->size(); if( fsize != (off64_t) (blk_num * BLK_SIZE)) { ostringstream errstr; errstr << "wrong file size after truncate, " << fsize << " != " << blk_num*BLK_SIZE; logMsg( ERROR, errstr.str() ); return false; } return true; }
bool TestRunner::hdfsRdwrExhaustTest() { // this is going to be a self-contained test that attempts to test // all logic inherent in HdfsRdwr // choose a new filename that is specific to our thread ostringstream oss; // embed pid so that this is a new directory path oss << "/tmp/hdfsrdwr-" << getpid() << "-" << m_id; string newpath = oss.str(); // open a file with arbitrarily small buffer IDBDataFile* file = IDBDataFile::open(IDBDataFile::HDFS, newpath.c_str(), "r+", 0, 8); assert( file ); // check various empty file conditions assert( file->size() == 0 ); assert( file->tell() == 0 ); assert( file->seek(-1, SEEK_CUR) == -1); assert( file->seek(0, SEEK_SET) == 0); unsigned char buf[4]; assert( file->read(buf, 4) == 0); // write some data buf[0] = 0xde; buf[1] = 0xad; buf[2] = 0xbe; buf[3] = 0xef; assert( file->write(buf, 4) == 4); assert( file->size() == 4 ); assert( file->tell() == 4 ); assert( file->truncate(-1) == -1 ); // now make file empty again assert( file->truncate(0) == 0 ); assert( file->size() == 0 ); assert( file->seek(0, SEEK_SET) == 0); assert( file->tell() == 0 ); assert( file->read(buf, 4) == 0); // write data again, this time exactly up to allocated size assert( file->write(buf, 4) == 4); assert( file->write(buf, 4) == 4); assert( file->size() == 8 ); assert( file->tell() == 8 ); // truncate back to 4 assert( file->truncate(4) == 0 ); assert( file->size() == 4 ); assert( file->seek(4, SEEK_SET) == 0); assert( file->tell() == 4 ); // now trigger a buffer reallocation assert( file->write(buf, 4) == 4); assert( file->write(buf, 4) == 4); assert( file->size() == 12 ); // now delete and close. delete file; // check the file size through the file system IDBFileSystem& fs = IDBFileSystem::getFs( IDBDataFile::HDFS ); assert( fs.size( newpath.c_str() ) == 12); // open again - the file is bigger than the default buffer so it triggers alternate // logic in the constructor file = IDBDataFile::open(IDBDataFile::HDFS, newpath.c_str(), "r+", 0, 8); assert( file ); assert( file->size() == 12); unsigned char newbuf[4]; assert( file->pread(newbuf, 4, 4) == 4); assert( newbuf[0] == 0xde && newbuf[1] == 0xad && newbuf[2] == 0xbe &&newbuf[3] == 0xef); delete file; fs.remove(newpath.c_str()); return true; }