/** * Test that a change to a resource that isn't covered by a viewspec or in an impact index still triggers the discover * impacted subjects operation and returns nothing */ public function testResourceUpdateNotCoveredBySpecStillTriggersOperations() { $context = 'http://talisaspire.com/'; $labeller = new \Tripod\Mongo\Labeller(); // First add a graph $originalGraph = new \Tripod\ExtendedGraph(); $uri1 = 'http://example.com/resources/' . uniqid(); $originalGraph->add_resource_triple($uri1, RDF_TYPE, $labeller->qname_to_uri('bibo:Document')); $originalGraph->add_literal_triple($uri1, $labeller->qname_to_uri('dct:title'), 'How to speak American like a native'); $originalGraph->add_literal_triple($uri1, $labeller->qname_to_uri('dct:subject'), 'Languages -- \'Murrican'); $originalSubjectsAndPredicatesOfChange = array($labeller->uri_to_alias($uri1) => array('rdf:type', 'dct:title', 'dct:subject')); $updatedSubjectsAndPredicatesOfChange = array($labeller->uri_to_alias($uri1) => array('dct:subject')); /** @var \Tripod\Mongo\Driver|PHPUnit_Framework_MockObject_MockObject $mockTripod */ $mockTripod = $this->getMock('\\Tripod\\Mongo\\Driver', array('getDataUpdater', 'getComposite'), array('CBD_testing', 'tripod_php_testing', array('defaultContext' => $context, OP_ASYNC => array(OP_TABLES => true, OP_VIEWS => false, OP_SEARCH => true)))); $mockTripodUpdates = $this->getMock('\\Tripod\\Mongo\\Updates', array('processSyncOperations', 'queueAsyncOperations'), array($mockTripod, array(OP_ASYNC => array(OP_TABLES => true, OP_VIEWS => false, OP_SEARCH => true)))); $mockViews = $this->getMock('\\Tripod\\Mongo\\Composites\\Views', array('generateViewsForResourcesOfType'), array('tripod_php_testing', \Tripod\Mongo\Config::getInstance()->getCollectionForCBD('tripod_php_testing', 'CBD_testing'), $context)); $mockTripod->expects($this->exactly(2))->method('getDataUpdater')->will($this->returnValue($mockTripodUpdates)); $mockTripod->expects($this->exactly(2))->method('getComposite')->with(OP_VIEWS)->will($this->returnValue($mockViews)); $mockTripodUpdates->expects($this->exactly(2))->method('processSyncOperations')->withConsecutive(array($this->equalTo($originalSubjectsAndPredicatesOfChange), $this->equalTo($context)), array($this->equalTo($updatedSubjectsAndPredicatesOfChange), $this->equalTo($context))); $mockTripodUpdates->expects($this->exactly(2))->method('queueAsyncOperations')->withConsecutive(array($this->equalTo($originalSubjectsAndPredicatesOfChange), $this->equalTo($context)), array($this->equalTo($updatedSubjectsAndPredicatesOfChange), $this->equalTo($context))); $mockViews->expects($this->never())->method('generateViewsForResourcesOfType'); $mockTripod->saveChanges(new \Tripod\ExtendedGraph(), $originalGraph); /** @var \Tripod\Mongo\Composites\Views $view */ $view = $mockTripod->getComposite(OP_VIEWS); $this->assertInstanceOf('\\Tripod\\Mongo\\Composites\\Views', $view); $impactedSubjects = $view->getImpactedSubjects($originalSubjectsAndPredicatesOfChange, $context); $this->assertEmpty($impactedSubjects); $newGraph = $originalGraph->get_subject_subgraph($uri1); $newGraph->replace_literal_triple($uri1, $labeller->qname_to_uri('dct:subject'), 'Languages -- \'Murrican', 'Languages -- English, American'); $mockTripod->saveChanges($originalGraph, $newGraph); /** @var \Tripod\Mongo\Composites\Views $view */ $view = $mockTripod->getComposite(OP_VIEWS); $this->assertInstanceOf('\\Tripod\\Mongo\\Composites\\Views', $view); $impactedSubjects = $view->getImpactedSubjects($updatedSubjectsAndPredicatesOfChange, $context); $this->assertEmpty($impactedSubjects); }
public function testTransactionLogIsWrittenToCorrectDBAndCollection() { $storeName = 'tripod_php_testing'; $newConfig = \Tripod\Mongo\Config::getConfig(); $newConfig['transaction_log']['database'] = 'tripod_php_testing_transaction_log'; $newConfig['transaction_log']['collection'] = 'transaction_log'; \Tripod\Mongo\Config::setConfig($newConfig); $config = \Tripod\Mongo\Config::getInstance(); // Clear out any old data $tlogDB = $config->getTransactionLogDatabase(); $tlogDB->drop(); // Make sure the dbs do not exist $transactionConnInfo = $newConfig['data_sources'][$newConfig['transaction_log']['data_source']]; $options = isset($transactionConnInfo['replicaSet']) && !empty($transactionConnInfo['replicaSet']) ? array('replicaSet' => $transactionConnInfo['replicaSet']) : array(); $transactionMongo = new Client($transactionConnInfo['connection'], $options); $transactionDbInfo = $transactionMongo->listDatabases(); foreach ($transactionDbInfo as $db) { $this->assertNotEquals($db->getName(), $newConfig['transaction_log']['database']); } $tqueuesConnInfo = $newConfig['data_sources'][$newConfig['transaction_log']['data_source']]; $options = isset($tqueuesConnInfo['replicaSet']) && !empty($tqueuesConnInfo['replicaSet']) ? array('replicaSet' => $tqueuesConnInfo['replicaSet']) : array(); $queuesMongo = new Client($tqueuesConnInfo['connection'], $options); $queuesDbInfo = $queuesMongo->listDatabases(); foreach ($queuesDbInfo as $db) { $this->assertNotEquals($db->getName(), $newConfig['transaction_log']['database']); } // Start adding some data $this->tripod = new \Tripod\Mongo\Driver('CBD_testing', $storeName, array(OP_ASYNC => array(OP_VIEWS => true, OP_TABLES => false, OP_SEARCH => false))); $this->loadResourceDataViaTripod(); $graph = new \Tripod\Mongo\MongoGraph(); $subject = 'http://example.com/' . uniqid(); $labeller = new \Tripod\Mongo\Labeller(); $graph->add_resource_triple($subject, RDF_TYPE, $labeller->qname_to_uri('foaf:Person')); $graph->add_literal_triple($subject, FOAF_NAME, "Anne Example"); $this->tripod->saveChanges(new \Tripod\ExtendedGraph(), $graph); $newGraph = $this->tripod->describeResource($subject); $newGraph->add_literal_triple($subject, $labeller->qname_to_uri('foaf:email'), '*****@*****.**'); $this->tripod->saveChanges($graph, $newGraph); // Make sure the dbs do now exist $transactionDbInfo = $transactionMongo->listDatabases(); $transactionDbExists = false; foreach ($transactionDbInfo as $db) { if ($db->getName() === $newConfig['transaction_log']['database']) { $transactionDbExists = true; } } $this->assertTrue($transactionDbExists); // Make sure the data in the dbs look right $transactionColletion = $transactionMongo->selectCollection($newConfig['transaction_log']['database'], $newConfig['transaction_log']['collection']); $transactionCount = $transactionColletion->count(); $transactionExampleDocument = $transactionColletion->findOne(); $this->assertEquals(24, $transactionCount); $this->assertContains('transaction_', $transactionExampleDocument["_id"]); }
public function testRemoveTableSpecDoesNotAffectInvalidation() { foreach (\Tripod\Mongo\Config::getInstance()->getTableSpecifications($this->tripod->getStoreName()) as $specId => $spec) { $this->generateTableRows($specId); } $context = 'http://talisaspire.com/'; $uri = "http://talisaspire.com/works/4d101f63c10a6"; $collection = \Tripod\Mongo\Config::getInstance()->getCollectionForTable('tripod_php_testing', 't_resource'); $this->assertGreaterThan(0, $collection->count(array('_id.type' => 't_resource', 'value._impactIndex' => array(_ID_RESOURCE => $uri, _ID_CONTEXT => $context)))); $config = \Tripod\Mongo\Config::getConfig(); unset($config['stores']['tripod_php_testing']['table_specifications'][0]); \Tripod\Mongo\Config::setConfig($config); /** @var PHPUnit_Framework_MockObject_MockObject|\Tripod\Mongo\Driver $mockTripod */ $mockTripod = $this->getMockBuilder('\\Tripod\\Mongo\\Driver')->setMethods(array('getComposite'))->setConstructorArgs(array('CBD_testing', 'tripod_php_testing', array('defaultContext' => $context, OP_ASYNC => array(OP_VIEWS => true, OP_TABLES => false, OP_SEARCH => true))))->getMock(); $mockTables = $this->getMockBuilder('\\Tripod\\Mongo\\Composites\\Tables')->setMethods(array('update'))->setConstructorArgs(array('tripod_php_testing', \Tripod\Mongo\Config::getInstance()->getCollectionForCBD('tripod_php_testing', 'CBD_testing'), $context))->getMock(); $labeller = new \Tripod\Mongo\Labeller(); $mockTripod->expects($this->once())->method('getComposite')->with(OP_TABLES)->will($this->returnValue($mockTables)); $mockTables->expects($this->never())->method('update'); $originalGraph = $mockTripod->describeResource($uri); $updatedGraph = $originalGraph->get_subject_subgraph($uri); $updatedGraph->add_literal_triple($uri, $labeller->qname_to_uri('dct:description'), 'Physics textbook'); $mockTripod->saveChanges($originalGraph, $updatedGraph); // The table row should still be there, even if the tablespec no longer exists $this->assertGreaterThan(0, $collection->count(array('_id.type' => 't_resource', 'value._impactIndex' => array(_ID_RESOURCE => $uri, _ID_CONTEXT => $context)))); }
public function testDeleteResourceCreatesImpactedSubjects() { $uri = 'http://example.com/resources/' . uniqid(); $labeller = new Tripod\Mongo\Labeller(); $uriAlias = $labeller->uri_to_alias($uri); $creatorUri = 'http://example.com/identities/oscar-wilde'; $creatorUriAlias = $labeller->uri_to_alias($creatorUri); $graph = new \Tripod\ExtendedGraph(); $graph->add_resource_triple($uri, RDF_TYPE, $labeller->qname_to_uri('acorn:Resource')); $graph->add_resource_triple($uri, RDF_TYPE, $labeller->qname_to_uri('bibo:Book')); $graph->add_literal_triple($uri, $labeller->qname_to_uri('dct:title'), 'The Importance of Being Earnest'); $graph->add_literal_triple($uri, $labeller->qname_to_uri('dct:subject'), 'Plays -- Satire'); $graph->add_resource_triple($uri, $labeller->qname_to_uri('dct:creator'), $creatorUri); $uri2 = 'http://example.com/resources/' . uniqid(); $uriAlias2 = $labeller->uri_to_alias($uri2); $graph2 = new \Tripod\ExtendedGraph(); $graph2->add_resource_triple($uri2, RDF_TYPE, $labeller->qname_to_uri('acorn:Resource')); $graph2->add_resource_triple($uri2, RDF_TYPE, $labeller->qname_to_uri('bibo:Book')); $graph2->add_literal_triple($uri2, $labeller->qname_to_uri('dct:title'), 'The Picture of Dorian Gray'); $graph2->add_literal_triple($uri2, $labeller->qname_to_uri('dct:subject'), 'Portraits -- Fiction'); $graph2->add_resource_triple($uri2, $labeller->qname_to_uri('dct:creator'), $creatorUri); $graph3 = new \Tripod\ExtendedGraph(); $graph3->add_resource_triple($creatorUri, RDF_TYPE, $labeller->qname_to_uri('foaf:Person')); $graph3->add_literal_triple($creatorUri, $labeller->qname_to_uri('foaf:name'), 'Oscar Wilde'); // Save the graphs and ensure that table rows are generated $tripod = new \Tripod\Mongo\Driver($this->defaultPodName, $this->defaultStoreName, array('defaultContext' => $this->defaultContext, OP_ASYNC => array(OP_VIEWS => false, OP_TABLES => false, OP_SEARCH => false))); // Save the author graph first so the joins work $tripod->saveChanges(new \Tripod\ExtendedGraph(), $graph3); $tripod->saveChanges(new \Tripod\ExtendedGraph(), $graph); $collection = \Tripod\Mongo\Config::getInstance()->getCollectionForSearchDocument($this->defaultStoreName, 'i_search_resource'); $query = array(_ID_KEY => array(_ID_RESOURCE => $uriAlias, _ID_CONTEXT => $this->defaultContext, _ID_TYPE => 'i_search_resource')); $this->assertEquals(1, $collection->count($query)); $tripod->saveChanges(new \Tripod\ExtendedGraph(), $graph2); $query[_ID_KEY][_ID_RESOURCE] = $uriAlias2; $this->assertEquals(1, $collection->count($query)); $impactQuery = array(_ID_KEY . '.' . _ID_TYPE => 'i_search_resource', '_impactIndex' => array(_ID_RESOURCE => $creatorUriAlias, _ID_CONTEXT => $this->defaultContext), 'result.author' => 'Oscar Wilde'); $this->assertEquals(2, $collection->count($impactQuery)); /** @var \Tripod\Mongo\Driver|PHPUnit_Framework_MockObject_MockObject $mockTripod */ $mockTripod = $this->getMockBuilder('\\Tripod\\Mongo\\Driver')->setMethods(array('getDataUpdater'))->setConstructorArgs(array($this->defaultPodName, $this->defaultStoreName, array('defaultContext' => $this->defaultContext, OP_ASYNC => array(OP_VIEWS => false, OP_TABLES => false, OP_SEARCH => false))))->getMock(); $mockTripodUpdates = $this->getMockBuilder('\\Tripod\\Mongo\\Updates')->setConstructorArgs(array($mockTripod, array('defaultContext' => $this->defaultContext, OP_ASYNC => array(OP_VIEWS => false, OP_TABLES => false, OP_SEARCH => false))))->setMethods(array('processSyncOperations'))->getMock(); $mockTripod->expects($this->once())->method('getDataUpdater')->will($this->returnValue($mockTripodUpdates)); $expectedSubjectsAndPredicatesOfChange = array($creatorUriAlias => array('rdf:type', 'foaf:name')); $mockTripodUpdates->expects($this->once())->method('processSyncOperations')->with($expectedSubjectsAndPredicatesOfChange, $this->defaultContext); // Delete creator resource $mockTripod->saveChanges($graph3, new \Tripod\ExtendedGraph()); $deletedGraph = $mockTripod->describeResource($creatorUri); $this->assertTrue($deletedGraph->is_empty()); // Manually walk through the tables operation /** @var \Tripod\Mongo\Composites\SearchIndexer $search */ $search = $mockTripod->getComposite(OP_SEARCH); $expectedImpactedSubjects = array(new \Tripod\Mongo\ImpactedSubject(array(_ID_RESOURCE => $uriAlias, _ID_CONTEXT => $this->defaultContext), OP_SEARCH, $this->defaultStoreName, $this->defaultPodName, array('i_search_resource')), new \Tripod\Mongo\ImpactedSubject(array(_ID_RESOURCE => $uriAlias2, _ID_CONTEXT => $this->defaultContext), OP_SEARCH, $this->defaultStoreName, $this->defaultPodName, array('i_search_resource'))); $this->assertEquals($expectedImpactedSubjects, $search->getImpactedSubjects($expectedSubjectsAndPredicatesOfChange, $this->defaultContext)); foreach ($expectedImpactedSubjects as $subject) { $search->update($subject); } $query = array(_ID_KEY => array(_ID_RESOURCE => $uriAlias, _ID_CONTEXT => $this->defaultContext, _ID_TYPE => 'i_search_resource')); $this->assertEquals(1, $collection->count($query)); $query[_ID_KEY][_ID_RESOURCE] = $uriAlias2; $this->assertEquals(1, $collection->count($query)); // Deleted resource will still be impact indexes because join still exists $impactQuery = array(_ID_KEY . '.' . _ID_TYPE => 'i_search_resource', '_impactIndex' => array(_ID_RESOURCE => $creatorUriAlias, _ID_CONTEXT => $this->defaultContext)); $this->assertEquals(2, $collection->count($impactQuery)); // But the document should have been regenerated without the value $impactQuery['result.author'] = 'Oscar Wilde'; $this->assertEquals(0, $collection->count($impactQuery)); }