View source
<?php
abstract class AbstractDrupalSolrOnlineWebTestCase extends DrupalWebTestCase {
protected $solr;
protected $solr_available = FALSE;
function setUp() {
$modules = func_get_args();
if (isset($modules[0]) && is_array($modules[0])) {
$modules = $modules[0];
}
$modules[] = 'apachesolr';
$modules[] = 'apachesolr_search';
$modules[] = 'search';
parent::setUp($modules);
}
function setUpSolr() {
$env_id = apachesolr_default_environment();
$environment = apachesolr_environment_load($env_id);
$this->base_solr_url = $environment['url'];
$this->core_admin_url = "{$this->base_solr_url}/admin/cores";
if ($this
->coreAdminAvailable()) {
$environment['url'] .= '/' . $this->databasePrefix;
$filesdir = file_directory_temp();
drupal_mkdir("{$filesdir}/solr", 0777, TRUE);
$instancedir = realpath($filesdir . "/solr");
$version = $this
->getSolrVersion();
if (isset($version) && $version == 3) {
$conf_path = dirname(__FILE__) . '/../solr-conf/solr-3.x/*';
}
elseif (isset($version) && $version == 4) {
$conf_path = dirname(__FILE__) . '/../solr-conf/solr-4.x/*';
}
else {
$conf_path = dirname(__FILE__) . '/../solr-conf/solr-1.4/*';
}
$patterns = array(
$conf_path,
dirname(__FILE__) . '/conf/*',
);
drupal_mkdir("{$instancedir}/conf", 0777, TRUE);
foreach ($patterns as $pattern) {
foreach (glob($pattern) as $conf_file) {
copy($conf_file, "{$instancedir}/conf/" . basename($conf_file));
}
}
$contents = file_get_contents("{$instancedir}/conf/solrconfig.xml");
file_put_contents("{$instancedir}/conf/solrconfig.xml", preg_replace('@<maxTime>[0-9]+</maxTime>@', '<maxTime>1000</maxTime>', $contents));
system("chmod -R 777 {$instancedir}");
$query['name'] = $this->databasePrefix;
$query['instanceDir'] = $instancedir;
$created = $this
->coreAdmin('CREATE', $query);
if ($created && apachesolr_server_status($environment['url'])) {
$this->instancedir = $instancedir;
$this->solr_url = $environment['url'];
apachesolr_environment_save($environment);
$this->solr = apachesolr_get_solr($env_id);
$this->solr_available = TRUE;
$this
->checkCoreStatus($this->databasePrefix);
}
}
if (!$this->solr_available) {
$this
->pass(t('Warning : The solr instance could not be found. Please enable a multicore one on http://localhost:8983/solr'));
}
}
protected function coreAdminAvailable() {
$url = url($this->core_admin_url, array(
'query' => array(
'action' => 'STATUS',
),
));
$options['timeout'] = 2;
$result = drupal_http_request($url, $options);
return $result->code == 200 && empty($result->error);
}
protected function getSolrVersion() {
$status = $this
->coreAdmin('STATUS');
foreach ($status['status'] as $core_id => $core) {
$solr = new DrupalApacheSolrService($this->base_solr_url . '/' . $core_id);
$version = $solr
->getSolrVersion();
if (!empty($version)) {
return $version;
}
else {
return "1";
}
}
}
protected function coreAdmin($action, $query = array()) {
$query['action'] = $action;
$query['wt'] = 'json';
$url = url($this->core_admin_url, array(
'query' => $query,
));
$options['timeout'] = 2;
$result = drupal_http_request($url, $options);
if ($result->code == 200) {
return json_decode($result->data, TRUE);
}
else {
return FALSE;
}
}
protected function checkCoreStatus($core_name) {
$response = $this
->coreAdmin('STATUS', array(
'core' => $core_name,
));
$this
->assertTrue(isset($response['status'][$core_name]['index']), 'Found Solr test core index status');
}
function tearDown() {
if ($this->solr_available) {
$query = array(
'core' => $this->databasePrefix,
'deleteIndex' => 'true',
'deleteDataDir' => 'true',
'deleteInstanceDir' => 'true',
);
$this
->coreAdmin('UNLOAD', $query);
}
parent::tearDown();
}
}
class DrupalSolrOnlineWebTestCase extends AbstractDrupalSolrOnlineWebTestCase {
function setUp() {
parent::setUp();
parent::setUpSolr();
}
}
class DrupalSolrMatchTestCase extends DrupalSolrOnlineWebTestCase {
public static function getInfo() {
return array(
'name' => 'Solr Index Data and test live queries',
'description' => 'Indexes content and queries it.',
'group' => 'ApacheSolr',
);
}
function testMatching() {
if ($this->solr_available) {
$this
->assertTrue($this->solr
->ping(), "The Server could be Pinged");
$response = $this->solr
->search("*:*", array());
$response = $response->response;
$this
->assertEqual($response->numFound, 0, "There should not be any documents in the index");
$this
->populateIndex(7);
$response = $this->solr
->search("*:*", array());
$response = $response->response;
$this
->assertEqual($response->numFound, 7, "There should be 7 documents in the index");
$this
->_testQueries();
}
}
protected function populateIndex($count) {
variable_set('minimum_word_size', 3);
for ($i = 1; $i <= $count; ++$i) {
$documents[] = $this
->buildDocument(array(
'entity_id' => $i,
'content' => $this
->getText($i),
));
}
$this->solr
->addDocuments($documents);
$this->solr
->commit();
}
protected function buildDocument($values = array()) {
$document = new ApacheSolrDocument();
if (!isset($values['entity_type'])) {
$values['entity_type'] = 'fake.';
}
$document->id = apachesolr_document_id($values['entity_id'], $values['entity_type']);
foreach ($values as $key => $value) {
$document->{$key} = $value;
}
return $document;
}
function getText($n) {
$n = $n % 7;
$words = explode(' ', "Ipsum dolore sit am. Ut enim am minim veniam. Es cillum dolore eu.");
return implode(' ', array_slice($words, $n - 1, $n));
}
function _testQueries() {
$queries = array(
'ipsum' => array(
1,
),
'enim' => array(
4,
5,
6,
),
'xxxxx' => array(),
'"minim am veniam es" OR "dolore sit"' => array(
2,
),
'"minim am veniam es" OR "sit dolore"' => array(),
'"am minim veniam es" -eu' => array(
6,
),
'"am minim veniam" -"cillum dolore"' => array(
5,
6,
),
);
$broken = array(
'enim minim' => array(
5,
6,
),
'enim xxxxx' => array(),
'dolore eu' => array(
7,
),
'dolore xx' => array(),
'ut minim' => array(
5,
),
'xx minim' => array(),
'enim veniam am minim ut' => array(
5,
),
'dolore OR ipsum' => array(
1,
2,
7,
),
'dolore OR xxxxx' => array(
2,
7,
),
'dolore OR ipsum OR enim' => array(
1,
2,
4,
5,
6,
7,
),
'minim dolore OR ipsum OR enim' => array(
5,
6,
7,
),
'xxxxx dolore OR ipsum' => array(),
'dolore -sit' => array(
7,
),
'dolore -eu' => array(
2,
),
'dolore -xxxxx' => array(
2,
7,
),
'dolore -xx' => array(
2,
7,
),
'"dolore sit"' => array(
2,
),
'"sit dolore"' => array(),
'"am minim veniam es"' => array(
6,
7,
),
'"minim am veniam es"' => array(),
'xxxxx "minim am veniam es" OR dolore' => array(),
'xx "minim am veniam es" OR dolore' => array(),
'"am minim veniam es" OR dolore' => array(
2,
6,
7,
),
'"am minim veniam" -"dolore cillum"' => array(
5,
6,
7,
),
);
foreach ($queries as $query => $results) {
$response = $this->solr
->search($query, array());
$this
->_testQueryMatching($query, $response->response->docs, $results);
}
}
function _testQueryMatching($query, $set, $results) {
$found = array();
foreach ($set as $item) {
$found[] = $item->entity_id;
}
sort($found);
sort($results);
$this
->assertEqual($found, $results, strtr("Query matching '{$query}' found: @found expected: @expected", array(
'@found' => implode(',', $found),
'@expected' => implode(',', $results),
)));
}
function _testQueryScores($query, $set, $results) {
$scores = array();
foreach ($set as $item) {
$scores[] = $item->score;
}
$sorted = $scores;
sort($sorted);
$this
->assertEqual($scores, array_reverse($sorted), "Query order '{$query}'");
$this
->assertEqual(!count($scores) || min($scores) > 0.0 && max($scores) <= 1.0001, TRUE, "Query scoring '{$query}'");
}
}