public function testTransactionRollbackDuringApplyChanges() { // Save some basic data into the db before we create a transaction to modify it $subjectOne = 'http://example.com/resources/1'; $subjectTwo = 'http://example.com/resources/2'; $doc1 = array('_id' => array('r' => $subjectOne, 'c' => 'http://talisaspire.com/'), 'rdf:type' => array('u' => 'acorn:Resource'), 'dct:title' => array(array('l' => 'Title one'), array('l' => 'Title two')), '_version' => 0, '_cts' => \Tripod\Mongo\DateUtil::getMongoDate(), '_uts' => \Tripod\Mongo\DateUtil::getMongoDate()); $doc2 = array('_id' => array('r' => $subjectTwo, 'c' => 'http://talisaspire.com/'), 'rdf:type' => array('u' => 'acorn:Book'), 'dct:title' => array(array('l' => 'Title three'), array('l' => 'Title four')), '_version' => 0, '_cts' => \Tripod\Mongo\DateUtil::getMongoDate(), '_uts' => \Tripod\Mongo\DateUtil::getMongoDate()); $this->addDocument($doc1); $this->addDocument($doc2); // now lets modify the data using tripod $g1 = $this->tripod->describeResources(array($subjectOne), 'http://talisaspire.com/'); $g2 = $this->tripod->describeResources(array($subjectTwo), 'http://talisaspire.com/'); $oG = new \Tripod\Mongo\MongoGraph(); $oG->add_graph($g1); $oG->add_graph($g2); $nG = new \Tripod\Mongo\MongoGraph(); $nG->add_graph($oG); $nG->remove_literal_triple($subjectOne, $nG->qname_to_uri("dct:title"), "Title one"); $nG->add_literal_triple($subjectOne, $nG->qname_to_uri("dct:title"), "Updated Title one"); $nG->remove_literal_triple($subjectTwo, $nG->qname_to_uri("dct:title"), "Title three"); $nG->add_literal_triple($subjectTwo, $nG->qname_to_uri("dct:title"), "Updated Title three"); $mockTransactionId = 'transaction_1'; $mockTripod = $this->getMock('\\Tripod\\Mongo\\Driver', array('getDataUpdater'), array('CBD_testing', 'tripod_php_testing', array('defaultContext' => 'http://talisaspire.com/'))); $mockTripodUpdate = $this->getMock('\\Tripod\\Mongo\\Updates', array('generateTransactionId', 'lockSingleDocument', 'applyChangeSet'), array($mockTripod)); $mockTripodUpdate->expects($this->exactly(1))->method('generateTransactionId')->will($this->returnValue($mockTransactionId)); $mockTripodUpdate->expects($this->exactly(2))->method('lockSingleDocument')->will($this->returnCallback(array($this, 'lockSingleDocumentCallback'))); $mockTripodUpdate->expects($this->once())->method('applyChangeSet')->will($this->throwException(new Exception("Exception throw by mock test during applychangeset"))); $mockTripod->expects($this->atLeastOnce())->method('getDataUpdater')->will($this->returnValue($mockTripodUpdate)); /** @var $mockTripod \Tripod\Mongo\Driver */ $mockTripod->setTransactionLog($this->tripodTransactionLog); try { $mockTripod->saveChanges($oG, $nG, "http://talisaspire.com/"); $this->fail('Exception should have been thrown'); } catch (\Tripod\Exceptions\Exception $e) { // Squash the exception here as we need to continue running the assertions. } // make sure the subjects werent changed $uG = $this->tripod->describeResources(array($subjectOne, $subjectTwo)); $this->assertTrue($uG->has_resource_triple($subjectOne, $uG->qname_to_uri("rdf:type"), $uG->qname_to_uri("acorn:Resource"))); $this->assertTrue($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Title one')); $this->assertTrue($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Title two')); $this->assertFalse($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Updated Title two')); $this->assertTrue($uG->has_resource_triple($subjectTwo, $uG->qname_to_uri("rdf:type"), $uG->qname_to_uri("acorn:Book"))); $this->assertTrue($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Title three')); $this->assertTrue($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Title four')); $this->assertFalse($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Updated Title three')); $this->assertDocumentDoesNotHaveProperty(array('r' => $subjectOne, 'c' => 'http://talisaspire.com/'), _LOCKED_FOR_TRANS, $this->tripod); $this->assertDocumentDoesNotHaveProperty(array('r' => $subjectOne, 'c' => 'http://talisaspire.com/'), _LOCKED_FOR_TRANS_TS, $this->tripod); $this->assertDocumentDoesNotHaveProperty(array('r' => $subjectTwo, 'c' => 'http://talisaspire.com/'), _LOCKED_FOR_TRANS, $this->tripod); $this->assertDocumentDoesNotHaveProperty(array('r' => $subjectTwo, 'c' => 'http://talisaspire.com/'), _LOCKED_FOR_TRANS_TS, $this->tripod); $transaction = $mockTripodUpdate->getTransactionLog()->getTransaction($mockTransactionId); $this->assertNotNull($transaction); $this->assertEquals("Exception throw by mock test during applychangeset", $transaction['error']['reason']); $this->assertEquals("failed", $transaction['status']); }
public function testTransactionIsLoggedCorrectlyWhenCompletedSuccessfully() { // STEP 1 $uri = 'http://example.com/resources/1'; // save a new entity, and retrieve it $g = new \Tripod\Mongo\MongoGraph(); $g->add_resource_triple($uri, $g->qname_to_uri("rdf:type"), $g->qname_to_uri("acorn:Resource")); $g->add_literal_triple($uri, $g->qname_to_uri("dct:title"), "wibble"); $mTripod = $this->getMock('\\Tripod\\Mongo\\Driver', array('getDataUpdater'), array('CBD_testing', 'tripod_php_testing')); $mTripodUpdate = $this->getMock('\\Tripod\\Mongo\\Updates', array('getUniqId'), array($mTripod)); $mTripodUpdate->expects($this->atLeastOnce())->method('getUniqId')->will($this->returnValue(1)); $mTripod->expects($this->atLeastOnce())->method('getDataUpdater')->will($this->returnValue($mTripodUpdate)); $mTripod->setTransactionLog($this->tripodTransactionLog); $mTripod->saveChanges(new \Tripod\Mongo\MongoGraph(), $g, 'http://talisaspire.com/'); // assert that the transaction in the transaction log is correct $transactionId = 'transaction_1'; $transactionDocument = $this->getDocument($transactionId, $this->tripod, true); $this->assertEquals($transactionId, $transactionDocument['_id'], 'transtion should have the mocked id we injected'); $this->assertEquals('completed', $transactionDocument['status'], 'status of the transaction should be completed'); $this->assertEquals(1, count($transactionDocument['originalCBDs']), 'There should only be on CBD in the originalCBs collection'); $this->assertTransactionDate($transactionDocument, 'startTime'); $this->assertTransactionDate($transactionDocument, 'endTime'); $this->assertTrue(isset($transactionDocument['changes']), "Transaction should contain changes"); $this->assertChangesForGivenSubject($transactionDocument['changes'], $uri, 2, 0); $expectedCBD = array('_id' => array('r' => 'http://example.com/resources/1', 'c' => 'http://talisaspire.com/')); $actualCBD = $transactionDocument['originalCBDs'][0]; $this->assertEquals($expectedCBD, $actualCBD, 'CBD in transaction should match our expected value exactly'); // STEP 2 // update the same entity with an addition $mTripod = null; $mTripod = $this->getMock('\\Tripod\\Mongo\\Driver', array('getDataUpdater'), array('CBD_testing', 'tripod_php_testing')); $mTripodUpdate = $this->getMock('\\Tripod\\Mongo\\Updates', array('getUniqId'), array($mTripod)); $mTripodUpdate->expects($this->atLeastOnce())->method('getUniqId')->will($this->returnValue(2)); $mTripod->expects($this->atLeastOnce())->method('getDataUpdater')->will($this->returnValue($mTripodUpdate)); $mTripod->setTransactionLog($this->tripodTransactionLog); $nG = new \Tripod\Mongo\MongoGraph(); $nG->add_graph($g); $nG->add_literal_triple($uri, $g->qname_to_uri("dct:title"), "another title"); $mTripod->saveChanges($g, $nG, 'http://talisaspire.com/'); // assert this transaction is correct $transactionId = 'transaction_2'; $transactionDocument = $this->getDocument($transactionId, $this->tripod, true); $this->assertEquals($transactionId, $transactionDocument['_id'], 'transtion should have the mocked id we injected'); $this->assertEquals('completed', $transactionDocument['status'], 'status of the transaction should be completed'); $this->assertEquals(1, count($transactionDocument['originalCBDs']), 'There should only be on CBD in the originalCBs collection'); $this->assertTransactionDate($transactionDocument, 'startTime'); $this->assertTransactionDate($transactionDocument, 'endTime'); $this->assertTrue(isset($transactionDocument['changes']), "Transaction should contain changes"); $this->assertChangesForGivenSubject($transactionDocument['changes'], $uri, 1, 0); $expectedCBD = array('_id' => array('r' => 'http://example.com/resources/1', 'c' => 'http://talisaspire.com/'), '_version' => 0, "dct:title" => array('l' => 'wibble'), "rdf:type" => array('u' => "acorn:Resource")); $actualCBD = $transactionDocument['originalCBDs'][0]; // TODO: find a better way of doing this, for now we set the expected created ts and updated ts to the same as actual or test will fail $expectedCBD[_UPDATED_TS] = $actualCBD[_UPDATED_TS]; $expectedCBD[_CREATED_TS] = $actualCBD[_CREATED_TS]; // sort the keys in both arrays to ensure equals check works (it will fail if the keys are in a different order) ksort($actualCBD); ksort($expectedCBD); $this->assertEquals($expectedCBD, $actualCBD, 'CBD in transaction should match our expected value exactly'); // STEP 3 // update the same entity with a removal $mTripod = null; $mTripod = $this->getMock('\\Tripod\\Mongo\\Driver', array('getDataUpdater'), array('CBD_testing', 'tripod_php_testing')); $mTripodUpdate = $this->getMock('\\Tripod\\Mongo\\Updates', array('getUniqId'), array($mTripod)); $mTripodUpdate->expects($this->atLeastOnce())->method('getUniqId')->will($this->returnValue(3)); $mTripod->expects($this->atLeastOnce())->method('getDataUpdater')->will($this->returnValue($mTripodUpdate)); $mTripod->setTransactionLog($this->tripodTransactionLog); $g = new \Tripod\Mongo\MongoGraph(); $g->add_graph($nG); $g->remove_literal_triple($uri, $g->qname_to_uri("dct:title"), "another title"); $mTripod->saveChanges($nG, $g, 'http://talisaspire.com/'); // assert this transaction $transactionId = 'transaction_3'; $transactionDocument = $this->getDocument($transactionId, $this->tripod, true); $this->assertEquals($transactionId, $transactionDocument['_id'], 'transtion should have the mocked id we injected'); $this->assertEquals('completed', $transactionDocument['status'], 'status of the transaction should be completed'); $this->assertEquals(1, count($transactionDocument['originalCBDs']), 'There should only be on CBD in the originalCBs collection'); $this->assertTransactionDate($transactionDocument, 'startTime'); $this->assertTransactionDate($transactionDocument, 'endTime'); $this->assertTrue(isset($transactionDocument['changes']), "Transaction should contain changes"); $this->assertChangesForGivenSubject($transactionDocument['changes'], $uri, 0, 1); $expectedCBD = array('_id' => array('r' => 'http://example.com/resources/1', 'c' => 'http://talisaspire.com/'), '_version' => 1, "dct:title" => array(array('l' => 'wibble'), array('l' => 'another title')), "rdf:type" => array('u' => "acorn:Resource")); $actualCBD = $transactionDocument['originalCBDs'][0]; // TODO: find a better way of doing this, for now we set the expected created ts and updated ts to the same as actual or test will fail $expectedCBD[_UPDATED_TS] = $actualCBD[_UPDATED_TS]; $expectedCBD[_CREATED_TS] = $actualCBD[_CREATED_TS]; // sort the keys in both arrays to ensure equals check works (it will fail if the keys are in a different order) ksort($actualCBD); ksort($expectedCBD); $this->assertEquals($expectedCBD, $actualCBD, 'CBD in transaction should match our expected value exactly'); }
public function testSaveChangesToMultipleSubjects() { $subjectOne = 'http://example.com/resources/1'; $subjectTwo = 'http://example.com/resources/2'; // save a graph to the store containng two completely new entities $oG = new \Tripod\Mongo\MongoGraph(); $oG->add_resource_triple($subjectOne, $oG->qname_to_uri("rdf:type"), $oG->qname_to_uri("acorn:Resource")); $oG->add_literal_triple($subjectOne, $oG->qname_to_uri("dct:title"), "Title one"); $oG->add_literal_triple($subjectOne, $oG->qname_to_uri("dct:title"), "Title two"); $oG->add_resource_triple($subjectTwo, $oG->qname_to_uri("rdf:type"), $oG->qname_to_uri("acorn:Book")); $oG->add_literal_triple($subjectTwo, $oG->qname_to_uri("dct:title"), "Title three"); $oG->add_literal_triple($subjectTwo, $oG->qname_to_uri("dct:title"), "Title four"); $this->tripod->saveChanges(new \Tripod\Mongo\MongoGraph(), $oG, "http://talisaspire.com/"); // retrieve them both, assert they are as we expect $g = $this->tripod->describeResources(array($subjectOne, $subjectTwo)); $this->assertTrue($g->has_triples_about($subjectOne)); $this->assertTrue($g->has_resource_triple($subjectOne, $g->qname_to_uri("rdf:type"), $g->qname_to_uri("acorn:Resource"))); $this->assertTrue($g->has_literal_triple($subjectOne, $g->qname_to_uri("dct:title"), 'Title one')); $this->assertTrue($g->has_literal_triple($subjectOne, $g->qname_to_uri("dct:title"), 'Title two')); $this->assertTrue($g->has_triples_about($subjectTwo)); $this->assertTrue($g->has_resource_triple($subjectTwo, $g->qname_to_uri("rdf:type"), $g->qname_to_uri("acorn:Book"))); $this->assertTrue($g->has_literal_triple($subjectTwo, $g->qname_to_uri("dct:title"), 'Title three')); $this->assertTrue($g->has_literal_triple($subjectTwo, $g->qname_to_uri("dct:title"), 'Title four')); // now lets save some changes to both $nG = new \Tripod\Mongo\MongoGraph(); $nG->add_graph($g); $nG->remove_literal_triple($subjectOne, $g->qname_to_uri("dct:title"), 'Title one'); $nG->add_literal_triple($subjectOne, $g->qname_to_uri("dct:title"), 'Updated Title one'); $nG->add_literal_triple($subjectOne, $g->qname_to_uri("dct:author"), 'Joe Bloggs'); $nG->remove_literal_triple($subjectTwo, $g->qname_to_uri("dct:title"), 'Title four'); $nG->remove_resource_triple($subjectTwo, $g->qname_to_uri("rdf:type"), $g->qname_to_uri("acorn:Book")); $nG->add_literal_triple($subjectTwo, $g->qname_to_uri("dct:title"), 'Updated Title four'); $nG->add_literal_triple($subjectTwo, $g->qname_to_uri("dct:author"), 'James Brown'); $this->tripod->saveChanges($g, $nG, "http://talisaspire.com/"); $uG = $this->tripod->describeResources(array($subjectOne, $subjectTwo)); $this->assertTrue($uG->has_triples_about($subjectOne)); $this->assertTrue($uG->has_resource_triple($subjectOne, $uG->qname_to_uri("rdf:type"), $uG->qname_to_uri("acorn:Resource"))); $this->assertTrue($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Updated Title one')); $this->assertFalse($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Title one')); $this->assertTrue($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:title"), 'Title two')); $this->assertTrue($uG->has_literal_triple($subjectOne, $uG->qname_to_uri("dct:author"), 'Joe Bloggs')); $this->assertTrue($uG->has_triples_about($subjectTwo)); $this->assertFalse($uG->has_resource_triple($subjectTwo, $uG->qname_to_uri("rdf:type"), $uG->qname_to_uri("acorn:Book"))); $this->assertTrue($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Title three')); $this->assertTrue($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Updated Title four')); $this->assertFalse($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:title"), 'Title four')); $this->assertTrue($uG->has_literal_triple($subjectTwo, $uG->qname_to_uri("dct:author"), 'James Brown')); }