From 20248abf8f93b0e4ec25eb928ba1057db6e57128 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 6 Jun 2004 22:08:09 +0000 Subject: [PATCH] add error handling test --- stepmania/src/tests/test_file_errors.cpp | 475 +++++++++++++++++++++++ 1 file changed, 475 insertions(+) create mode 100644 stepmania/src/tests/test_file_errors.cpp diff --git a/stepmania/src/tests/test_file_errors.cpp b/stepmania/src/tests/test_file_errors.cpp new file mode 100644 index 0000000000..eb8c4ef641 --- /dev/null +++ b/stepmania/src/tests/test_file_errors.cpp @@ -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 + +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 = ""; + + 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 = ""; + + 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. + */ +