--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/tdbms/t_dbbug.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,623 @@
+// Copyright (c) 1998-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:
+// Test code for bugs that have been fixed, to help prevent regression
+//
+//
+
+#include <d32dbms.h>
+#include <f32file.h>
+#include <e32test.h>
+#include <s32mem.h>
+
+LOCAL_D RTest test(_L("t_dbbug"));
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D RFs TheFs;
+LOCAL_D RDbNamedDatabase TheDatabase;
+
+const TInt KTestCleanupStack=0x40;
+
+void Check(TInt aValue,TInt aExpected,TInt aLine)
+ {
+ if (aValue!=aExpected)
+ {
+ test.Printf(_L("*** Expected %d: got %d\r\n"),aExpected,aValue);
+ test.operator()(EFalse,aLine);
+ }
+ }
+#define test2(a,b) Check(a,b,__LINE__)
+
+static void Print(const TText* aString)
+ {
+ test.Printf(_L("%s\n"),aString);
+ }
+
+////////////////////////////////////////////
+
+_LIT(KTestDatabase,"c:\\dbms-tst\\bug.db");
+_LIT(KTableA,"A");
+_LIT(KTableB,"B");
+_LIT(KTableC,"C");
+
+class Defect_590829
+ {
+public:
+ static void TestL();
+ static const TDesC& Name();
+ };
+
+
+const TDesC& Defect_590829::Name()
+ {
+ _LIT(KName,"590829");
+ return KName;
+ }
+
+/////////////////////////////////////////////////
+
+// Length of text data used for each entry. This will be
+// equivalent to 400 bytes for ansi characters. The number of
+// bytes must not be less than 256 (or 128 for this const).
+// If it is a stream will not be used for transfer of data.
+const TInt KTextDataLength = 200;
+
+// max column size
+const TInt KMaxColLength = 1000;
+
+// Buffer size to cause HDbsBuf::DoReadL() ipc check to be executed
+const TInt KBufSizeDoReadL = 1000;
+
+// Buffer size to cause HDbsBuf::UnderflowL() ipc check to be executed
+const TInt KBufSizeUnderflowL = 500;
+
+class Defect_071149
+ {
+public:
+ static void TestL();
+ static const TDesC& Name();
+ };
+
+
+const TDesC& Defect_071149::Name()
+ {
+ _LIT(KName,"071149");
+ return KName;
+ }
+
+/**
+HDbsBuf did not handle case when iIpc.iHandle is 0 causing IPC calls to panic.
+The handle is 0 when opening a stream and all data is retrieved in this request.
+
+@SYMTestCaseID SYSLIB-DBMS-CT-1491
+@SYMTestCaseDesc Tests for defect number 590829
+@SYMTestPriority High
+@SYMTestActions Tests by setting up failure conditions.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF INC071149
+*/
+void Defect_071149::TestL()
+ {
+ test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-1491 "));
+ Print(_S("Creating test database"));
+
+ // Connect to dbms and open db
+ RDbs dbs;
+ RDbNamedDatabase db;
+ test2 (db.Replace(TheFs,KTestDatabase),KErrNone);
+ db.Close();
+
+ test2(dbs.Connect(), KErrNone);
+ test2(db.Open(dbs,KTestDatabase), KErrNone);
+
+ // creating column to hold LongText
+ CDbColSet *colSet = CDbColSet::NewL();
+ CleanupStack::PushL(colSet);
+ colSet->AddL(TDbCol(_L("Id"), EDbColLongText, KMaxColLength));
+
+ // create table
+ test2(db.CreateTable(KTableA, *colSet), KErrNone);
+ CleanupStack::PopAndDestroy(colSet);
+
+ // create text data to add to table
+ HBufC* testText = HBufC::New(KTextDataLength);
+ test(testText !=NULL );
+ TPtr ptr = testText->Des();
+ for(TInt y=0;y<KTextDataLength;++y)
+ {
+ ptr.Append(TChar('A'));
+ }
+
+ // add data to table
+ RDbTable newTable;
+ test2 (newTable.Open(db,KTableA),KErrNone);
+ db.Begin();
+ newTable.InsertL();
+ newTable.SetColL(1, ptr);
+ newTable.PutL();
+
+ test2 (db.Commit(),KErrNone);
+ test2 (newTable.CountL(), 1);
+ newTable.Close();
+
+ // cleanup
+ delete testText;
+
+ // disconnect from db and dbms
+ db.Close();
+ dbs.Close();
+
+//
+ // Connect to dbms and open db
+ test2(dbs.Connect(), KErrNone);
+ test2(db.Open(dbs,KTestDatabase), KErrNone);
+
+ // Test handle check in HDbsBuf::DoReadL() - See defect
+ // If the handle check did not exist in the production code then
+ // it would panic.
+
+ // create test table
+ RDbTable testTable;
+ test2 (testTable.Open(db,KTableA),KErrNone);
+ db.Begin();
+ testTable.FirstL();
+ testTable.GetL();
+
+ // Open stream
+ RDbColReadStream rs;
+ rs.OpenLC( testTable, 1);
+
+ // Read data
+ TBuf<KBufSizeDoReadL> buf;
+ TRAPD(err, rs.ReadL( buf, buf.MaxLength()));
+ if(err != KErrNone)
+ {
+ test2(err, KErrEof);
+ }
+ CleanupStack::PopAndDestroy(); // Close rs
+ testTable.Close();
+
+//
+ // Test handle check in HDbsBuf::UnderflowL() - additional error not in defect
+ // If the handle check did not exist in the production code then
+ // it would panic.
+
+ // create test table
+ test2 (testTable.Open(db,KTableA),KErrNone);
+ testTable.NextL();
+ testTable.GetL();
+
+ // Open stream
+ RDbColReadStream rs2;
+ rs2.OpenLC( testTable, 1);
+
+ // Read data
+ TBuf<KBufSizeUnderflowL> buf2;
+ TRAP(err, rs2.ReadL( buf2, buf2.MaxLength()));
+ if(err != KErrNone)
+ {
+ test2(err, KErrEof);
+ }
+ CleanupStack::PopAndDestroy(); // Close rs
+
+ // tidy up
+ testTable.Close();
+ db.Close();
+ dbs.Close();
+ }
+
+/////////////////////////////////////////////////
+
+/**
+Cached, unused tables were breaking the iterator in CDbTableDatabase::CheckIdle
+The latter function has been re-written to restart the iteration when tables are Idle()'d
+
+@SYMTestCaseID SYSLIB-DBMS-CT-0582
+@SYMTestCaseDesc Tests for defect number 590829
+@SYMTestPriority Medium
+@SYMTestActions Tests by setting up failure conditions.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void Defect_590829::TestL()
+ {
+ test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0582 "));
+ Print(_S("Creating test database"));
+ test2 (TheDatabase.Replace(TheFs,KTestDatabase),KErrNone);
+ TheDatabase.Begin();
+ test2 (TheDatabase.Execute(_L("create table A (id counter)")),KErrNone);
+ test2 (TheDatabase.Execute(_L("create table B (id counter)")),KErrNone);
+ test2 (TheDatabase.Execute(_L("create table C (id counter)")),KErrNone);
+ test2 (TheDatabase.Commit(),KErrNone);
+//
+ Print(_S("Setting up failure"));
+ RDbTable tA,tB,tC;
+ test2 (tA.Open(TheDatabase,KTableA),KErrNone);
+ test2 (tB.Open(TheDatabase,KTableB),KErrNone);
+ tB.Close();
+ test2 (tC.Open(TheDatabase,KTableC),KErrNone);
+ tC.Close();
+ TheDatabase.Begin();
+ tA.Close();
+//
+ Print(_S("Testing fix"));
+ test2 (TheDatabase.Commit(),KErrNone);
+ TheDatabase.Destroy();
+ }
+
+/////////////////////////////////////////////////
+
+class Defect_394751
+ {
+public:
+ static void TestL();
+ static const TDesC& Name();
+private:
+ static TInt Thread(TAny*);
+ static void ThreadL();
+ };
+
+
+const TDesC& Defect_394751::Name()
+ {
+ _LIT(KName,"394751");
+ return KName;
+ }
+
+void Defect_394751::ThreadL()
+ {
+ RDbs dbs;
+ RDbNamedDatabase db;
+ User::LeaveIfError(dbs.Connect());
+ User::LeaveIfError(db.Open(dbs,KTestDatabase));
+ db.Begin();
+ db.Begin(); /// panic now
+ User::Panic(_L("T_BUG failure"),0);
+ }
+
+TInt Defect_394751::Thread(TAny*)
+ {
+ User::SetJustInTime(EFalse); // disable debugger panic handling
+ CTrapCleanup* cleanup=CTrapCleanup::New();
+ if (!cleanup)
+ return KErrNoMemory;
+ TRAPD(r,ThreadL());
+ delete cleanup;
+ return r;
+ }
+
+/**
+@SYMTestCaseID SYSLIB-DBMS-CT-0583
+@SYMTestCaseDesc Tests for defect number 394751
+@SYMTestPriority Medium
+@SYMTestActions Tests for thread exit status.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void Defect_394751::TestL()
+//
+//
+ {
+ test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0583 "));
+ Print(_S("Creating test database"));
+ test2 (TheDatabase.Replace(TheFs,KTestDatabase),KErrNone);
+ TheDatabase.Close();
+//
+ RDbs dbs;
+ test2 (dbs.Connect(),KErrNone);
+//
+ Print(_S("Running test thread"));
+ RThread t;
+ _LIT(KTestThread,"Defect Fix 394751");
+ test2 (t.Create(KTestThread,&Thread,0x2000,0x1000,0x10000,0,EOwnerThread),KErrNone);
+ TRequestStatus s;
+ t.Logon(s);
+ test2 (s.Int(),KRequestPending);
+ t.Resume();
+ Print(_S("Awaiting completion"));
+ User::WaitForRequest(s);
+ _LIT(KCategory,"DBMS-Table");
+ test2 (t.ExitType(),EExitPanic);
+ test (t.ExitCategory()==KCategory);
+ test2 (t.ExitReason(),11); // begin nested transaction
+ User::SetJustInTime(ETrue); // enable debugger panic handling
+ t.Close();
+//
+ test2 (dbs.ResourceCount(),0);
+ dbs.Close();
+ }
+
+///////////////////////////////////////////////////////////
+
+class Defect_COMBBAR_463J5D
+ {
+public:
+ static void TestL();
+ static const TDesC& Name();
+private:
+ static void WaitForServerExit();
+ static TInt Thread(TAny*);
+ };
+
+const TDesC& Defect_COMBBAR_463J5D::Name()
+ {
+ _LIT(KName,"COMBBAR_463J5D");
+ return KName;
+ }
+
+void Defect_COMBBAR_463J5D::WaitForServerExit()
+ {
+ _LIT(KDbmsServer,"*!DBMS server");
+ TFullName n;
+ TFindThread ft(KDbmsServer);
+ if (ft.Next(n)==KErrNone)
+ {
+ RThread t;
+ if (t.Open(ft)==KErrNone)
+ {
+ TRequestStatus s;
+ t.Logon(s);
+ User::WaitForRequest(s);
+ t.Close();
+ }
+ }
+ }
+
+TInt Defect_COMBBAR_463J5D::Thread(TAny*)
+//
+// Just try to start the server
+//
+ {
+ RDbs dbs;
+ return dbs.Connect();
+ }
+
+/**
+@SYMTestCaseID SYSLIB-DBMS-CT-0584
+@SYMTestCaseDesc Tests for defect number COMBBAR_463J5D
+@SYMTestPriority Medium
+@SYMTestActions Testing that defect COMBBAR_463J5D in ER5 Defects database has been fixed
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void Defect_COMBBAR_463J5D::TestL()
+ {
+ test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0584 "));
+ Print(_S("Wait for the server to exit"));
+ WaitForServerExit();
+//
+ Print(_S("Create the launching threads"));
+ RThread t1,t2;
+ TRequestStatus s1,s2;
+ _LIT(KThread1,"t1");
+ test2 (t1.Create(KThread1,&Thread,0x2000,0,0,EOwnerThread),KErrNone);
+ t1.SetPriority(EPriorityLess);
+ t1.Logon(s1);
+ _LIT(KThread2,"t2");
+ test2 (t2.Create(KThread2,&Thread,0x2000,0,0,EOwnerThread),KErrNone);
+ t2.SetPriority(EPriorityLess);
+ t2.Logon(s2);
+//
+ Print(_S("Run the threads and wait"));
+ t1.Resume();
+ t2.Resume();
+ User::WaitForRequest(s1,s2);
+ if (s1==KRequestPending)
+ User::WaitForRequest(s1);
+ else
+ User::WaitForRequest(s2);
+//
+ test2 (t1.ExitType(),EExitKill);
+ if (s1.Int()!=KErrNotFound)
+ test2 (s1.Int(),KErrNone);
+ test2 (t2.ExitType(),EExitKill);
+ if (s2.Int()!=KErrNotFound)
+ test2 (s2.Int(),KErrNone);
+ t1.Close();
+ t2.Close();
+ }
+
+/////////////////////////////////////////////////////////
+
+class Defect_EDNATHE_48AEZW
+ {
+public:
+ static void TestL();
+ static const TDesC& Name();
+ };
+
+const TDesC& Defect_EDNATHE_48AEZW::Name()
+ {
+ _LIT(KName,"EDNATHE_48AEZW");
+ return KName;
+ }
+/**
+@SYMTestCaseID SYSLIB-DBMS-CT-0585
+@SYMTestCaseDesc Tests for defect number EDNATHE_48AEZW
+@SYMTestPriority Medium
+@SYMTestActions Tests for navigation and deletion
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void Defect_EDNATHE_48AEZW::TestL()
+ {
+ test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0585 "));
+ Print(_S("Set up database"));
+ test2 (TheDatabase.Replace(TheFs,KTestDatabase),KErrNone);
+ test2 (TheDatabase.Begin(),KErrNone);
+ test2 (TheDatabase.Execute(_L("create table A (id counter)")),KErrNone);
+ RDbView v1;
+ test2 (v1.Prepare(TheDatabase,_L("select * from A"),v1.EInsertOnly),KErrNone);
+ test2 (v1.EvaluateAll(),KErrNone);
+ for (TInt ii=0;ii<4;++ii)
+ {
+ v1.InsertL();
+ v1.PutL();
+ }
+ test2 (TheDatabase.Commit(),KErrNone);
+ v1.Close();
+//
+ Print(_S("test navigation"));
+ test2 (v1.Prepare(TheDatabase,_L("select * from A where id=0")),KErrNone);
+ test2 (v1.EvaluateAll(),KErrNone);
+ v1.FirstL();
+ RDbView v2;
+ test2 (v2.Prepare(TheDatabase,_L("select * from A where id=1")),KErrNone);
+ test2 (v2.EvaluateAll(),KErrNone);
+ v2.FirstL();
+ v2.DeleteL();
+ TRAPD(r, v1.NextL());
+ test2 (r,KErrNone);
+ test (v1.AtEnd());
+ v2.Close();
+//
+ Print(_S("test deletion"));
+ v1.FirstL();
+ test2 (v2.Prepare(TheDatabase,_L("select * from A where id=2")),KErrNone);
+ test2 (v2.EvaluateAll(),KErrNone);
+ v2.FirstL();
+ v2.DeleteL();
+ TRAP(r,v1.DeleteL());
+ test2 (r,KErrNone);
+ TRAP(r, v1.NextL());
+ test2 (r,KErrNone);
+ test (v1.AtEnd());
+//
+ v1.Close();
+ v2.Close();
+ TheDatabase.Close();
+ }
+
+/////////////////////////////////////////////////////////
+
+static void NextTest(const TDesC& aName)
+ {
+ TBuf<80> buf;
+ buf=_S("Checking Defect ");
+ buf+=aName;
+ test.Next(buf);
+ }
+
+template <typename T>
+struct RunTest
+ {
+ RunTest()
+ {
+ const TDesC& name = T::Name();
+ NextTest(name);
+ TRAPD(r,T::TestL());
+ test2 (r,KErrNone);
+ Print(_S("Defect fixed"));
+ }
+ };
+
+LOCAL_C void setupTestDirectory()
+//
+// Prepare the test directory.
+//
+ {
+ TInt r=TheFs.Connect();
+ test(r==KErrNone);
+//
+ r=TheFs.MkDir(KTestDatabase);
+ test(r==KErrNone || r==KErrAlreadyExists);
+ }
+
+LOCAL_C void setupCleanup()
+//
+// Initialise the cleanup stack.
+//
+ {
+ TheTrapCleanup=CTrapCleanup::New();
+ test(TheTrapCleanup!=NULL);
+ TRAPD(r,\
+ {\
+ for (TInt i=KTestCleanupStack;i>0;i--)\
+ CleanupStack::PushL((TAny*)0);\
+ CleanupStack::Pop(KTestCleanupStack);\
+ });
+ test(r==KErrNone);
+ }
+
+LOCAL_C void DeleteDataFile(const TDesC& aFullName)
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ TEntry entry;
+ if(fsSession.Entry(aFullName, entry) == KErrNone)
+ {
+ RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
+ err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+ }
+ err = fsSession.Delete(aFullName);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+ }
+ }
+ fsSession.Close();
+ }
+ else
+ {
+ RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+ }
+ }
+
+GLDEF_C TInt E32Main()
+//
+// Test streaming conversions.
+//
+ {
+ __UHEAP_MARK;
+ test.Title();
+ setupTestDirectory();
+ setupCleanup();
+//
+ test.Start(_L("Verifying defect fixes"));
+ RunTest<Defect_COMBBAR_463J5D>();
+// The following short delay is needed for ccover builds only.
+// Without the pause, the kernel scheduler would intermittently
+// crash 0.3s after the last test ended.
+ User::After(500000);
+ test.Printf(_L("Resume test after delay.\n"));
+
+ RunTest<Defect_394751>();
+ User::After(500000);
+ test.Printf(_L("Resume test after delay.\n"));
+
+ RunTest<Defect_590829>();
+ User::After(500000);
+ test.Printf(_L("Resume test after delay.\n"));
+
+ RunTest<Defect_071149>();
+ User::After(500000);
+ test.Printf(_L("Resume test after delay.\n"));
+
+ RunTest<Defect_EDNATHE_48AEZW>();
+
+ // clean up data files used by this test - must be done before call to End() - DEF047652
+ ::DeleteDataFile(KTestDatabase);
+
+ test.End();
+//
+ delete TheTrapCleanup;
+
+ TheFs.Close();
+ test.Close();
+ __UHEAP_MARKEND;
+ return 0;
+ }