sl@0: // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include <e32test.h> sl@0: #include <bautils.h> sl@0: #include <e32math.h> sl@0: #include <sqldb.h> sl@0: #include "SqlUtil.h" sl@0: #include "SqlSrvStartup.h" //KSqlMajorVer, KSqlMinorVer, KSqlBuildVer sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: static RFs TheFs; sl@0: RTest TheTest(_L("t_sqlbadclient test")); sl@0: _LIT(KTestDir, "c:\\test\\"); sl@0: _LIT(KTestDbName1, "c:\\test\\t_sqlbadclient.db"); sl@0: _LIT(KTestDbName2, "c:[1111D1C1]t_sqlbadclient.db"); sl@0: sl@0: #if defined __WINS__ || defined __WINSCW__ sl@0: const TInt KTestIterCount = 5000; sl@0: #else sl@0: const TInt KTestIterCount = 4000; sl@0: #endif sl@0: const TInt KMaxDesArgLen = 1000; sl@0: enum TArgType sl@0: { sl@0: EIntArgType, sl@0: ETextArgType, sl@0: EBinArgType, sl@0: ELastArgType sl@0: }; sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //If the SQL server crashes and the test receives KErrServerTerminated error, then the sl@0: //next set will contain the last: sl@0: // - iteration number; sl@0: // - handle type; sl@0: // - function code; sl@0: // - handle; sl@0: // - IPC arguments values; sl@0: struct TThreadData sl@0: { sl@0: TInt iIteration; sl@0: TSqlSrvHandleType iHandleType; sl@0: TInt iFunction; sl@0: TInt iHandle; sl@0: TArgType iArgType[KMaxMessageArguments]; sl@0: TInt iIntArg[KMaxMessageArguments]; sl@0: TBuf<KMaxDesArgLen> iTextArg[KMaxMessageArguments]; sl@0: TBuf8<KMaxDesArgLen> iBinArg[KMaxMessageArguments]; sl@0: TInt64 iSeed; sl@0: }; sl@0: ////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: _LIT(KPanicCategory, "SrvTerm"); sl@0: _LIT(KPanicCategory2, "InvArg"); sl@0: const TInt KPanicCode = 1111; sl@0: const TInt KPanicCode2 = 2222; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //Deletes all created test files. sl@0: void DeleteTestFiles() sl@0: { sl@0: RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: //Test macros and functions sl@0: void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse) sl@0: { sl@0: if(!aValue) sl@0: { sl@0: DeleteTestFiles(); sl@0: if(aPrintThreadName) sl@0: { sl@0: RThread th; sl@0: TName name = th.Name(); sl@0: RDebug::Print(_L("*** Thread %S, Line %d\r\n"), &name, aLine); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Print(_L("*** Line %d\r\n"), aLine); sl@0: } sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse) sl@0: { sl@0: if(aValue != aExpected) sl@0: { sl@0: DeleteTestFiles(); sl@0: if(aPrintThreadName) sl@0: { sl@0: RThread th; sl@0: TName name = th.Name(); sl@0: RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); sl@0: } sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: #define TEST(arg) ::Check1((arg), __LINE__) sl@0: #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) sl@0: #define TTEST(arg) ::Check1((arg), __LINE__, ETrue) sl@0: #define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue) sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //Creates file session instance and the test directory sl@0: void CreateTestEnv() sl@0: { sl@0: TInt err = TheFs.Connect(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: err = TheFs.MkDir(KTestDir); sl@0: TEST(err == KErrNone || err == KErrAlreadyExists); sl@0: } sl@0: sl@0: //Starts the SQL server process. sl@0: TInt StartSqlServer() sl@0: { sl@0: const TUid KSqlSrvUid3 = {0x10281E17};//The same UID is in SqlSrv.mmp file sl@0: const TUidType serverUid(KNullUid, KNullUid, KSqlSrvUid3); sl@0: _LIT(KSqlSrvImg, "SqlSrv");//SQL server image name sl@0: RProcess server; sl@0: TInt err = server.Create(KSqlSrvImg, KNullDesC, serverUid); sl@0: if(err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: TRequestStatus stat; sl@0: server.Rendezvous(stat); sl@0: if(stat != KRequestPending) sl@0: { sl@0: server.Kill(0); // abort startup sl@0: } sl@0: else sl@0: { sl@0: server.Resume(); // logon OK - start the server sl@0: } sl@0: User::WaitForRequest(stat); // wait for start or death sl@0: // we can't use the 'exit reason' if the server panicked as this sl@0: // is the panic 'reason' and may be '0' which cannot be distinguished sl@0: // from KErrNone sl@0: err = (server.ExitType() == EExitPanic) ? KErrGeneral : stat.Int(); sl@0: server.Close(); sl@0: return err; sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////// RTestSqlDbSession ////////////////////////////////// sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //Test client SQL session class sl@0: class RTestSqlDbSession : public RSessionBase sl@0: { sl@0: public: sl@0: TInt Connect(const TVersion& aVersion); sl@0: void Close(); sl@0: TInt SendReceive(TInt aFunction); sl@0: TInt SendReceive(TInt aFunction, const TIpcArgs& aArgs); sl@0: sl@0: private: sl@0: TInt DoCreateSession(const TVersion& aVersion); sl@0: }; sl@0: sl@0: TInt RTestSqlDbSession::Connect(const TVersion& aVersion) sl@0: { sl@0: TInt err = DoCreateSession(aVersion); sl@0: if(err == KErrNone) sl@0: { sl@0: TIpcArgs ipcArgs(KTestDbName1().Length(), &KTestDbName1(), 0, 0); sl@0: err = SendReceive(ESqlSrvDbOpen, ipcArgs); sl@0: } sl@0: if(err != KErrNone && err != KErrAlreadyExists) sl@0: { sl@0: Close(); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void RTestSqlDbSession::Close() sl@0: { sl@0: if(Handle()) sl@0: { sl@0: (void)SendReceive(ESqlSrvDbClose); sl@0: } sl@0: RSessionBase::Close(); sl@0: } sl@0: sl@0: TInt RTestSqlDbSession::SendReceive(TInt aFunction) sl@0: { sl@0: return RSessionBase::SendReceive(aFunction); sl@0: } sl@0: sl@0: TInt RTestSqlDbSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs) sl@0: { sl@0: return RSessionBase::SendReceive(aFunction, aArgs); sl@0: } sl@0: sl@0: TInt RTestSqlDbSession::DoCreateSession(const TVersion& aVersion) sl@0: { sl@0: const TInt KTimesToRetryConnection = 2; sl@0: TInt retry = KTimesToRetryConnection; sl@0: _LIT(KSqlSrvName, "!SQL Server");//SqlDb server name sl@0: for(;;) sl@0: { sl@0: TInt err = CreateSession(KSqlSrvName, aVersion); sl@0: if(err != KErrNotFound && err != KErrServerTerminated) sl@0: { sl@0: return err; sl@0: } sl@0: if(--retry == 0) sl@0: { sl@0: return err; sl@0: } sl@0: err = ::StartSqlServer(); sl@0: if(err != KErrNone && err != KErrAlreadyExists) sl@0: { sl@0: return err; sl@0: } sl@0: } sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: TInt SendReceive(RTestSqlDbSession aSession, TSqlSrvHandleType aHandleType, TInt aFunction, TInt aHandle, TIpcArgs& aArgs) sl@0: { sl@0: return aSession.SendReceive(::MakeMsgCode(static_cast <TSqlSrvFunction> (aFunction), aHandleType, aHandle), aArgs); sl@0: } sl@0: sl@0: TInt SendReceive(RTestSqlDbSession aSession, TInt aFunction, TIpcArgs& aArgs) sl@0: { sl@0: return aSession.SendReceive(aFunction, aArgs); sl@0: } sl@0: sl@0: void PrintIterationCount(TInt aIteration) sl@0: { sl@0: if((aIteration % 100) == 0) sl@0: { sl@0: TTime time; sl@0: time.HomeTime(); sl@0: TDateTime dt = time.DateTime(); sl@0: TBuf<16> tbuf; sl@0: tbuf.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond()); sl@0: RDebug::Print(_L("-----[%S] Test iterations: %d\r\n"), &tbuf, aIteration); sl@0: } sl@0: } sl@0: sl@0: //Worker thread function. sl@0: //It behaves as a malicious client. Connects to the SQL server. In each test iteration generates some random values sl@0: //for the function number, handle, handle type, IPC arguments. Then sends a command to the server using these sl@0: //randomly generated values. If the server crashes and the thread function receives KErrServerTerminated error, sl@0: //then the thread kills itself and the main thread will get KPanicCategory and KPanicCode as a reason for the sl@0: //worker thread's death. The last set of randomly generated values will be stored in the memory, pointed by aData argument. sl@0: TInt ThreadFunc1(void* aData) sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: TTEST(tc != NULL); sl@0: sl@0: TThreadData* p = static_cast <TThreadData*> (aData); sl@0: TTEST(p != NULL); sl@0: TThreadData& data = *p; sl@0: sl@0: TVersion sqlSoftwareVersion(KSqlMajorVer, KSqlMinorVer, KSqlBuildVer); sl@0: RTestSqlDbSession sess; sl@0: TInt err = sess.Connect(sqlSoftwareVersion); sl@0: TTEST2(err, KErrNone); sl@0: sl@0: while(++data.iIteration <= KTestIterCount) sl@0: { sl@0: PrintIterationCount(data.iIteration); sl@0: TIpcArgs args; sl@0: do sl@0: { sl@0: data.iFunction = Math::Rand(data.iSeed) % (ESqlSrvStreamClose + 1);//ESqlSrvStreamClose - the last server message number) sl@0: } sl@0: while(data.iFunction >= ESqlSrvResourceMark && data.iFunction <= ESqlSrvSetHeapFailure); sl@0: for(TInt i=0;i<KMaxMessageArguments;++i) sl@0: { sl@0: //Initialize arguments sl@0: data.iArgType[i] = static_cast <TArgType> (Math::Rand(data.iSeed) % ELastArgType); sl@0: switch(data.iArgType[i]) sl@0: { sl@0: case EIntArgType: sl@0: data.iIntArg[i] = Math::Rand(data.iSeed) % 9711; sl@0: args.Set(i, data.iIntArg[i]); sl@0: break; sl@0: case ETextArgType: sl@0: { sl@0: TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen; sl@0: data.iTextArg[i].SetLength(len); sl@0: args.Set(i, &data.iTextArg[i]); sl@0: } sl@0: break; sl@0: case EBinArgType: sl@0: { sl@0: TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen; sl@0: data.iBinArg[i].SetLength(len); sl@0: args.Set(i, &data.iBinArg[i]); sl@0: } sl@0: break; sl@0: default: sl@0: User::Panic(KPanicCategory2, KPanicCode2); sl@0: break; sl@0: } sl@0: } sl@0: //Send arguments sl@0: User::SetJustInTime(EFalse); sl@0: TInt err = KErrNone; sl@0: if((Math::Rand(data.iSeed) % 5) == 0) //Pass a handle (statement or stream) sl@0: { sl@0: data.iHandleType = (Math::Rand(data.iSeed) % 2) ? ESqlSrvStatementHandle : ESqlSrvStreamHandle; sl@0: data.iHandle = Math::Rand(data.iSeed) % 64; sl@0: err = ::SendReceive(sess, data.iHandleType, data.iFunction, data.iHandle, args); sl@0: } sl@0: else sl@0: { sl@0: err = ::SendReceive(sess, data.iFunction, args); sl@0: } sl@0: if(err == KErrServerTerminated) sl@0: { sl@0: User::Panic(KPanicCategory, KPanicCode); sl@0: } sl@0: User::SetJustInTime(ETrue); sl@0: } sl@0: sl@0: sess.Close(); sl@0: sl@0: delete tc; sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-CT-1769 sl@0: @SYMTestCaseDesc In a loop, where the loop iterations are less than KTestIterCount (5000 at the moment), sl@0: the test creates a public shared database and a worker thread, which will behave as sl@0: malicious client. If the worker thread crashes the SQL server, then the worker thread sl@0: dies notifying the main thread about the SQL server crash. The main thread prints the sl@0: values used in the last IPC call and crashes the test. sl@0: @SYMTestPriority High sl@0: @SYMTestActions SQL, Malicious client simulation test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ5792 sl@0: REQ5793 sl@0: REQ10405 sl@0: REQ10407 sl@0: */ sl@0: void BadClientTest() sl@0: { sl@0: TThreadData* p = new TThreadData; sl@0: TEST(p != NULL); sl@0: TThreadData& data = *p; sl@0: data.iFunction = 0; sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: data.iSeed = now.Int64(); sl@0: sl@0: _LIT(KThreadName, "WorkThrd"); sl@0: sl@0: for(data.iIteration=0;data.iIteration<KTestIterCount;++data.iIteration) sl@0: { sl@0: PrintIterationCount(data.iIteration); sl@0: //Create/open the test database sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(KTestDbName1); sl@0: TEST(err == KErrNone || err == KErrAlreadyExists); sl@0: if(err == KErrNone) sl@0: { sl@0: err = db.Exec(_L8("CREATE TABLE A(Id INTEGER); INSERT INTO A(Id) VALUES(1); INSERT INTO A(Id) VALUES(2);")); sl@0: TEST(err >= 0); sl@0: } sl@0: db.Close(); sl@0: //Run the malicious client (one worker theread which will try to crash the SQL server) sl@0: RThread thread; sl@0: TEST2(thread.Create(KThreadName, &ThreadFunc1, 0x2000, 0x1000, 0x10000, &data, EOwnerProcess), KErrNone); sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: TEST2(status.Int(), KRequestPending); sl@0: thread.Resume(); sl@0: User::WaitForRequest(status); sl@0: User::SetJustInTime(ETrue); // enable debugger panic handling sl@0: if(thread.ExitType() == EExitPanic) sl@0: { sl@0: if(thread.ExitReason() == KPanicCode) sl@0: { sl@0: TheTest.Printf(_L("##Server terminated!\r\n")); sl@0: TheTest.Printf(_L("##Iteration=%d, Handle type(hex)=%X, Function(hex)=%X, Handle=%d\r\n"), data.iIteration, data.iHandleType, data.iFunction, data.iHandle); sl@0: for(TInt i=0;i<KMaxMessageArguments;++i) sl@0: { sl@0: switch(data.iArgType[i]) sl@0: { sl@0: case EIntArgType: sl@0: TheTest.Printf(_L("##Arg %d, Integer, value=%d\r\n"), i, data.iIntArg[i]); sl@0: break; sl@0: case ETextArgType: sl@0: TheTest.Printf(_L("##Arg %d, Text, length=%d\r\n"), i, data.iTextArg[i].Length()); sl@0: break; sl@0: case EBinArgType: sl@0: TheTest.Printf(_L("##Arg %d, Binary, length=%d\r\n"), i, data.iBinArg[i].Length()); sl@0: break; sl@0: default: sl@0: TheTest.Printf(_L("##Arg %d, Invalid argument type: %d\r\n"), i, data.iArgType[i]); sl@0: break; sl@0: } sl@0: } sl@0: TEST(0); sl@0: } sl@0: } sl@0: thread.Close(); sl@0: } sl@0: User::SetJustInTime(ETrue); // enable debugger panic handling sl@0: delete p; sl@0: } sl@0: sl@0: RSqlSecurityPolicy CreateSecurityPolicy() sl@0: { sl@0: RSqlSecurityPolicy securityPolicy; sl@0: const TSecurityPolicy KDefaultPolicy(TSecurityPolicy::EAlwaysPass); sl@0: TInt err = securityPolicy.Create(KDefaultPolicy); sl@0: TEST2(err, KErrNone); sl@0: return securityPolicy; sl@0: } sl@0: sl@0: void DoBadNameTest(RSqlDatabase& aDb) sl@0: { sl@0: TFileName invalidFileName1; sl@0: invalidFileName1.SetLength(KMaxFileName); sl@0: //Initialise the first character so that it is not treated as an empty descriptor by the sever sl@0: invalidFileName1[0] = TChar(204); //0xCC sl@0: TFileName invalidFileName2; sl@0: invalidFileName2.SetLength(KMaxFileName); sl@0: invalidFileName2.Fill(TChar(204));//0xCC sl@0: sl@0: TInt err = aDb.Attach(invalidFileName1, invalidFileName2); sl@0: TheTest.Printf(_L("Attach, invalid database name-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = aDb.Attach(invalidFileName2, invalidFileName1); sl@0: TheTest.Printf(_L("Attach, invalid database name-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = aDb.Attach(KTestDbName2, invalidFileName2); sl@0: TheTest.Printf(_L("Attach, invalid database name-3, err=%d\r\n"), err); sl@0: TEST(err != KErrDied); sl@0: if(err == KErrNone) sl@0: { sl@0: err = aDb.Detach(invalidFileName2); sl@0: TheTest.Printf(_L("Detach, invalid database name-3, err=%d\r\n"), err); sl@0: TEST2(err, KErrNone); sl@0: } sl@0: err = aDb.Attach(KTestDbName2, invalidFileName1); sl@0: TheTest.Printf(_L("Attach, invalid database name-4, err=%d\r\n"), err); sl@0: TEST(err != KErrDied); sl@0: if(err == KErrNone) sl@0: { sl@0: err = aDb.Detach(invalidFileName1); sl@0: TheTest.Printf(_L("Detach, invalid database name-4, err=%d\r\n"), err); sl@0: TEST2(err, KErrNone); sl@0: } sl@0: sl@0: RSqlDatabase::TSize size; sl@0: sl@0: err = aDb.Size(size, invalidFileName1); sl@0: TheTest.Printf(_L("Size, invalid database name-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = aDb.Size(size, invalidFileName2); sl@0: TheTest.Printf(_L("Size, invalid database name-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: sl@0: err = aDb.Compact(RSqlDatabase::EMaxCompaction, invalidFileName1); sl@0: TheTest.Printf(_L("Compact, invalid database name-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = aDb.Compact(RSqlDatabase::EMaxCompaction, invalidFileName2); sl@0: TheTest.Printf(_L("Compact, invalid database name-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(aDb, _L("SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: sl@0: err = stmt.ColumnIndex(invalidFileName1); sl@0: TheTest.Printf(_L("ColumnIndex, invalid column name-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = stmt.ColumnIndex(invalidFileName2); sl@0: TheTest.Printf(_L("ColumnIndex, invalid column name-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = stmt.ParameterIndex(invalidFileName1); sl@0: TheTest.Printf(_L("ParameterIndex, invalid parameter name-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = stmt.ParameterIndex(invalidFileName2); sl@0: TheTest.Printf(_L("ParameterIndex, invalid parameter name-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: sl@0: stmt.Close(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4048 sl@0: @SYMTestCaseDesc Bad database names - robustness test. sl@0: The test defines file names with invalid content and attempts to use sl@0: these file names with the SQL API. The test should not cause crashes sl@0: in the SQL server. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Bad database names - robustness test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ10405 sl@0: REQ10407 sl@0: */ sl@0: void BadNameTest() sl@0: { sl@0: TFileName invalidFileName1; sl@0: invalidFileName1.SetLength(KMaxFileName); sl@0: TFileName invalidFileName2; sl@0: invalidFileName2.SetLength(KMaxFileName / 2); sl@0: sl@0: //Initialise the first character so that it is not treated as an empty descriptor by the sever sl@0: invalidFileName1[0] = TChar(204); //0xCC sl@0: invalidFileName2[0] = TChar(204); //0xCC sl@0: sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: (void)RSqlDatabase::Delete(KTestDbName2); sl@0: sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(invalidFileName1); sl@0: TEST(err != KErrNone); sl@0: err = db.Create(invalidFileName2); sl@0: TEST(err != KErrNone); sl@0: sl@0: err = db.Open(invalidFileName1); sl@0: TEST(err != KErrNone); sl@0: err = db.Open(invalidFileName2); sl@0: TEST(err != KErrNone); sl@0: sl@0: err = db.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = db.Exec(_L("CREATE TABLE A(I INTEGER)")); sl@0: TEST(err >= 0); sl@0: db.Close(); sl@0: sl@0: RSqlSecurityPolicy sp = CreateSecurityPolicy(); sl@0: err = db.Create(KTestDbName2, sp); sl@0: TEST2(err, KErrNone); sl@0: sp.Close(); sl@0: err = db.Exec(_L("CREATE TABLE A(I INTEGER)")); sl@0: TEST(err >= 0); sl@0: db.Close(); sl@0: sl@0: TheTest.Printf(_L("Bad names test - public shared database\r\n")); sl@0: err = db.Open(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: DoBadNameTest(db); sl@0: db.Close(); sl@0: sl@0: TheTest.Printf(_L("Bad names test - public secure shared database\r\n")); sl@0: err = db.Open(KTestDbName2); sl@0: TEST2(err, KErrNone); sl@0: DoBadNameTest(db); sl@0: db.Close(); sl@0: sl@0: (void)RSqlDatabase::Delete(KTestDbName2); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: sl@0: err = RSqlDatabase::Copy(invalidFileName1, invalidFileName2); sl@0: TheTest.Printf(_L("Copy database, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = RSqlDatabase::Delete(invalidFileName1); sl@0: TheTest.Printf(_L("Delete database-1, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: err = RSqlDatabase::Delete(invalidFileName2); sl@0: TheTest.Printf(_L("Delete database-2, err=%d\r\n"), err); sl@0: TEST(err != KErrNone); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID PDS-SQL-CT-4200 sl@0: @SYMTestCaseDesc Invalid sql software version test. sl@0: @SYMTestPriority High sl@0: @SYMTestActions The test verifies that the SQL server checks that the software version of SQL sessions sl@0: to be created is less or equal to the current version of the server software. sl@0: If that is not true then the SQL server does not create the session annd returns KErrNotSupported. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMDEF DEF145236 sl@0: */ sl@0: void InvalidSoftwareVersionTest() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: db.Close(); sl@0: sl@0: //Smaller version number sl@0: TVersion sqlSoftwareVersion1(1, 0, 0); sl@0: RTestSqlDbSession sess1; sl@0: err = sess1.Connect(sqlSoftwareVersion1); sl@0: sess1.Close(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: //Bigger version number 1 sl@0: TVersion sqlSoftwareVersion2(1, 97, 3); sl@0: RTestSqlDbSession sess2; sl@0: err = sess2.Connect(sqlSoftwareVersion2); sl@0: TEST2(err, KErrNotSupported); sl@0: sl@0: //Bigger version number 2 sl@0: TVersion sqlSoftwareVersion3(78, 0, 1); sl@0: RTestSqlDbSession sess3; sl@0: err = sess3.Connect(sqlSoftwareVersion3); sl@0: TEST2(err, KErrNotSupported); sl@0: sl@0: //The current version number sl@0: TVersion sqlSoftwareVersion4(KSqlMajorVer, KSqlMinorVer, KSqlBuildVer); sl@0: RTestSqlDbSession sess4; sl@0: err = sess4.Connect(sqlSoftwareVersion4); sl@0: sess4.Close(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: void DoTests() sl@0: { sl@0: TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1769 Bad client test ")); sl@0: BadClientTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4048 Bad names test")); sl@0: BadNameTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4200 Invalid software version test")); sl@0: InvalidSoftwareVersionTest(); sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: TheTest.Title(); sl@0: sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: DeleteTestFiles(); sl@0: CreateTestEnv(); sl@0: DoTests(); sl@0: DeleteTestFiles(); sl@0: TheFs.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: TheTest.End(); sl@0: TheTest.Close(); sl@0: sl@0: delete tc; sl@0: sl@0: User::Heap().Check(); sl@0: return KErrNone; sl@0: }