SeekquarrySeekquarry - Yioop Repo - Seekquarry

/ tests / MessagesBundleTest.php⤓
<?php
/**
 * SeekQuarry/Yioop --
 * Open Source Pure PHP Search Engine, Crawler, and Indexer
 *
 * Copyright (C) 2009 - 2026  Chris Pollett chris@pollett.org
 *
 * LICENSE:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * END LICENSE
 *
 * @author Chris Pollett chris@pollett.org
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
namespace seekquarry\yioop\tests;

use seekquarry\yioop\configs as C;
use seekquarry\yioop\library\UnitTest;
use seekquarry\yioop\models\Model;
use seekquarry\yioop\library\storage_formats\MessagesBundle;

/**
 * MessagesBundleTest checks the send window that hands fetch batches to
 * fetchers: how long a batch may be out before it is offered again, and
 * that the window still reads batch files written before the batch size
 * was kept in the name.
 *
 * @author Chris Pollett
 */
class MessagesBundleTest extends UnitTest
{
    /**
     * The folder the test's messages bundle is made in
     * @var string
     */
    public $dir;
    /**
     * Makes an empty messages bundle folder for each case.
     */
    public function setUp()
    {
        $this->dir = C\TEST_DIR . "/test_files/MessagesBundleTest";
        $this->tearDown();
        mkdir($this->dir, 0777, true);
    }
    /**
     * Removes the test's messages bundle folder.
     */
    public function tearDown()
    {
        if (file_exists($this->dir)) {
            (new Model())->db->unlinkRecursive($this->dir, true);
        }
    }
    /**
     * smallBatchIsOfferedAgainSoonTestCase checks that a batch of one url
     * that has been out longer than the time one pass of urls needs is
     * offered to a fetcher again, while a full batch out for the same time
     * is not: a full batch is allowed the whole SCHEDULE_TIMEOUT and a
     * smaller one a share of it.
     */
    public function smallBatchIsOfferedAgainSoonTestCase()
    {
        $one_pass = MessagesBundle::scheduleTimeout(1);
        $full = MessagesBundle::scheduleTimeout(C\MAX_FETCH_SIZE);
        $this->assertTrue($one_pass < $full,
            "a one url batch is allowed less time than a full one");
        $this->assertEqual(C\SCHEDULE_TIMEOUT, $full,
            "a full batch is allowed the whole schedule timeout");
        $this->assertEqual(C\SCHEDULE_TIMEOUT,
            MessagesBundle::scheduleTimeout(0),
            "a batch of unknown size is allowed the whole timeout");
        $bundle = new MessagesBundle($this->dir);
        $bundle->window_size = 8;
        $bundle->initWindows();
        $small = $this->dir . "/small.txt";
        file_put_contents($small, "one url");
        $bundle->insertSendWindow($small, 1);
        $bundle->extractSendWindow();
        $this->assertTrue(count(glob($this->dir . "/send/*")) == 1,
            "the batch went out once and stays in the window");
        foreach ($bundle->send as $sequence => $item) {
            $old = $bundle->makeSendWindowFilename($sequence,
                time() - $one_pass - 1, $item['tries'], 1);
            rename($item['file'], $old);
        }
        $bundle->initWindows();
        $this->assertTrue($bundle->extractSendWindow() !== false,
            "a one url batch out longer than one pass is offered again");
    }
    /**
     * batchThatWaitedGoesOutOnceTestCase checks that the timeout of a full
     * batch made most of SCHEDULE_TIMEOUT ago, but not asked for by a
     * fetcher until now, starts when a fetcher gets it. Otherwise the
     * batch is sent to a second fetcher soon after the first gets it.
     */
    public function batchThatWaitedGoesOutOnceTestCase()
    {
        mkdir($this->dir . "/send", 0777, true);
        mkdir($this->dir . "/receive", 0777, true);
        $bundle = new MessagesBundle($this->dir);
        $now = time();
        file_put_contents($bundle->makeSendWindowFilename(1,
            $now - C\SCHEDULE_TIMEOUT + 60, 0, C\MAX_FETCH_SIZE), "batch");
        $bundle->initWindows();
        $this->assertEqual("batch", $bundle->extractSendWindow(),
            "the first fetcher to ask gets the batch");
        $bundle->initWindows();
        $this->assertTrue($bundle->send[1]['schedule_time'] >= $now,
            "its timeout starts when the fetcher got it");
    }
    /**
     * oldWindowNameStillReadsTestCase checks that a send window file named
     * the way batches were named before the size was kept, three parts
     * rather than four, is still read into the window and given the whole
     * schedule timeout.
     */
    public function oldWindowNameStillReadsTestCase()
    {
        mkdir($this->dir . "/send", 0777, true);
        mkdir($this->dir . "/receive", 0777, true);
        file_put_contents($this->dir . "/send/3-1000-0.txt", "old batch");
        $bundle = new MessagesBundle($this->dir);
        $bundle->window_size = 8;
        $bundle->initWindows();
        $this->assertTrue(isset($bundle->send[3]),
            "the three part name is read into the window");
        $this->assertEqual(0, $bundle->send[3]['num_urls'],
            "its size is not known");
    }
}