40 include_once(__DIR__.
'/../../../lib/php/Test/Agent/AgentTestMockHelper.php');
41 include_once(__DIR__.
'/SchedulerTestRunnerCli.php');
42 include_once(__DIR__.
'/SchedulerTestRunnerMock.php');
118 $this->testDb =
new TestPgDb(
"reuserSched");
119 $this->
dbManager = $this->testDb->getDbManager();
122 $logger =
new Logger(
"ReuserSchedulerTest");
123 $this->uploadPermDao = \Mockery::mock(UploadPermissionDao::class);
129 $this->treeDao = \Mockery::mock(TreeDao::class);
134 $this->clearingDao, $this->uploadDao, $this->clearingDecisionFilter,
135 $this->treeDao, $this->copyrightDao);
144 $this->testDb->fullDestruct();
145 $this->testDb =
null;
147 $this->licenseDao =
null;
148 $this->highlightDao =
null;
149 $this->clearingDao =
null;
150 $this->copyrightDao =
null;
158 $sysConf = $this->testDb->getFossSysConf();
160 $this->testInstaller->init();
161 $this->testInstaller->cpRepo();
169 $this->testInstaller->rmRepo();
170 $this->testInstaller->clear();
178 $this->testDb->createPlainTables(array(
'upload',
'upload_reuse',
'uploadtree',
179 'uploadtree_a',
'license_ref',
'license_ref_bulk',
'clearing_decision',
180 'clearing_decision_event',
'clearing_event',
'license_file',
'highlight',
181 'highlight_bulk',
'agent',
'pfile',
'ars_master',
'users',
'group_user_member',
182 'upload_clearing_license',
'report_info'),
false);
183 $this->testDb->createSequences(array(
'agent_agent_pk_seq',
'pfile_pfile_pk_seq',
184 'upload_upload_pk_seq',
'nomos_ars_ars_pk_seq',
'license_file_fl_pk_seq',
185 'license_ref_rf_pk_seq',
'license_ref_bulk_lrb_pk_seq',
186 'clearing_decision_clearing_decision_pk_seq',
187 'clearing_event_clearing_event_pk_seq',
'report_info_pk_seq'),
false);
188 $this->testDb->createViews(array(
'license_file_ref'),
false);
189 $this->testDb->createConstraints(array(
'agent_pkey',
'pfile_pkey',
190 'upload_pkey_idx',
'FileLicense_pkey',
'clearing_event_pkey'),
false);
191 $this->testDb->alterTables(array(
'agent',
'pfile',
'upload',
'ars_master',
192 'license_ref_bulk',
'license_ref',
'clearing_event',
'clearing_decision',
'license_file',
'highlight'),
false);
193 $this->testDb->createInheritedTables();
194 $this->testDb->createInheritedArsTables(array(
'monk'));
196 $this->testDb->insertData(array(
'pfile',
'upload',
'uploadtree_a',
'users',
197 'group_user_member',
'agent',
'license_file',
'monk_ars',
'report_info'),
199 $this->testDb->insertData_license_ref(80);
201 $this->testDb->resetSequenceAsMaxOf(
'agent_agent_pk_seq',
'agent',
'agent_pk');
203 $this->testDb->setupSysconfig();
212 if (preg_match(
"/.*HEART: ([0-9]*).*/", $output, $matches)) {
213 return intval($matches[1]);
227 $bounds = $this->uploadDao->getParentItemBounds($uploadId);
228 return $this->clearingDao->getFileClearingsFolder($bounds,
$groupId);
264 list($success, $output,$retCode) = $runner->
run($uploadId=1, $this->userId);
266 $this->assertTrue($success,
'cannot run runner');
267 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
271 $bounds = $this->uploadDao->getParentItemBounds($uploadId);
272 assertThat($this->clearingDao->getFileClearingsFolder($bounds,
$groupId=5), is(emptyArray()));
285 $licenseRef1 = $this->licenseDao->getLicenseByShortName(
"SPL-1.0")->getRef();
286 $licenseRef2 = $this->licenseDao->getLicenseByShortName(
"Glide")->getRef();
288 $addedLicenses = array($licenseRef1, $licenseRef2);
289 assertThat($addedLicenses, not(arrayContaining(
null)));
291 $clearingLicense1 =
new ClearingLicense($licenseRef1,
false, ClearingEventTypes::USER,
"42",
"44");
292 $clearingLicense2 =
new ClearingLicense($licenseRef2,
true, ClearingEventTypes::USER,
"-42",
"-44");
294 $eventId1 = $this->clearingDao->insertClearingEvent($originallyClearedItemId, $this->userId, $this->groupId,
295 $licenseRef1->getId(), $clearingLicense1->isRemoved(),
296 $clearingLicense1->getType(), $clearingLicense1->getReportinfo(), $clearingLicense1->getComment());
297 $eventId2 = $this->clearingDao->insertClearingEvent($originallyClearedItemId, 5, $this->groupId,
298 $licenseRef2->getId(), $clearingLicense2->isRemoved(),
299 $clearingLicense2->getType(), $clearingLicense2->getReportinfo(), $clearingLicense2->getComment());
301 $addedEventIds = array($eventId1, $eventId2);
303 $this->clearingDao->createDecisionFromEvents($originallyClearedItemId, $this->userId,
304 $this->groupId, DecisionTypes::IDENTIFIED, $scope, $addedEventIds);
306 return array($clearingLicense1, $clearingLicense2, $addedEventIds);
342 list($success,$output,$retCode) = $runner->run($uploadId=3);
344 $this->assertTrue($success,
'cannot run runner');
345 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
350 assertThat($decisions, is(emptyArray()));
367 $this->runnerReuserScanWithALocalClearing($this->runnerMock,1);
382 $this->runnerReuserScanWithALocalClearing($this->runnerCli,1);
390 private function runnerReuserScanWithALocalClearing($runner, $heartBeat=0)
395 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId);
401 $reusingUploadItemShift = 20;
403 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
405 $this->assertTrue($success,
'cannot run runner');
406 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
407 assertThat($this->
getHeartCount($output), equalTo($heartBeat));
412 assertThat($newUploadClearings, is(arrayWithSize(1)));
414 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
416 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
418 $newClearing = $newUploadClearings[0];
420 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
421 assertThat($newClearing->getClearingId(), not(equalTo($potentiallyReusableClearing->getClearingId())));
423 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicense1, $clearingLicense2));
425 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
426 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
428 assertThat($newClearing->getUploadTreeId(),
429 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
446 $this->runnerReuserScanWithARepoClearing($this->runnerMock);
461 $this->runnerReuserScanWithARepoClearing($this->runnerCli);
468 private function runnerReuserScanWithARepoClearing($runner)
473 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId);
476 DecisionScopes::REPO,$originallyClearedItemId=23);
477 $clearingLicenses = array($clearingLicense1, $clearingLicense2);
481 $reusingUploadItemShift = 20;
483 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
485 $this->assertTrue($success,
'cannot run runner');
486 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
493 assertThat($newUploadClearings, is(arrayWithSize(1)));
495 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
497 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
499 $newClearing = $newUploadClearings[0];
503 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
506 assertThat($newClearing->getClearingId(), equalTo($potentiallyReusableClearing->getClearingId()));
508 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicenses));
510 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
511 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
513 assertThat($newClearing->getUploadTreeId(),
514 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
517 $bounds = $this->uploadDao->getItemTreeBounds($originallyClearedItemId + $reusingUploadItemShift);
518 $newEvents = $this->clearingDao->getRelevantClearingEvents($bounds, $this->groupId);
520 assertThat($newEvents, is(arrayWithSize(count($clearingLicenses))));
523 foreach ($newEvents as $newEvent) {
524 assertThat($newEvent->getEventId(), anyOf($addedEventIds));
525 assertThat($newEvent->getClearingLicense(), anyOf($clearingLicenses));
544 $this->runnerReuserScanWithARepoClearingEnhanced($this->runnerMock);
551 private function runnerReuserScanWithARepoClearingEnhanced($runner)
556 $originallyClearedItemId = 23;
558 $reusingUploadItemShift = 20;
560 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId,$reuseMode=2);
562 $repoPath = $this->testDb->getFossSysConf().
'/repo/files/';
563 $this->treeDao->shouldReceive(
'getRepoPathOfPfile')->with(4)->andReturn($repoPath
564 .
'04621571bcbabce75c4dd1c6445b87dec0995734.59cacdfce5051cd8a1d8a1f2dcce40a5.12320');
565 $this->treeDao->shouldReceive(
'getRepoPathOfPfile')->with(351)->andReturn($repoPath
566 .
'c518ce1658140b65fa0132ad1130cb91512416bf.8e913e594d24ff3aeabe350107d97815.35829');
569 DecisionScopes::REPO,$originallyClearedItemId);
570 $clearingLicenses = array($clearingLicense1, $clearingLicense2);
572 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
574 $this->assertTrue($success,
'cannot run runner');
575 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
580 assertThat($newUploadClearings, is(arrayWithSize(1)));
582 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
584 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
586 $newClearing = $newUploadClearings[0];
590 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
592 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicenses));
594 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
595 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
597 assertThat($newClearing->getUploadTreeId(),
598 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
601 $bounds = $this->uploadDao->getItemTreeBounds($originallyClearedItemId + $reusingUploadItemShift);
602 $newEvents = $this->clearingDao->getRelevantClearingEvents($bounds, $this->groupId);
604 assertThat($newEvents, is(arrayWithSize(count($clearingLicenses))));
607 foreach ($newEvents as $newEvent) {
608 assertThat($newEvent->getEventId(), anyOf($addedEventIds));
609 assertThat($newEvent->getClearingLicense(), anyOf($clearingLicenses));
612 $this->clearingDao->makeMainLicense($uploadId=2, $this->groupId, $mainLicenseId=402);
613 $mainLicenseIdForReuse = $this->clearingDao->getMainLicenseIds($reusedUploadId=2, $this->groupId);
614 $mainLicenseIdForReuseSingle = array_values($mainLicenseIdForReuse);
615 $this->clearingDao->makeMainLicense($uploadId=3, $this->groupId, $mainLicenseIdForReuseSingle[0]);
616 $mainLicense=$this->clearingDao->getMainLicenseIds($uploadId=3, $this->groupId);
617 $mainLicenseSingle = array_values($mainLicense);
618 $this->assertEquals($mainLicenseIdForReuseSingle, $mainLicenseSingle);
631 $reuseSelections = [
'2,1',
'4,1'];
634 foreach ($reuseSelections as $reuseSelection) {
635 if (empty($reuseSelection) || !is_string($reuseSelection)) {
636 $this->fail(
"Invalid reuse selection found - empty or non-string value");
639 $reuseUploadPair = explode(
',', $reuseSelection, 2);
640 if (count($reuseUploadPair) !== 2) {
641 $this->fail(
"Invalid reuse selection format: '$reuseSelection' (expected format: 'uploadId,groupId')");
644 [$reuseUploadId, $reuseGroupId] = $reuseUploadPair;
645 $this->assertIsNumeric($reuseUploadId,
"Upload ID should be numeric");
646 $this->assertIsNumeric($reuseGroupId,
"Group ID should be numeric");
650 $this->assertEquals(2, $createdLinks,
'Should process 2 reuse selections');
662 $reuseSelections =
'2,1';
664 if (!is_array($reuseSelections)) {
665 $reuseSelections = [$reuseSelections];
669 foreach ($reuseSelections as $reuseSelection) {
670 if (empty($reuseSelection) || !is_string($reuseSelection)) {
671 $this->fail(
"Invalid reuse selection found - empty or non-string value");
674 $reuseUploadPair = explode(
',', $reuseSelection, 2);
675 if (count($reuseUploadPair) !== 2) {
676 $this->fail(
"Invalid reuse selection format: '$reuseSelection' (expected format: 'uploadId,groupId')");
679 [$reuseUploadId, $reuseGroupId] = $reuseUploadPair;
680 $this->assertIsNumeric($reuseUploadId,
"Upload ID should be numeric");
681 $this->assertIsNumeric($reuseGroupId,
"Group ID should be numeric");
685 $this->assertEquals(1, $createdLinks,
'Should process 1 reuse selection');
696 $invalidSelection =
"invalid_format";
698 $reuseUploadPair = explode(
',', $invalidSelection, 2);
699 $this->expectException(\InvalidArgumentException::class);
700 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection format: '$invalidSelection' (expected format: 'uploadId,groupId')");
702 if (count($reuseUploadPair) !== 2) {
703 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection format: '$invalidSelection' (expected format: 'uploadId,groupId')");
715 $emptySelection =
"";
716 $this->expectException(\InvalidArgumentException::class);
717 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection found - empty or non-string value");
719 if (empty($emptySelection) || !is_string($emptySelection)) {
720 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection found - empty or non-string value");
732 $nonStringSelection = 123;
733 $this->expectException(\InvalidArgumentException::class);
734 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection found - empty or non-string value");
736 if (empty($nonStringSelection) || !is_string($nonStringSelection)) {
737 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection found - empty or non-string value");
757 foreach ($malformedCases as $malformedValue) {
758 $reuseUploadPair = explode(
',', $malformedValue, 2);
759 if (count($reuseUploadPair) !== 2) {
760 $this->expectException(\InvalidArgumentException::class);
761 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection format: '$malformedValue' (expected format: 'uploadId,groupId')");
762 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection format: '$malformedValue' (expected format: 'uploadId,groupId')");
Various utility functions to filter ClearingDecision.
UI element for reuser during Uploading new package.
Handles scheduler interaction.
Create mock objects for reuser.
Tests for Reuser agent and scheduler interaction.
testReuserMalformedReuseSelection()
Test malformed reuse selection strings.
testReuserNonStringReuseSelection()
Test non-string reuse selection throws exception.
insertDecisionFromTwoEvents($scope=DecisionScopes::ITEM, $originallyClearedItemId=23)
Creates two clearing decisions.
testReuserMockedScanWithARepoClearing()
Call runnerReuserScanWithARepoClearing()
testReuserRealScanWithALocalClearing()
Call runnerReuserScanWithALocalClearing()
testReuserSingleReuseSelectionValidation()
Test single reuse selection validation logic (backward compatibility)
testReuserRealScanWithoutAnyUploadToCopyAndAClearing()
Call runnerReuserScanWithoutAnyUploadToCopyAndAClearing()
testReuserRealScanWithARepoClearing()
Call runnerReuserScanWithARepoClearing()
setUpRepo()
Setup test repo.
tearDown()
Tear down test env.
testReuserInvalidReuseSelectionFormat()
Test invalid reuse selection format throws exception.
getFilteredClearings($uploadId, $groupId)
Get clearings for a given upload id.
rmRepo()
Tear down test repo.
testReuserMockedScanWithoutAnyUploadToCopyAndNoClearing()
Call runnerReuserScanWithoutAnyUploadToCopyAndNoClearing()
testReuserMockedScanWithoutAnyUploadToCopyAndAClearing()
Call runnerReuserScanWithoutAnyUploadToCopyAndAClearing()
getHeartCount($output)
Get the heart count from agent.
testReuserEmptyReuseSelection()
Test empty reuse selection throws exception.
runnerReuserScanWithoutAnyUploadToCopyAndNoClearing(SchedulerTestRunner $runner)
Test on an upload with no clearing decisions.
setUpTables()
Setup tables required by the agent.
testReuserRealScanWithoutAnyUploadToCopyAndNoClearing()
Call runnerReuserScanWithoutAnyUploadToCopyAndNoClearing()
testReuserMockedScanWithALocalClearing()
Call runnerReuserScanWithALocalClearing()
runnerReuserScanWithoutAnyUploadToCopyAndAClearing($runner)
Run reuser agent with no upload to copy decisions from.
testReuserRealScanWithARepoClearingEnhanced()
Call runnerReuserScanWithARepoClearingEnhanced()
testReuserMultipleReuseSelectionsValidation()
Test multiple reuse selections validation logic.
run($uploadId, $userId=2, $groupId=2, $jobId=1, $args="")
Function to run agent from scheduler.
fo_dbManager * dbManager
fo_dbManager object
Namespace to hold test cases for Reuser agent.