add error handling test
This commit is contained in:
@@ -0,0 +1,475 @@
|
||||
#include "global.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "RageLog.h"
|
||||
#include "RageFile.h"
|
||||
#include "RageFileDriver.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageUtil_FileDB.h"
|
||||
#include "test_misc.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
static CString g_TestFile;
|
||||
static CString g_TestFilename;
|
||||
static int g_BytesUntilError = 6;
|
||||
|
||||
/*
|
||||
* This driver
|
||||
* 1: reads from a single "file", contained in g_TestFile, with fn g_TestFilename;
|
||||
* 2: writes to the bit bucket,
|
||||
* 3: triggers an error when g_BytesUntilError reaches 0.
|
||||
*/
|
||||
class RageFileDriverTest: public RageFileDriver
|
||||
{
|
||||
public:
|
||||
RageFileDriverTest( CString root );
|
||||
|
||||
RageFileObj *Open( const CString &path, int mode, RageFile &p, int &err );
|
||||
bool Remove( const CString &sPath ) { return false; }
|
||||
bool Ready() { return true; }
|
||||
|
||||
private:
|
||||
CString root;
|
||||
};
|
||||
|
||||
static struct FileDriverEntry_TEST: public FileDriverEntry
|
||||
{
|
||||
FileDriverEntry_TEST(): FileDriverEntry( "TEST" ) { }
|
||||
RageFileDriver *Create( CString Root ) const { return new RageFileDriverTest( Root ); }
|
||||
} const g_RegisterDriver;
|
||||
|
||||
class TestFilenameDB: public FilenameDB
|
||||
{
|
||||
protected:
|
||||
virtual void PopulateFileSet( FileSet &fs, const CString &sPath )
|
||||
{
|
||||
if( sPath != "." )
|
||||
return;
|
||||
if( g_TestFile == "" )
|
||||
return;
|
||||
|
||||
fs.files.clear();
|
||||
|
||||
File f;
|
||||
f.SetName( g_TestFilename );
|
||||
f.dir = false;
|
||||
f.size = g_TestFile.size();
|
||||
f.hash = GetHashForString( g_TestFile );
|
||||
fs.files.insert(f);
|
||||
}
|
||||
|
||||
CString root;
|
||||
|
||||
public:
|
||||
TestFilenameDB( CString root_ )
|
||||
{
|
||||
root = root_;
|
||||
if( root == "./" )
|
||||
root = "";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class RageFileObjTest: public RageFileObj
|
||||
{
|
||||
public:
|
||||
RageFileObjTest( const CString &path, RageFile &p );
|
||||
int Read(void *buffer, size_t bytes);
|
||||
int Write(const void *buffer, size_t bytes);
|
||||
int Flush() { return 0; }
|
||||
void Rewind() { pos = 0; }
|
||||
int Seek( int offset )
|
||||
{
|
||||
pos = min( offset, (int) g_TestFile.size() );
|
||||
return pos;
|
||||
}
|
||||
RageFileObj *Copy( RageFile &p ) const;
|
||||
CString GetDisplayPath() const { return path; }
|
||||
int GetFileSize() { return g_TestFile.size(); }
|
||||
|
||||
private:
|
||||
CString path; /* for Copy */
|
||||
int pos;
|
||||
};
|
||||
|
||||
|
||||
RageFileDriverTest::RageFileDriverTest( CString root_ ):
|
||||
RageFileDriver( new TestFilenameDB(root_) ),
|
||||
root(root_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RageFileObj *RageFileDriverTest::Open( const CString &path, int mode, RageFile &p, int &err )
|
||||
{
|
||||
if( path != g_TestFilename )
|
||||
{
|
||||
err = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new RageFileObjTest( root + path, p );
|
||||
}
|
||||
|
||||
RageFileObj *RageFileObjTest::Copy( RageFile &p ) const
|
||||
{
|
||||
RageFileObj *ret = new RageFileObjTest( path, p );
|
||||
|
||||
ret->Seek( parent.Tell() );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const unsigned int BUFSIZE = 1024*64;
|
||||
RageFileObjTest::RageFileObjTest( const CString &path_, RageFile &p ):
|
||||
RageFileObj( p )
|
||||
{
|
||||
path = path_;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
int RageFileObjTest::Read( void *buf, size_t bytes )
|
||||
{
|
||||
bytes = min( bytes, g_TestFile.size()-pos );
|
||||
|
||||
if( g_BytesUntilError != -1 )
|
||||
{
|
||||
if( (int) bytes > g_BytesUntilError )
|
||||
{
|
||||
SetError( "Fake error" );
|
||||
g_BytesUntilError = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_BytesUntilError -= min( g_BytesUntilError, (int) bytes );
|
||||
}
|
||||
|
||||
memcpy( buf, g_TestFile.data()+pos, bytes );
|
||||
pos += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int RageFileObjTest::Write( const void *buf, size_t bytes )
|
||||
{
|
||||
if( g_BytesUntilError != -1 )
|
||||
{
|
||||
if( (int) bytes > g_BytesUntilError )
|
||||
{
|
||||
SetError( "Fake error" );
|
||||
g_BytesUntilError = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_BytesUntilError -= min( g_BytesUntilError, (int) bytes );
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#define Fail(s...) \
|
||||
{ \
|
||||
LOG->Warn( s ); break; \
|
||||
}
|
||||
|
||||
void SanityCheck()
|
||||
{
|
||||
/* Read sanity check. */
|
||||
do {
|
||||
g_TestFile = "hello";
|
||||
g_TestFilename = "file";
|
||||
|
||||
RageFile test;
|
||||
if( !test.Open("test/file", RageFile::READ ) )
|
||||
Fail( "Sanity check Open() failed: %s", test.GetError().c_str() );
|
||||
|
||||
CString str;
|
||||
int got = test.GetLine( str );
|
||||
if( got <= 0 )
|
||||
Fail( "Sanity check GetLine(): got %i", got );
|
||||
|
||||
if( str != "hello" )
|
||||
Fail( "Sanity check Read(): expected \"hello\", got \"%s\"", str.c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Read error sanity check. */
|
||||
do {
|
||||
g_TestFile = "hello world";
|
||||
g_TestFilename = "file";
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
RageFile test;
|
||||
if( !test.Open("test/file", RageFile::READ ) )
|
||||
Fail( "Sanity check 2 Open() failed: %s", test.GetError().c_str() );
|
||||
|
||||
CString str;
|
||||
int got = test.Read( str, 5 );
|
||||
if( got != 5 )
|
||||
Fail( "Sanity check 2 Read(): got %i", got );
|
||||
|
||||
if( str != "hello" )
|
||||
Fail( "Sanity check 2 Read(): expected \"hello\", got \"%s\"", str.c_str() );
|
||||
|
||||
got = test.Read( str, 5 );
|
||||
if( got != -1 )
|
||||
Fail( "Sanity check 2 GetLine(): expected -1, got %i", got );
|
||||
|
||||
if( test.GetError() != "Fake error" )
|
||||
Fail( "Sanity check 2 GetError(): expected \"Fake error\", got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Write error sanity check. */
|
||||
do {
|
||||
g_TestFilename = "file";
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
RageFile test;
|
||||
if( !test.Open("test/file", RageFile::WRITE ) )
|
||||
Fail( "Write error check Open() failed: %s", test.GetError().c_str() );
|
||||
|
||||
int wrote = test.Write( "test", 4 );
|
||||
if( wrote != 4 )
|
||||
Fail( "Write error check Write(): wrote %i", wrote );
|
||||
|
||||
wrote = test.Write( "ing", 3 );
|
||||
if( wrote != -1 )
|
||||
Fail( "Write error check Write(): expected -1, got %i", wrote );
|
||||
|
||||
if( test.GetError() != "Fake error" )
|
||||
Fail( "Write error check GetError(): expected \"Fake error\", got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
}
|
||||
|
||||
#include "IniFile.h"
|
||||
void IniTest()
|
||||
{
|
||||
g_TestFilename = "file";
|
||||
|
||||
/* Read check. */
|
||||
do {
|
||||
g_TestFile =
|
||||
"[test]\n"
|
||||
"abc=def";
|
||||
|
||||
g_BytesUntilError = -1;
|
||||
|
||||
IniFile test;
|
||||
if( !test.ReadFile( "test/file" ) )
|
||||
Fail( "INI: ReadFile failed: %s", test.GetError().c_str() );
|
||||
|
||||
CString sStr;
|
||||
if( !test.GetValue( "test", "abc", sStr ) )
|
||||
Fail( "INI: GetValue failed" );
|
||||
if( sStr != "def" )
|
||||
Fail( "INI: GetValue failed: expected \"def\", got \"%s\"", sStr.c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Read error check. */
|
||||
do {
|
||||
g_TestFile =
|
||||
"[test]\n"
|
||||
"abc=def";
|
||||
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
IniFile test;
|
||||
if( test.ReadFile( "test/file" ) )
|
||||
Fail( "INI: ReadFile should have failed" );
|
||||
|
||||
if( test.GetError() != "Fake error" )
|
||||
Fail( "INI: ReadFile error check: wrong error return: got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Write error check. */
|
||||
do {
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
IniFile test;
|
||||
test.SetValue( "foo", "bar", "baz" );
|
||||
if( test.WriteFile( "test/file" ) )
|
||||
Fail( "INI: WriteFile should have failed" );
|
||||
|
||||
if( test.GetError() != "Fake error" )
|
||||
Fail( "INI: ReadFile error check: wrong error return: got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
}
|
||||
|
||||
#include "MsdFile.h"
|
||||
void MsdTest()
|
||||
{
|
||||
g_TestFilename = "file";
|
||||
|
||||
/* Read check. */
|
||||
do {
|
||||
g_TestFile = "#FOO;";
|
||||
|
||||
g_BytesUntilError = -1;
|
||||
|
||||
MsdFile test;
|
||||
if( !test.ReadFile( "test/file" ) )
|
||||
Fail( "MSD: ReadFile failed: %s", test.GetError().c_str() );
|
||||
|
||||
if( test.GetNumValues() != 1 )
|
||||
Fail( "MSD: GetNumValues: expected 1, got %i", test.GetNumValues() );
|
||||
if( test.GetNumParams(0) != 1 )
|
||||
Fail( "MSD: GetNumParams(0): expected 1, got %i", test.GetNumParams(0) );
|
||||
CString sStr = test.GetValue(0)[0];
|
||||
if( sStr != "FOO" )
|
||||
Fail( "MSD: GetValue failed: expected \"FOO\", got \"%s\"", sStr.c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Read error check. */
|
||||
do {
|
||||
g_TestFile = "#FOO:BAR:BAZ;";
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
MsdFile test;
|
||||
if( test.ReadFile( "test/file" ) )
|
||||
Fail( "MSD: ReadFile should have failed" );
|
||||
|
||||
if( test.GetError() != "Fake error" )
|
||||
Fail( "MSD: ReadFile error check: wrong error return: got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
}
|
||||
|
||||
#include "XmlFile.h"
|
||||
void XmlTest()
|
||||
{
|
||||
g_TestFilename = "file";
|
||||
|
||||
/* Read check. */
|
||||
do {
|
||||
g_TestFile = "<foo><bar></bar></foo>";
|
||||
|
||||
g_BytesUntilError = -1;
|
||||
|
||||
XNode test;
|
||||
PARSEINFO pi;
|
||||
if( !test.LoadFromFile( "test/file", &pi ) )
|
||||
Fail( "XML: LoadFromFile failed: %s", pi.error_string.c_str() );
|
||||
|
||||
if( test.GetChild( "bar" ) == NULL )
|
||||
Fail( "XML: couldn't find node" );
|
||||
} while(false);
|
||||
|
||||
/* Read error check. */
|
||||
do {
|
||||
g_TestFile = "<foo><bar></bar></foo>";
|
||||
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
XNode test;
|
||||
PARSEINFO pi;
|
||||
if( test.LoadFromFile( "test/file", &pi ) )
|
||||
Fail( "XML: LoadFromFile should have failed" );
|
||||
if( pi.error_string != "Fake error" )
|
||||
Fail( "XML: LoadFromFile error check: wrong error return: got \"%s\"", pi.error_string.c_str() );
|
||||
} while(false);
|
||||
|
||||
/* Write error check. */
|
||||
do {
|
||||
g_BytesUntilError = 5;
|
||||
|
||||
XNode test;
|
||||
test.name = "foo";
|
||||
|
||||
XNode* pNode = new XNode;
|
||||
pNode->name = "bar";
|
||||
|
||||
test.AppendChild( pNode );
|
||||
|
||||
PARSEINFO pi;
|
||||
|
||||
if( test.SaveToFile( "test/file" ) )
|
||||
Fail( "XML: SaveToFile should have failed" );
|
||||
|
||||
// if( test.GetError() != "Fake error" )
|
||||
// Fail( "INI: ReadFile error check: wrong error return: got \"%s\"", test.GetError().c_str() );
|
||||
} while(false);
|
||||
|
||||
}
|
||||
|
||||
#include "CryptManager.h"
|
||||
void CryptoTest()
|
||||
{
|
||||
PREFSMAN = new PrefsManager; /* CRYPTMAN needs PREFSMAN */
|
||||
PREFSMAN->m_bSignProfileData = true;
|
||||
|
||||
CRYPTMAN = new CryptManager;
|
||||
|
||||
g_TestFile = "hello world";
|
||||
g_TestFilename = "file";
|
||||
FlushDirCache();
|
||||
|
||||
do {
|
||||
g_BytesUntilError = -1;
|
||||
CRYPTMAN->SignFileToFile( "test/file", "output" );
|
||||
|
||||
FlushDirCache();
|
||||
|
||||
if( !CRYPTMAN->VerifyFileWithFile( "test/file", "output" ) )
|
||||
Fail( "Crypto: VerifyFileWithFile failed");
|
||||
} while(false);
|
||||
|
||||
|
||||
/* Write error check. */
|
||||
do {
|
||||
g_BytesUntilError = 5;
|
||||
CRYPTMAN->SignFileToFile( "test/file", "output" );
|
||||
} while(false);
|
||||
|
||||
/* Read error check. */
|
||||
do {
|
||||
g_BytesUntilError = 5;
|
||||
CRYPTMAN->SignFileToFile( "output", "test/file" );
|
||||
} while(false);
|
||||
|
||||
delete PREFSMAN;
|
||||
delete CRYPTMAN;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
test_handle_args( argc, argv );
|
||||
|
||||
test_init();
|
||||
|
||||
/* Setup. */
|
||||
FILEMAN->Mount( "TEST", ".", "test" );
|
||||
|
||||
SanityCheck();
|
||||
|
||||
IniTest();
|
||||
MsdTest();
|
||||
XmlTest();
|
||||
CryptoTest();
|
||||
|
||||
test_deinit();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user