--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sqlite3api/OsLayer/test_fileutil.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,344 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <f32file.h>
+#include <sys/param.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "tcl.h"
+
+_LIT(KTestExt, "*.test");
+_LIT(KTclExt, "*.tcl");
+_LIT(KExplainExt, "*.explain");
+_LIT(KTclTempFilePrefix, "tcl*");
+
+//Note: every time when you add a new KTestFileXX constant here, don't forget to add that constant as a new entry into
+//"TPtrC fileNames[]" array in DoDeleteTestFilesL() function.
+_LIT(KTestFile1, "test1.bt");
+_LIT(KTestFile2, "test.bu");
+_LIT(KTestFile3, "backup.db");
+_LIT(KTestFile4, "bak.db");
+_LIT(KTestFile5, "corrupt.db");
+_LIT(KTestFile6, "ptf2.db");
+_LIT(KTestFile7, "test1.db");
+_LIT(KTestFile8, "test2.db");
+_LIT(KTestFile9, "test3.db");
+_LIT(KTestFile10,"test4.db");
+_LIT(KTestFile11,"test.db");
+_LIT(KTestFile12,"test.db2");
+_LIT(KTestFile13,"bak.db-journal");
+_LIT(KTestFile14,"test.db-journal-bu");
+_LIT(KTestFile15,"mydir");
+_LIT(KTestFile16,"testdb");
+_LIT(KTestFile17,"test2-script.tcl");
+_LIT(KTestFile18,"test.tcl");
+_LIT(KTestFile19,"speed1.txt");
+_LIT(KTestFile20,"speed2.txt");
+_LIT(KTestFile21,"test.db-bu1");
+_LIT(KTestFile22,"test.db-bu2");
+_LIT(KTestFile23,"test.db-template");
+_LIT(KTestFile24,"invalid.db");
+_LIT(KTestFile25,"log");
+_LIT(KTestFile26,"test5.db");
+
+_LIT(KTestDir1,"mydir-journal");
+
+#ifdef _DEBUG
+
+#define PRINT_DELFILE_ERROR(aFileName, aErr) \
+ if(aErr != KErrNone && aErr != KErrNotFound)\
+ {\
+ RDebug::Print(_L("###TclSqlite3: Failed to delete file \"%S\". Error=%d\r\n"), &aFileName, aErr);\
+ }
+
+#else
+
+#define PRINT_DELFILE_ERROR(aFileName, aErr) void(0)
+
+#endif
+
+//Connects the file session argument.
+//Creates application's private datacage on drive C: (if does not exist).
+//Copies the private path as string to the aPrivatePath argument (without the drive name).
+//aPrivatePath must point to a big enough place (ideally TFileName object).
+static void GetFsAndPrivatePathL(RFs& aFs, TDes& aPrivatePath)
+ {
+ User::LeaveIfError(aFs.Connect());
+ TInt err = aFs.CreatePrivatePath(EDriveC);
+ if(!(err == KErrNone || err == KErrAlreadyExists))
+ {
+ User::Leave(err);
+ }
+
+ User::LeaveIfError(aFs.PrivatePath(aPrivatePath));
+ }
+
+//The function constructs a full script file path, containing wildcards, in aFullPath argument
+// (from aDriveNumber and aPrivatePath arguments, using aMask parameter as a file name).
+//aFullPath must point to a big enough place (ideally TFileName object).
+static void ConstructFilePathByMask(TDriveNumber aDriveNumber, const TDesC& aPrivatePath, const TDesC& aMask, TDes& aFullPath)
+ {
+ TDriveName srcDriveName = TDriveUnit(aDriveNumber).Name();
+ aFullPath.Copy(srcDriveName);
+ aFullPath.Append(aMask);
+ TParse parse;
+ parse.Set(aPrivatePath, &aFullPath, 0);
+ aFullPath.Copy(parse.FullName());
+ }
+
+//The function constructs a full file path in aFullPath argument (from aDriveNumber, aFileName and aPrivatePath arguments).
+//aFullPath must point to a big enough place (ideally TFileName object).
+static void ConstructFilePathByName(TDriveNumber aDriveNumber, const TDesC& aFileName, const TDesC& aPrivatePath, TDes& aFullPath)
+ {
+ TDriveName srcDriveName = TDriveUnit(aDriveNumber).Name();
+ aFullPath.Copy(srcDriveName);
+ aFullPath.Append(aFileName);
+ TParse parse;
+ parse.Set(aPrivatePath, &aFullPath, 0);
+ aFullPath.Copy(parse.FullName());
+ }
+
+//The function constructs a full path in aDestPath argument (from aDriveNumber and aPrivatePath arguments).
+//aDestPath must point to a big enough place (ideally TFileName object).
+static void ConstructDestPath(TDriveNumber aDriveNumber, const TDesC& aPrivatePath, TDes& aDestPath)
+ {
+ TDriveName destDriveName = TDriveUnit(aDriveNumber).Name();
+ TParse parse;
+ parse.Set(aPrivatePath, &destDriveName, 0);
+ aDestPath.Copy(parse.FullName());
+ }
+
+//The function copies all test script files from Z: to C: drive, in application's private data cage.
+static void DoCopyTestFilesL()
+ {
+ RDebug::Print(_L("###TclSqlite3: Construct private data cage on drive C:\r\n"));
+ RFs fs;
+ CleanupClosePushL(fs);
+ TFileName privatePath;
+ GetFsAndPrivatePathL(fs, privatePath);
+
+ CFileMan* fm = CFileMan::NewL(fs);
+ CleanupStack::PushL(fm);
+
+ TFileName srcPath, destPath;
+ ConstructFilePathByMask(EDriveZ, privatePath, KTestExt, srcPath);
+ ConstructDestPath(EDriveC, privatePath, destPath);
+ RDebug::Print(_L("###TclSqlite3: Copying \"%S\" to \"%S\"\r\n"), &srcPath, &destPath);
+ User::LeaveIfError(fm->Copy(srcPath, destPath));
+
+ ConstructFilePathByMask(EDriveZ, privatePath, KTclExt, srcPath);
+ ConstructDestPath(EDriveC, privatePath, destPath);
+ RDebug::Print(_L("###TclSqlite3: Copying \"%S\" to \"%S\"\r\n"), &srcPath, &destPath);
+ User::LeaveIfError(fm->Copy(srcPath, destPath));
+
+ ConstructFilePathByMask(EDriveZ, privatePath, KExplainExt, srcPath);
+ ConstructDestPath(EDriveC, privatePath, destPath);
+ RDebug::Print(_L("###TclSqlite3: Copying \"%S\" to \"%S\"\r\n"), &srcPath, &destPath);
+ User::LeaveIfError(fm->Copy(srcPath, destPath));
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+//The function deletes a file, identified by the aFullPath argument.
+//The function leaves if the delete operation error is different than KErrNone and KErrNotFound.
+static void DoDeleteTestFileL(CFileMan& aFm, const TDesC& aFullPath)
+ {
+ TInt err = aFm.Attribs(aFullPath, 0, KEntryAttReadOnly, TTime(0));
+ if(err == KErrNone)
+ {
+ err = aFm.Delete(aFullPath);
+ }
+ if(err != KErrNone && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+ }
+
+//The function deletes a directory, identified by the aFullPath argument.
+//The function leaves if the delete operation error is different than KErrNone and KErrNotFound.
+static void DoDeleteTestDirL(CFileMan& aFm, const TDesC& aFullPath)
+ {
+ TInt err = aFm.Attribs(aFullPath, 0, KEntryAttReadOnly, TTime(0));
+ if(err == KErrNone)
+ {
+ err = aFm.RmDir(aFullPath);
+ }
+ if(err != KErrNone && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+ }
+
+//Deletes the test scripts and test output files from C: drive.
+static void DoDeleteTestFilesL()
+ {
+ RFs fs;
+ CleanupClosePushL(fs);
+ TFileName privatePath;
+ GetFsAndPrivatePathL(fs, privatePath);
+
+ CFileMan* fm = CFileMan::NewL(fs);
+ CleanupStack::PushL(fm);
+
+ TFileName filePath;
+ ConstructFilePathByMask(EDriveC, privatePath, KExplainExt, filePath);
+ TRAPD(err, DoDeleteTestFileL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+
+ ConstructFilePathByMask(EDriveC, privatePath, KTclExt, filePath);
+ TRAP(err, DoDeleteTestFileL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+
+ ConstructFilePathByMask(EDriveC, privatePath, KTestExt, filePath);
+ TRAP(err, DoDeleteTestFileL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+
+ ConstructFilePathByMask(EDriveC, privatePath, KTclTempFilePrefix, filePath);
+ TRAP(err, DoDeleteTestFileL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+
+ TPtrC fileNames[] =
+ {
+ KTestFile1(), KTestFile2(), KTestFile3(), KTestFile4(), KTestFile5(),
+ KTestFile6(), KTestFile7(), KTestFile8(), KTestFile9(), KTestFile10(),
+ KTestFile11(), KTestFile12(), KTestFile13(), KTestFile14(), KTestFile15(),
+ KTestFile16(), KTestFile17(), KTestFile18(), KTestFile19(), KTestFile20(),
+ KTestFile21(), KTestFile22(), KTestFile23(), KTestFile24(), KTestFile25(), KTestFile26()
+ };
+ for(TInt i=0;i<(sizeof(fileNames)/sizeof(fileNames[0]));++i)
+ {
+ ConstructFilePathByName(EDriveC, fileNames[i], privatePath, filePath);
+ TRAP(err, DoDeleteTestFileL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+ }
+
+ ConstructFilePathByName(EDriveC, KTestDir1, privatePath, filePath);
+ RDebug::Print(_L("###TclSqlite3: test dir to be removed - \"%S\".\r\n"), &filePath);
+ TRAP(err, DoDeleteTestDirL(*fm, filePath));
+ PRINT_DELFILE_ERROR(filePath, err);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+//Deletes the test scripts from C: drive
+//Because the TCL SQLITE exe has mutiple exit points, there is no right place in the code where this function
+//can be called from.
+//The way how the test cleanup is implemented is:
+// - a new script function has been definied and registered (tclsqlite.c)- "delete_test_files"
+// - the "delete_test_files" function is called from the "finalize_testing" procedure (tester.tcl file),
+// that is guaranteed to be called at the end of any test script execution
+extern "C" int DeleteTestFiles(void)
+ {
+ RDebug::Print(_L("###TclSqlite3: Begin \"Delete test files\" operation\r\n"));
+ TRAP_IGNORE(DoDeleteTestFilesL());
+ RDebug::Print(_L("###TclSqlite3: \"Delete test files\" operation has completed\r\n"));
+ return 0;
+ }
+
+//Copies the test scripts from Z: to C: drive
+//This function is called from main() (tclsqlite.c file)
+extern "C" TInt CopyTestFiles(void)
+ {
+ RDebug::Print(_L("###TclSqlite3: Begin \"Copy test files\" operation\r\n"));
+ TRAPD(err, DoCopyTestFilesL());
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("###TclSqlite3: \"Copy test files\" operation has failed with error %d\r\n"), err);
+ DeleteTestFiles();
+ }
+ else
+ {
+ RDebug::Print(_L("###TclSqlite3: \"Copy test files\" operation has completed successfully\r\n"));
+ }
+ return err;
+ }
+
+//Used by GetFullFilePath() in test_hexio.c
+//Seems that the OpenEnv library does not provide _splitpath().
+extern "C" char* FullFilePath(char* aPath, const char* aFileName)
+ {
+ static TFileName fname;
+ fname.Copy(TPtrC8((const TUint8*)aFileName));
+ fname.Trim();
+ for(TInt i=0;i<fname.Length();++i)
+ {
+ if(fname[i] == TChar('/'))
+ {
+ fname[i] = TChar('\\');
+ }
+ }
+ if(fname.Find(_L(".\\")) == 0) //TParsePtrC::TParsePtrC() panics if the first two characters are ".\"
+ {
+ fname.Delete(0, 2);
+ }
+ TParsePtrC parse(fname);
+ if(!parse.DrivePresent() || !parse.PathPresent())
+ {
+ if(!getcwd(aPath, MAXPATHLEN + 1))
+ {
+ return 0;
+ }
+ aPath[0] = 'c';//a temporary patch. The defect number is: DEF116621.
+ strcat(aPath, "\\");
+ static TBuf8<KMaxFileName> fname2;
+ fname2.Copy(parse.NameAndExt());
+ fname2.Append(TChar('\x0'));
+ strcat(aPath, (const char*)fname2.Ptr());
+ }
+ else
+ {
+ strcpy(aPath, aFileName);
+ }
+ return aPath;
+ }
+
+extern "C" int PrintText(void*, Tcl_Interp*, int objc, Tcl_Obj* const* objv)
+ {
+ if(objc == 3)
+ {
+ const char* txt1 = Tcl_GetStringFromObj(objv[1], 0);
+ const char* txt2 = Tcl_GetStringFromObj(objv[2], 0);
+ if(txt1 && txt2)
+ {
+ TTime time;
+ time.HomeTime();
+ TDateTime dt = time.DateTime();
+ TBuf<16> tbuf;
+ tbuf.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond());
+
+ TBuf<256> buf1;
+ buf1.Copy(TPtrC8((const TUint8*)txt1));
+
+ TBuf<256> buf2;
+ buf2.Copy(TPtrC8((const TUint8*)txt2));
+
+ RDebug::Print(_L("%S: %S %S.\n"), &tbuf, &buf1, &buf2);
+ return TCL_OK;
+ }
+ }
+ return TCL_ERROR;
+ }
+
+extern "C" void PrintS(const char* aTxt)
+ {
+ TBuf<128> buf;
+ buf.Copy(TPtrC8((const TUint8*)aTxt));
+
+ RProcess process;
+ TProcessId processId = process.Id();
+
+ RDebug::Print(_L("%S. Process Id=%ld.\n"), &buf, processId.Id());
+ }