Esempio n. 1
0
TEST(LockManager, GrantMultipleFIFOOrder) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    std::unique_ptr<MMAPV1LockerImpl> locker[6];
    for (int i = 0; i < 6; i++) {
        locker[i].reset(new MMAPV1LockerImpl());
    }

    TrackingLockGrantNotification notify[6];

    LockRequest request[6];
    for (int i = 0; i < 6; i++) {
        request[i].initNew(locker[i].get(), &notify[i]);
        lockMgr.lock(resId, &request[i], MODE_X);

        ASSERT(request[i].mode == MODE_X);
        ASSERT(request[i].recursiveCount == 1);
    }

    // Release the last held lock and ensure the next one, based on time is granted
    for (int i = 0; i < 5; i++) {
        lockMgr.unlock(&request[i]);

        ASSERT(notify[i + 1].numNotifies == 1);
        ASSERT(notify[i + 1].lastResId == resId);
        ASSERT(notify[i + 1].lastResult == LOCK_OK);
    }

    // Release the last one
    lockMgr.unlock(&request[5]);
}
Esempio n. 2
0
TEST(LockManager, GrantRecursiveNonCompatibleConvertDown) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    LockRequestCombo request(&locker);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_X));
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 1);
    ASSERT(request.numNotifies == 0);

    // Acquire again, in *non-compatible*, but less strict mode
    ASSERT(LOCK_OK == lockMgr.convert(resId, &request, MODE_S));
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 2);
    ASSERT(request.numNotifies == 0);

    // Release first acquire
    lockMgr.unlock(&request);
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 1);

    // Release second acquire
    lockMgr.unlock(&request);
    ASSERT(request.recursiveCount == 0);
}
Esempio n. 3
0
TEST(LockManager, MultipleConflict) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    TrackingLockGrantNotification notify;

    LockRequest request[6];
    for (int i = 0; i < 6; i++) {
        request[i].initNew(&locker, &notify);

        if (i == 0) {
            ASSERT(LOCK_OK == lockMgr.lock(resId, &request[i], MODE_X));
        } else {
            ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request[i], MODE_X));
        }

        ASSERT(request[i].mode == MODE_X);
        ASSERT(request[i].recursiveCount == 1);
    }

    ASSERT(notify.numNotifies == 0);

    // Free them one by one and make sure they get granted in the correct order
    for (int i = 0; i < 6; i++) {
        lockMgr.unlock(&request[i]);

        if (i < 5) {
            ASSERT(notify.numNotifies == i + 1);
        }
    }
}
Esempio n. 4
0
TEST(LockManager, ConflictCancelWaiting) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    TrackingLockGrantNotification notify1;

    MMAPV1LockerImpl locker2;
    TrackingLockGrantNotification notify2;

    LockRequest request1;
    request1.initNew(&locker1, &notify1);

    LockRequest request2;
    request2.initNew(&locker2, &notify2);

    // First request granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
    ASSERT(notify1.numNotifies == 0);

    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_X));

    // Release second request (which is still in the WAITING mode)
    lockMgr.unlock(&request2);
    ASSERT(notify2.numNotifies == 0);

    ASSERT(request1.mode == MODE_S);
    ASSERT(request1.recursiveCount == 1);

    // Release second acquire
    lockMgr.unlock(&request1);
}
Esempio n. 5
0
    TEST(LockManager, GrantRecursiveNonCompatibleConvertDown) {
        LockManager lockMgr;
        const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

        LockState locker;
        TrackingLockGrantNotification notify;

        LockRequest request;
        request.initNew(&locker, &notify);

        ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_X));
        ASSERT(request.mode == MODE_X);
        ASSERT(request.recursiveCount == 1);
        ASSERT(notify.numNotifies == 0);

        // Acquire again, in *non-compatible*, but less strict mode
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_S));
        ASSERT(request.mode == MODE_X);
        ASSERT(request.recursiveCount == 2);
        ASSERT(notify.numNotifies == 0);

        // Release first acquire
        lockMgr.unlock(&request);
        ASSERT(request.mode == MODE_X);
        ASSERT(request.recursiveCount == 1);

        // Release second acquire
        lockMgr.unlock(&request);
        ASSERT(request.recursiveCount == 0);
    }
Esempio n. 6
0
// Lock conflict matrix tests
static void checkConflict(LockMode existingMode, LockMode newMode, bool hasConflict) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl lockerExisting;
    TrackingLockGrantNotification notifyExisting;
    LockRequest requestExisting;
    requestExisting.initNew(&lockerExisting, &notifyExisting);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &requestExisting, existingMode));

    MMAPV1LockerImpl lockerNew;
    TrackingLockGrantNotification notifyNew;
    LockRequest requestNew;
    requestNew.initNew(&lockerNew, &notifyNew);

    LockResult result = lockMgr.lock(resId, &requestNew, newMode);
    if (hasConflict) {
        ASSERT_EQUALS(LOCK_WAITING, result);
    } else {
        ASSERT_EQUALS(LOCK_OK, result);
    }

    lockMgr.unlock(&requestNew);
    lockMgr.unlock(&requestExisting);
}
void TestOnMappedNetworkDrives::ActualTestImportDocument()
{
	DocProviderWorker	objWorker;
	WSDocNonCom			wsDoc;
	LockManager			lockMgr;

	CStdString sMappedDriveLetter = m_NetDriveHelper.GetMapNetworkDriveLetter();
	assertMessage(!sMappedDriveLetter.IsEmpty(), _T("Cannot map network drive - used to just skip test"));
	CStdString sOrigFile = sMappedDriveLetter + _T("\\Original.doc");

	DocumentID docImportID(DocumentID::GenerateIdFromFilePath(sOrigFile));
	CStdString csLocalFile = docImportID.CreateLocalFile();
	objWorker.PopulateDocumentProperties(docImportID, wsDoc, false);
	CStdString sOldDocID = wsDoc.GetDocId();
	HRESULT hrImport = objWorker.ImportDocument(wsDoc, false);

	assertMessage(SUCCEEDED(hrImport),_T("Failure code returned from ImportDocument()"));

	if(sOldDocID.CompareNoCase( CStdString(wsDoc.GetDocId()))==0)
	{
		assertMessage(false,_T("The in and out DocID's are the same after import"));
	}


	// check lock=false
	CStdString sLockedBy;
	if(lockMgr.IsDocIDLocked(wsDoc.GetDocId(), sLockedBy) )
	{
		assertMessage(false, _T("Imported file is locked when it was requested not to be"));
	}

	if(docImportID.GetDescription() != wsDoc.GetDescription())
	{
		assertMessage(false, _T("The document Description does not match the original file used for the import."));
	}
	
	assertTest((wsDoc.GetFlags() & DOCUMENT_LOCKED_BY_US)==0);

	LFSDMSHelper dmsHelp;

	DocumentID docID(wsDoc.GetDocId());
	CStdString	sLocalName(docID.GetWorkingFile());
	int iFileNameStartsAt = sLocalName.ReverseFind('\\');
	if ((iFileNameStartsAt != CStdString::npos) && (dmsHelp.DoesFileExist(sLocalName)))
	{
		sLocalName.resize(iFileNameStartsAt);
		assertTest(dmsHelp.DeleteDirectoryAndContents(sLocalName));
	}
	::DeleteFile(csLocalFile.c_str());
}
Esempio n. 8
0
void TestCloseDocument::TestUnlocksFileOnClose()
{
	DocProviderWorker	objWorker;
	WSDocNonCom			wsDoc;
	DocumentID			docTarget(DocumentID::GenerateIdFromFilePath(sTestOriginalFileName));
	
	wsDoc.SetDescription(docTarget.GetDescription());
	wsDoc.SetLocalFile(docTarget.GetWorkingFile());
	assertTest(objWorker.ImportDocument(wsDoc, true) == S_OK);
	m_wsImportedDoc = wsDoc;
	assertTest(objWorker.CloseDocument(wsDoc,0) == S_OK);

	LockManager lckMngr;
	CStdString sLockedBy;
	assertTest(lckMngr.IsDocIDLocked(wsDoc.GetDocId(),sLockedBy) == false);
}
Esempio n. 9
0
TEST(LockManager, ConflictingConversion) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    MMAPV1LockerImpl locker2;

    LockRequestCombo request1(&locker1);
    LockRequestCombo request2(&locker2);

    // The S requests are granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
    ASSERT(request1.numNotifies == 0);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
    ASSERT(request2.numNotifies == 0);

    // Convert first request to conflicting
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request1, MODE_X));
    ASSERT(request1.numNotifies == 0);

    // Free the second lock and make sure the first is granted
    lockMgr.unlock(&request2);
    ASSERT(request1.mode == MODE_X);
    ASSERT(request1.numNotifies == 1);
    ASSERT(request2.numNotifies == 0);

    // Frees the first reference, mode remains X
    lockMgr.unlock(&request1);
    ASSERT(request1.mode == MODE_X);
    ASSERT(request1.recursiveCount == 1);

    lockMgr.unlock(&request1);
}
Esempio n. 10
0
    TEST(LockManager, Upgrade) {
        LockManager lockMgr;
        const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

        LockState locker1;
        TrackingLockGrantNotification notify1;
        LockRequest request1;
        request1.initNew(&locker1, &notify1);
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_IS));

        LockState locker2;
        TrackingLockGrantNotification notify2;
        LockRequest request2;
        request2.initNew(&locker2, &notify2);
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
        ASSERT(request2.recursiveCount == 1);

        // Upgrade the IS lock to X
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request1, MODE_IX));

        ASSERT(!lockMgr.unlock(&request1));
        ASSERT(lockMgr.unlock(&request1));

        ASSERT(lockMgr.unlock(&request2));
    }
Esempio n. 11
0
TEST(LockManager, ConflictCancelMultipleWaiting) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    TrackingLockGrantNotification notify;

    LockRequest request[6];
    for (int i = 0; i < 6; i++) {
        request[i].initNew(&locker, &notify);
        lockMgr.lock(resId, &request[i], MODE_X);

        ASSERT(request[i].mode == MODE_X);
        ASSERT(request[i].recursiveCount == 1);
    }

    ASSERT(notify.numNotifies == 0);

    // Free the second (waiting)
    lockMgr.unlock(&request[1]);

    // Free the last
    lockMgr.unlock(&request[5]);

    // Free one in the middle
    lockMgr.unlock(&request[3]);

    // Free the remaining so the LockMgr does not compain about leaked locks
    lockMgr.unlock(&request[2]);
    lockMgr.unlock(&request[4]);
    lockMgr.unlock(&request[0]);
}
Esempio n. 12
0
TEST(LockManager, Grant) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    TrackingLockGrantNotification notify;

    LockRequest request;
    request.initNew(&locker, &notify);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_S));
    ASSERT(request.mode == MODE_S);
    ASSERT(request.recursiveCount == 1);
    ASSERT(notify.numNotifies == 0);

    lockMgr.unlock(&request);
    ASSERT(request.recursiveCount == 0);
}
Esempio n. 13
0
    TEST(LockManager, Conflict) {
        LockManager lockMgr;
        const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

        LockState locker1;
        TrackingLockGrantNotification notify1;

        LockState locker2;
        TrackingLockGrantNotification notify2;        

        LockRequest request1;
        request1.initNew(&locker1, &notify1);

        LockRequest request2;
        request2.initNew(&locker2, &notify2);

        // First request granted right away
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
        ASSERT(request1.recursiveCount == 1);
        ASSERT(notify1.numNotifies == 0);

        // Second request must block
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_X));
        ASSERT(request2.mode == MODE_X);
        ASSERT(request2.recursiveCount == 1);
        ASSERT(notify2.numNotifies == 0);

        // Release first request
        lockMgr.unlock(&request1);
        ASSERT(request1.recursiveCount == 0);
        ASSERT(notify1.numNotifies == 0);

        ASSERT(request2.mode == MODE_X);
        ASSERT(request2.recursiveCount == 1);
        ASSERT(notify2.numNotifies == 1);
        ASSERT(notify2.lastResult == LOCK_OK);

        // Release second acquire
        lockMgr.unlock(&request2);
        ASSERT(request2.recursiveCount == 0);

        ASSERT(notify1.numNotifies == 0);
        ASSERT(notify2.numNotifies == 1);
    }
Esempio n. 14
0
TEST(LockManagerTest, TxShutdown) {
    LockManager lm;
    ClientTransaction t1(&lm, 1);
    ClientTransaction t2(&lm, 2);

    t1.acquire(kShared, 1, ACQUIRED);
    lm.shutdown(3000);

    // t1 can still do work while quiescing
    t1.release(kShared, 1);
    t1.acquire(kShared, 2, ACQUIRED);
#ifdef TRANSACTION_REGISTRATION
    // t2 is new and should be refused
    t2.acquire(kShared, 3, ABORTED);
#else
    t2.quit();
#endif
    // after the quiescing period, t1's request should be refused
    sleepsecs(3);
    t1.acquire(kShared, 4, ABORTED);
}
Esempio n. 15
0
void TestLockDocument::TestLockAttachment()
{
	DocProviderWorker	objWorker;
	LockManager			docLock;
	CStdString			sDocID(DocumentID::GetDocProviderId() + TEST_DIRECTORY + TEST_DOC + _T(".doc"));
	DocumentID			docID(sDocID);
	CStdString			szDummyUser(_T("HighHouseShadow"));
	CStdString			sLockFileName(docID.GetLockFileName(szDummyUser, false));
	WSDocNonCom			wsDoc;

	objWorker.GetDocument(sDocID,NULL,wsDoc);
		
	HRESULT hrLock = docLock.CreateLock(sDocID, szDummyUser);

	if(FAILED(hrLock))
	{
		CStdString szErr;
		szErr.Format(_T("CreateLock returned a Failure Error code - %08x"),hrLock);
		assertMessage(false, szErr);
	}
	
	if (_taccess(sLockFileName, 0) == -1)
	{
		assertMessage(false, _T("We didn't create a lock file as HighHouseShadow"));
	}

	HRESULT hrUnlock = docLock.RemoveLock(sDocID,szDummyUser);
	
	if(FAILED(hrUnlock))
	{
		CStdString szErr;
		szErr.Format(_T("CreateLock returned a Failure Error code - %08x"),hrUnlock);
		assertMessage(false,szErr);
	}

	if (_taccess(sLockFileName, 0) != -1)
	{
		assertMessage(false, _T("We didn't remove the HighHouseShadow lock"));
	}
}
Esempio n. 16
0
TEST(LockManager, CancelWaitingConversionStrongModes) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    MMAPV1LockerImpl locker2;

    LockRequestCombo request1(&locker1);
    LockRequestCombo request2(&locker2);

    // First request granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
    ASSERT(request1.numNotifies == 0);

    // Second request is granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
    ASSERT(request2.numNotifies == 0);

    // Convert second request to conflicting
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request2, MODE_X));
    ASSERT(request2.mode == MODE_S);
    ASSERT(request2.convertMode == MODE_X);
    ASSERT(request2.numNotifies == 0);

    // Cancel the conflicting upgrade
    lockMgr.unlock(&request2);
    ASSERT(request2.mode == MODE_S);
    ASSERT(request2.convertMode == MODE_NONE);
    ASSERT(request2.numNotifies == 0);

    // Free the remaining locks so the LockManager destructor does not complain
    lockMgr.unlock(&request1);
    lockMgr.unlock(&request2);
}
Esempio n. 17
0
TEST(LockManager, ConflictingConversionInTheMiddle) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    TrackingLockGrantNotification notify;

    LockRequest request[3];
    for (int i = 0; i < 3; i++) {
        request[i].initNew(&locker, &notify);
        lockMgr.lock(resId, &request[i], MODE_S);
    }

    // Upgrade the one in the middle (not the first one)
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request[1], MODE_X));

    ASSERT(notify.numNotifies == 0);

    // Release the two shared modes
    lockMgr.unlock(&request[0]);
    ASSERT(notify.numNotifies == 0);

    lockMgr.unlock(&request[2]);
    ASSERT(notify.numNotifies == 1);

    ASSERT(request[1].mode == MODE_X);

    // Request 1 should be unlocked twice
    lockMgr.unlock(&request[1]);
    lockMgr.unlock(&request[1]);
}
Esempio n. 18
0
TEST(LockManager, Downgrade) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    LockRequestCombo request1(&locker1);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_X));

    MMAPV1LockerImpl locker2;
    LockRequestCombo request2(&locker2);
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_S));

    // Downgrade the X request to S
    lockMgr.downgrade(&request1, MODE_S);

    ASSERT(request2.numNotifies == 1);
    ASSERT(request2.lastResult == LOCK_OK);
    ASSERT(request2.recursiveCount == 1);

    ASSERT(lockMgr.unlock(&request1));
    ASSERT(lockMgr.unlock(&request2));
}
Esempio n. 19
0
void TestCloseDocument::TestFailIfLockedByOther()
{
	DocProviderWorker	objWorker;
	WSDocNonCom			wsDoc;
	DocumentID			docTarget(DocumentID::GenerateIdFromFilePath(sTestOriginalFileName));
	
	wsDoc.SetDescription(docTarget.GetDescription());
	wsDoc.SetLocalFile(docTarget.GetWorkingFile());
	assertTest(objWorker.ImportDocument(wsDoc, false) == S_OK);
	m_wsImportedDoc = wsDoc;

	LockManager lckMngr;
	assertTest(lckMngr.CreateLock(wsDoc.GetDocId(),_T("poptart")) == S_OK);

	assertTest(objWorker.CloseDocument(wsDoc,0) == S_OK);

	wsDoc.SetFlags(wsDoc.GetFlags()|DOCUMENT_LOCKED_BY_US);
	
	assertTest(objWorker.CloseDocument(wsDoc,0) == E_DOCUMENT_LOCKED_BY_ANOTHER);

	lckMngr.RemoveLock(wsDoc.GetDocId(),_T("poptart"));
}
Esempio n. 20
0
void TestLockDocument::TestAlreadyLockedByOther()
{
	DocProviderWorker	objWorker;
	CStdString			sDocID(DocumentID::GetDocProviderId() + TEST_DIRECTORY + TEST_DOC + _T(".doc"));
	DocumentID			docID(sDocID);
	CStdString			sLockFileName(docID.GetLockFileName(_T("apple"), false));
	WSDocNonCom			wsDoc;
	LockManager			docLock;
	
	objWorker.GetDocument(sDocID, 0, wsDoc);

	docLock.CreateLock(sDocID, _T("apple"));

	if (_taccess(sLockFileName, 0) == -1)
	{
		assertMessage(false, _T("Unable to create lock file"));
	}
	
	assertTest(objWorker.LockDocument(sDocID, LOCK_DOCUMENT) == E_DOCUMENT_LOCKED_BY_ANOTHER);

	assertMessage(docLock.RemoveLock(docID, _T("apple")) == S_OK, _T("Failed to unlock document at end of test"));	
}
Esempio n. 21
0
TEST(LockManager, Conflict) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    MMAPV1LockerImpl locker2;

    LockRequestCombo request1(&locker1);
    LockRequestCombo request2(&locker2);

    // First request granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
    ASSERT(request1.recursiveCount == 1);
    ASSERT(request1.numNotifies == 0);

    // Second request must block
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_X));
    ASSERT(request2.mode == MODE_X);
    ASSERT(request2.recursiveCount == 1);
    ASSERT(request2.numNotifies == 0);

    // Release first request
    lockMgr.unlock(&request1);
    ASSERT(request1.recursiveCount == 0);
    ASSERT(request1.numNotifies == 0);

    ASSERT(request2.mode == MODE_X);
    ASSERT(request2.recursiveCount == 1);
    ASSERT(request2.numNotifies == 1);
    ASSERT(request2.lastResult == LOCK_OK);

    // Release second acquire
    lockMgr.unlock(&request2);
    ASSERT(request2.recursiveCount == 0);

    ASSERT(request1.numNotifies == 0);
    ASSERT(request2.numNotifies == 1);
}
Esempio n. 22
0
void TestCloseDocument::TestDontDeleteLocal()
{
	DocProviderWorker	objWorker;
	WSDocNonCom			wsDoc;
	DocumentID			docTarget(DocumentID::GenerateIdFromFilePath(sTestOriginalFileName));
	
	wsDoc.SetDescription(docTarget.GetDescription());
	wsDoc.SetLocalFile(docTarget.GetWorkingFile());
	assertTest(objWorker.ImportDocument(wsDoc, true) == S_OK);
	m_wsImportedDoc = wsDoc;

	assertTest(objWorker.CloseDocument(wsDoc, DF_UNLOCK_ONLY) == S_OK);

	LockManager lckMngr;
	assertTest(lckMngr.IsDocIDLockedByUs(wsDoc.GetDocId()) == false);

	CStdString	sLocalFile = wsDoc.GetLocalFile();
	if (_taccess(sLocalFile, 0) == -1)
	{
		assertMessage(false, _T("CloseDocument deleted local file when it shouldn't have"));
	}
	::DeleteFile(sLocalFile);
}
Esempio n. 23
0
void TestLockDocument::TestLockNonExistentAttachment()
{
	DocProviderWorker	objWorker;
	CStdString			sDocID(DocumentID::GetDocProviderId() + TEST_DIRECTORY + TEST_DOC _T(".doc") + _T("?attach.xdf"));
	CStdString			sLockFileName(TEST_DIRECTORY + TEST_DOC _T(".doc") _T("." TEST_DMS_EXT _T("\\Version 1\\attach.xdf_Bones.lock")));
	CStdString			sFile(_T("c:\\Not\\here.doc"));

	::DeleteFile(sFile.c_str());
	::DeleteFile(sLockFileName.c_str());

	WSDocNonCom			wsDoc;
	LockManager			docLock;
	const CStdString	sUsername(_T("Bones"));

	HRESULT hrLock = docLock.CreateLock(sDocID, sUsername);

	if(SUCCEEDED(hrLock))
		assertMessage(false,_T("Reported Succeeded in creating lock on non existent file"));

	if (_taccess(sLockFileName, 0) != -1 )
	{
		assertMessage(false, _T("Lock file exists for a non existent document"));
	}	
}
Esempio n. 24
0
TEST(LockManager, Fairness) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_GLOBAL, 0);

    // Start with some 'regular' intent locks
    MMAPV1LockerImpl lockerIS;
    LockRequestCombo requestIS(&lockerIS);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &requestIS, MODE_IS));

    MMAPV1LockerImpl lockerIX;
    LockRequestCombo requestIX(&lockerIX);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &requestIX, MODE_IX));

    // Now a conflicting lock comes
    MMAPV1LockerImpl lockerX;
    LockRequestCombo requestX(&lockerX);
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));

    // Now, whoever comes next should be blocked
    MMAPV1LockerImpl lockerIX1;
    LockRequestCombo requestIX1(&lockerIX1);
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestIX1, MODE_IX));

    // Freeing the first two locks should grant the X lock
    ASSERT(lockMgr.unlock(&requestIS));
    ASSERT(lockMgr.unlock(&requestIX));
    ASSERT_EQ(LOCK_OK, requestX.lastResult);
    ASSERT_EQ(1, requestX.numNotifies);
    ASSERT_EQ(LOCK_INVALID, requestIX1.lastResult);
    ASSERT_EQ(0, requestIX1.numNotifies);

    ASSERT(lockMgr.unlock(&requestX));
    ASSERT_EQ(LOCK_OK, requestIX1.lastResult);
    ASSERT_EQ(1, requestIX1.numNotifies);

    // Unlock all locks so we don't assert for leaked locks
    ASSERT(lockMgr.unlock(&requestIX1));
}
Esempio n. 25
0
TEST(LockManager, ConvertUpgrade) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    LockRequestCombo request1(&locker1);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));

    MMAPV1LockerImpl locker2;
    LockRequestCombo request2(&locker2);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));

    // Upgrade the S lock to X
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request1, MODE_X));

    ASSERT(!lockMgr.unlock(&request1));
    ASSERT(lockMgr.unlock(&request1));

    ASSERT(lockMgr.unlock(&request2));
}
Esempio n. 26
0
TEST(LockManager, CompatibleFirstGrantAlreadyQueued) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_GLOBAL, 0);

    // This tests the following behavior:
    //   Lock held in X, queue: S IX IS, where S is compatibleFirst.
    //   Once X unlocks both the S and IS requests should proceed.

    MMAPV1LockerImpl locker1;
    LockRequestCombo request1(&locker1);

    MMAPV1LockerImpl locker2;
    LockRequestCombo request2(&locker2);
    request2.compatibleFirst = true;

    MMAPV1LockerImpl locker3;
    LockRequestCombo request3(&locker3);

    MMAPV1LockerImpl locker4;
    LockRequestCombo request4(&locker4);

    // Hold the lock in X and establish the S IX IS queue.
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_X));
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_S));
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request3, MODE_IX));
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request4, MODE_IS));

    // Now unlock, so all readers should be able to proceed, while the IX remains queued.
    ASSERT(lockMgr.unlock(&request1));
    ASSERT(request2.lastResult == LOCK_OK);
    ASSERT(request3.lastResult == LOCK_INVALID);
    ASSERT(request4.lastResult == LOCK_OK);

    // Now unlock the S lock, and the IX succeeds as well.
    ASSERT(lockMgr.unlock(&request2));
    ASSERT(request3.lastResult == LOCK_OK);

    // Unlock remaining
    ASSERT(lockMgr.unlock(&request4));
    ASSERT(lockMgr.unlock(&request3));
}
Esempio n. 27
0
    TEST(LockManager, ConflictingConversion) {
        LockManager lockMgr;
        const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

        LockState locker1;
        TrackingLockGrantNotification notify1;

        LockState locker2;
        TrackingLockGrantNotification notify2;

        LockRequest request1;
        request1.initNew(&locker1, &notify1);

        LockRequest request2;
        request2.initNew(&locker2, &notify2);

        // First request granted right away
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
        ASSERT(notify1.numNotifies == 0);

        ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
        ASSERT(notify2.numNotifies == 0);

        // Convert first request to conflicting
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request1, MODE_X));
        ASSERT(notify1.numNotifies == 0);

        // Free the second lock and make sure the first is granted
        lockMgr.unlock(&request2);
        ASSERT(request1.mode == MODE_X);
        ASSERT(notify1.numNotifies == 1);
        ASSERT(notify2.numNotifies == 0);

        // Frees the first reference, mode remains X
        lockMgr.unlock(&request1);
        ASSERT(request1.mode == MODE_X);
        ASSERT(request1.recursiveCount == 1);

        lockMgr.unlock(&request1);
    }
Esempio n. 28
0
TEST(LockManager, EnqueueAtFront) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl lockerX;
    LockRequestCombo requestX(&lockerX);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &requestX, MODE_X));

    // The subsequent request will block
    MMAPV1LockerImpl lockerLow;
    LockRequestCombo requestLow(&lockerLow);

    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestLow, MODE_X));

    // This is a "queue jumping request", which will go before locker 2 above
    MMAPV1LockerImpl lockerHi;
    LockRequestCombo requestHi(&lockerHi);
    requestHi.enqueueAtFront = true;

    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestHi, MODE_X));

    // Once the X request is gone, lockerHi should be granted, because it's queue jumping
    ASSERT(lockMgr.unlock(&requestX));

    ASSERT(requestHi.lastResId == resId);
    ASSERT(requestHi.lastResult == LOCK_OK);

    // Finally lockerLow should be granted
    ASSERT(lockMgr.unlock(&requestHi));

    ASSERT(requestLow.lastResId == resId);
    ASSERT(requestLow.lastResult == LOCK_OK);

    // This avoids the lock manager asserting on leaked locks
    ASSERT(lockMgr.unlock(&requestLow));
}
Esempio n. 29
0
    TEST(LockManager, ConflictCancelWaitingConversion) {
        LockManager lockMgr;
        const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

        LockState locker1;
        TrackingLockGrantNotification notify1;

        LockState locker2;
        TrackingLockGrantNotification notify2;

        LockRequest request1;
        request1.initNew(&locker1, &notify1);

        LockRequest request2;
        request2.initNew(&locker2, &notify2);

        // First request granted right away
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
        ASSERT(notify1.numNotifies == 0);

        // Second request is granted right away
        ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
        ASSERT(notify2.numNotifies == 0);

        // Convert second request to conflicting
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_X));
        ASSERT(request2.mode == MODE_S);
        ASSERT(request2.convertMode == MODE_X);
        ASSERT(notify2.numNotifies == 0);

        // Cancel the conflicting upgrade
        lockMgr.unlock(&request2);
        ASSERT(request2.mode == MODE_S);
        ASSERT(request2.convertMode == MODE_NONE);
        ASSERT(notify2.numNotifies == 0);

        // Free the remaining locks so the LockManager destructor does not complain
        lockMgr.unlock(&request1);
        lockMgr.unlock(&request2);
    }
Esempio n. 30
0
TEST(LockManager, CompatibleFirstCancelWaiting) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_GLOBAL, 0);

    MMAPV1LockerImpl lockerSInitial;
    LockRequestCombo requestSInitial(&lockerSInitial);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &requestSInitial, MODE_S));

    MMAPV1LockerImpl lockerX;
    LockRequestCombo requestX(&lockerX);
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));

    MMAPV1LockerImpl lockerPending;
    LockRequestCombo requestPending(&lockerPending);
    requestPending.compatibleFirst = true;
    ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestPending, MODE_S));

    // S1 is not granted yet, so the policy should still be FIFO
    {
        MMAPV1LockerImpl lockerS;
        LockRequestCombo requestS(&lockerS);
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
        ASSERT(lockMgr.unlock(&requestS));
    }

    // Unlock S1, the policy should still be FIFO
    ASSERT(lockMgr.unlock(&requestPending));

    {
        MMAPV1LockerImpl lockerS;
        LockRequestCombo requestS(&lockerS);
        ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
        ASSERT(lockMgr.unlock(&requestS));
    }

    // Unlock remaining locks to keep the leak detection logic happy
    ASSERT(lockMgr.unlock(&requestSInitial));
    ASSERT(lockMgr.unlock(&requestX));
}