40 include_once(__DIR__.
'/../../../lib/php/Test/Agent/AgentTestMockHelper.php');
41 include_once(__DIR__.
'/SchedulerTestRunnerCli.php');
112 $this->testDb =
new TestPgDb(
"reuserSched");
113 $this->
dbManager = $this->testDb->getDbManager();
116 $logger =
new Logger(
"ReuserSchedulerTest");
117 $this->uploadPermDao = \Mockery::mock(UploadPermissionDao::class);
123 $this->treeDao = \Mockery::mock(TreeDao::class);
133 $this->testDb->fullDestruct();
134 $this->testDb =
null;
136 $this->licenseDao =
null;
137 $this->highlightDao =
null;
138 $this->clearingDao =
null;
139 $this->copyrightDao =
null;
147 $sysConf = $this->testDb->getFossSysConf();
149 $this->testInstaller->init();
150 $this->testInstaller->cpRepo();
158 $this->testInstaller->rmRepo();
159 $this->testInstaller->clear();
167 $this->testDb->createPlainTables(array(
'upload',
'upload_reuse',
'uploadtree',
168 'uploadtree_a',
'license_ref',
'license_ref_bulk',
'clearing_decision',
169 'clearing_decision_event',
'clearing_event',
'license_file',
'highlight',
170 'highlight_bulk',
'agent',
'pfile',
'ars_master',
'users',
'group_user_member',
171 'upload_clearing_license',
'report_info'),
false);
172 $this->testDb->createSequences(array(
'agent_agent_pk_seq',
'pfile_pfile_pk_seq',
173 'upload_upload_pk_seq',
'nomos_ars_ars_pk_seq',
'license_file_fl_pk_seq',
174 'license_ref_rf_pk_seq',
'license_ref_bulk_lrb_pk_seq',
175 'clearing_decision_clearing_decision_pk_seq',
176 'clearing_event_clearing_event_pk_seq',
'report_info_pk_seq'),
false);
177 $this->testDb->createViews(array(
'license_file_ref'),
false);
178 $this->testDb->createConstraints(array(
'agent_pkey',
'pfile_pkey',
179 'upload_pkey_idx',
'FileLicense_pkey',
'clearing_event_pkey'),
false);
180 $this->testDb->alterTables(array(
'agent',
'pfile',
'upload',
'ars_master',
181 'license_ref_bulk',
'license_ref',
'clearing_event',
'clearing_decision',
'license_file',
'highlight'),
false);
182 $this->testDb->createInheritedTables();
183 $this->testDb->createInheritedArsTables(array(
'monk'));
185 $this->testDb->insertData(array(
'pfile',
'upload',
'uploadtree_a',
'users',
186 'group_user_member',
'agent',
'license_file',
'monk_ars',
'report_info'),
188 $this->testDb->insertData_license_ref(80);
190 $this->testDb->resetSequenceAsMaxOf(
'agent_agent_pk_seq',
'agent',
'agent_pk');
192 $this->testDb->setupSysconfig();
201 if (preg_match(
"/.*HEART: ([0-9]*).*/", $output, $matches)) {
202 return intval($matches[1]);
216 $bounds = $this->uploadDao->getParentItemBounds($uploadId);
217 return $this->clearingDao->getFileClearingsFolder($bounds,
$groupId);
241 list($success, $output,$retCode) = $runner->
run($uploadId=1, $this->userId);
243 $this->assertTrue($success,
'cannot run runner');
244 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
248 $bounds = $this->uploadDao->getParentItemBounds($uploadId);
249 assertThat($this->clearingDao->getFileClearingsFolder($bounds,
$groupId=5), is(emptyArray()));
262 $licenseRef1 = $this->licenseDao->getLicenseByShortName(
"SPL-1.0")->getRef();
263 $licenseRef2 = $this->licenseDao->getLicenseByShortName(
"Glide")->getRef();
265 $addedLicenses = array($licenseRef1, $licenseRef2);
266 assertThat($addedLicenses, not(arrayContaining(
null)));
268 $clearingLicense1 =
new ClearingLicense($licenseRef1,
false, ClearingEventTypes::USER,
"42",
"44");
269 $clearingLicense2 =
new ClearingLicense($licenseRef2,
true, ClearingEventTypes::USER,
"-42",
"-44");
271 $eventId1 = $this->clearingDao->insertClearingEvent($originallyClearedItemId, $this->userId, $this->groupId,
272 $licenseRef1->getId(), $clearingLicense1->isRemoved(),
273 $clearingLicense1->getType(), $clearingLicense1->getReportinfo(), $clearingLicense1->getComment());
274 $eventId2 = $this->clearingDao->insertClearingEvent($originallyClearedItemId, 5, $this->groupId,
275 $licenseRef2->getId(), $clearingLicense2->isRemoved(),
276 $clearingLicense2->getType(), $clearingLicense2->getReportinfo(), $clearingLicense2->getComment());
278 $addedEventIds = array($eventId1, $eventId2);
280 $this->clearingDao->createDecisionFromEvents($originallyClearedItemId, $this->userId,
281 $this->groupId, DecisionTypes::IDENTIFIED, $scope, $addedEventIds);
283 return array($clearingLicense1, $clearingLicense2, $addedEventIds);
308 list($success,$output,$retCode) = $runner->run($uploadId=3);
310 $this->assertTrue($success,
'cannot run runner');
311 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
316 assertThat($decisions, is(emptyArray()));
333 $this->runnerReuserScanWithALocalClearing($this->runnerCli,1);
341 private function runnerReuserScanWithALocalClearing($runner, $heartBeat=0)
346 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId);
352 $reusingUploadItemShift = 20;
354 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
356 $this->assertTrue($success,
'cannot run runner');
357 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
358 assertThat($this->
getHeartCount($output), equalTo($heartBeat));
363 assertThat($newUploadClearings, is(arrayWithSize(1)));
365 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
367 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
369 $newClearing = $newUploadClearings[0];
371 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
372 assertThat($newClearing->getClearingId(), not(equalTo($potentiallyReusableClearing->getClearingId())));
374 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicense1, $clearingLicense2));
376 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
377 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
379 assertThat($newClearing->getUploadTreeId(),
380 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
397 $this->runnerReuserScanWithARepoClearing($this->runnerCli);
404 private function runnerReuserScanWithARepoClearing($runner)
409 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId);
412 DecisionScopes::REPO,$originallyClearedItemId=23);
413 $clearingLicenses = array($clearingLicense1, $clearingLicense2);
417 $reusingUploadItemShift = 20;
419 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
421 $this->assertTrue($success,
'cannot run runner');
422 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
429 assertThat($newUploadClearings, is(arrayWithSize(1)));
431 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
433 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
435 $newClearing = $newUploadClearings[0];
439 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
442 assertThat($newClearing->getClearingId(), equalTo($potentiallyReusableClearing->getClearingId()));
444 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicenses));
446 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
447 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
449 assertThat($newClearing->getUploadTreeId(),
450 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
453 $bounds = $this->uploadDao->getItemTreeBounds($originallyClearedItemId + $reusingUploadItemShift);
454 $newEvents = $this->clearingDao->getRelevantClearingEvents($bounds, $this->groupId);
456 assertThat($newEvents, is(arrayWithSize(count($clearingLicenses))));
459 foreach ($newEvents as $newEvent) {
460 assertThat($newEvent->getEventId(), anyOf($addedEventIds));
461 assertThat($newEvent->getClearingLicense(), anyOf($clearingLicenses));
471 private function runnerReuserScanWithARepoClearingEnhanced($runner)
476 $originallyClearedItemId = 23;
478 $reusingUploadItemShift = 20;
480 $this->uploadDao->addReusedUpload($uploadId=3,$reusedUpload=2,$this->groupId,$this->groupId,$reuseMode=2);
482 $repoPath = $this->testDb->getFossSysConf().
'/repo/files/';
483 $this->treeDao->shouldReceive(
'getRepoPathOfPfile')->with(4)->andReturn($repoPath
484 .
'04621571bcbabce75c4dd1c6445b87dec0995734.59cacdfce5051cd8a1d8a1f2dcce40a5.12320');
485 $this->treeDao->shouldReceive(
'getRepoPathOfPfile')->with(351)->andReturn($repoPath
486 .
'c518ce1658140b65fa0132ad1130cb91512416bf.8e913e594d24ff3aeabe350107d97815.35829');
489 DecisionScopes::REPO,$originallyClearedItemId);
490 $clearingLicenses = array($clearingLicense1, $clearingLicense2);
492 list($success,$output,$retCode) = $runner->run($uploadId, $this->userId, $this->groupId);
494 $this->assertTrue($success,
'cannot run runner');
495 $this->assertEquals($retCode, 0,
'reuser failed: '.$output);
500 assertThat($newUploadClearings, is(arrayWithSize(1)));
502 assertThat($potentiallyReusableClearings, is(arrayWithSize(1)));
504 $potentiallyReusableClearing = $potentiallyReusableClearings[0];
506 $newClearing = $newUploadClearings[0];
510 assertThat($newClearing, not(equalTo($potentiallyReusableClearing)));
512 assertThat($newClearing->getClearingLicenses(), arrayContainingInAnyOrder($clearingLicenses));
514 assertThat($newClearing->getType(), equalTo($potentiallyReusableClearing->getType()));
515 assertThat($newClearing->getScope(), equalTo($potentiallyReusableClearing->getScope()));
517 assertThat($newClearing->getUploadTreeId(),
518 equalTo($potentiallyReusableClearing->getUploadTreeId() + $reusingUploadItemShift));
521 $bounds = $this->uploadDao->getItemTreeBounds($originallyClearedItemId + $reusingUploadItemShift);
522 $newEvents = $this->clearingDao->getRelevantClearingEvents($bounds, $this->groupId);
524 assertThat($newEvents, is(arrayWithSize(count($clearingLicenses))));
527 foreach ($newEvents as $newEvent) {
528 assertThat($newEvent->getEventId(), anyOf($addedEventIds));
529 assertThat($newEvent->getClearingLicense(), anyOf($clearingLicenses));
532 $this->clearingDao->makeMainLicense($uploadId=2, $this->groupId, $mainLicenseId=402);
533 $mainLicenseIdForReuse = $this->clearingDao->getMainLicenseIds($reusedUploadId=2, $this->groupId);
534 $mainLicenseIdForReuseSingle = array_values($mainLicenseIdForReuse);
535 $this->clearingDao->makeMainLicense($uploadId=3, $this->groupId, $mainLicenseIdForReuseSingle[0]);
536 $mainLicense=$this->clearingDao->getMainLicenseIds($uploadId=3, $this->groupId);
537 $mainLicenseSingle = array_values($mainLicense);
538 $this->assertEquals($mainLicenseIdForReuseSingle, $mainLicenseSingle);
551 $reuseSelections = [
'2,1',
'4,1'];
554 foreach ($reuseSelections as $reuseSelection) {
555 if (empty($reuseSelection) || !is_string($reuseSelection)) {
556 $this->fail(
"Invalid reuse selection found - empty or non-string value");
559 $reuseUploadPair = explode(
',', $reuseSelection, 2);
560 if (count($reuseUploadPair) !== 2) {
561 $this->fail(
"Invalid reuse selection format: '$reuseSelection' (expected format: 'uploadId,groupId')");
564 [$reuseUploadId, $reuseGroupId] = $reuseUploadPair;
565 $this->assertIsNumeric($reuseUploadId,
"Upload ID should be numeric");
566 $this->assertIsNumeric($reuseGroupId,
"Group ID should be numeric");
570 $this->assertEquals(2, $createdLinks,
'Should process 2 reuse selections');
582 $reuseSelections =
'2,1';
584 if (!is_array($reuseSelections)) {
585 $reuseSelections = [$reuseSelections];
589 foreach ($reuseSelections as $reuseSelection) {
590 if (empty($reuseSelection) || !is_string($reuseSelection)) {
591 $this->fail(
"Invalid reuse selection found - empty or non-string value");
594 $reuseUploadPair = explode(
',', $reuseSelection, 2);
595 if (count($reuseUploadPair) !== 2) {
596 $this->fail(
"Invalid reuse selection format: '$reuseSelection' (expected format: 'uploadId,groupId')");
599 [$reuseUploadId, $reuseGroupId] = $reuseUploadPair;
600 $this->assertIsNumeric($reuseUploadId,
"Upload ID should be numeric");
601 $this->assertIsNumeric($reuseGroupId,
"Group ID should be numeric");
605 $this->assertEquals(1, $createdLinks,
'Should process 1 reuse selection');
616 $invalidSelection =
"invalid_format";
618 $reuseUploadPair = explode(
',', $invalidSelection, 2);
619 $this->expectException(\InvalidArgumentException::class);
620 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection format: '$invalidSelection' (expected format: 'uploadId,groupId')");
622 if (count($reuseUploadPair) !== 2) {
623 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection format: '$invalidSelection' (expected format: 'uploadId,groupId')");
635 $emptySelection =
"";
636 $this->expectException(\InvalidArgumentException::class);
637 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection found - empty or non-string value");
639 if (empty($emptySelection) || !is_string($emptySelection)) {
640 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection found - empty or non-string value");
652 $nonStringSelection = 123;
653 $this->expectException(\InvalidArgumentException::class);
654 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection found - empty or non-string value");
656 if (empty($nonStringSelection) || !is_string($nonStringSelection)) {
657 throw new \InvalidArgumentException(
"Reuser: Invalid reuse selection found - empty or non-string value");
677 foreach ($malformedCases as $malformedValue) {
678 $reuseUploadPair = explode(
',', $malformedValue, 2);
679 if (count($reuseUploadPair) !== 2) {
680 $this->expectException(\InvalidArgumentException::class);
681 $this->expectExceptionMessage(
"Reuser: Invalid reuse selection format: '$malformedValue' (expected format: 'uploadId,groupId')");
682 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.
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.
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.
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()
runnerReuserScanWithoutAnyUploadToCopyAndAClearing($runner)
Run reuser agent with no upload to copy decisions from.
testReuserMultipleReuseSelectionsValidation()
Test multiple reuse selections validation logic.
run($uploadId, $userId=2, $groupId=2, $jobId=1, array $args=[])
Function to run agent from scheduler.
fo_dbManager * dbManager
fo_dbManager object
Namespace to hold test cases for Reuser agent.