1
0
Fork 0

Merge pull request #9296 from mcaskill/bugfix/file-downloader-cache-keys

Fix availability of $urls in FileDownloader
pull/9310/head
Jordi Boggiano 2020-10-16 11:24:03 +02:00 committed by GitHub
commit 4d005a9786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 194 additions and 0 deletions

View File

@ -142,6 +142,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
$reject = null; $reject = null;
$download = function () use ($io, $output, $httpDownloader, $cache, $cacheKeyGenerator, $eventDispatcher, $package, $fileName, &$urls, &$accept, &$reject) { $download = function () use ($io, $output, $httpDownloader, $cache, $cacheKeyGenerator, $eventDispatcher, $package, $fileName, &$urls, &$accept, &$reject) {
$url = reset($urls); $url = reset($urls);
$index = key($urls);
if ($eventDispatcher) { if ($eventDispatcher) {
$preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $httpDownloader, $url['processed'], 'package', $package); $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $httpDownloader, $url['processed'], 'package', $package);
@ -154,6 +155,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
$url['processed'] = $preFileDownloadEvent->getProcessedUrl(); $url['processed'] = $preFileDownloadEvent->getProcessedUrl();
} }
$urls[$index] = $url;
$checksum = $package->getDistSha1Checksum(); $checksum = $package->getDistSha1Checksum();
$cacheKey = $url['cacheKey']; $cacheKey = $url['cacheKey'];

View File

@ -12,7 +12,11 @@
namespace Composer\Test\Downloader; namespace Composer\Test\Downloader;
use Composer\Config;
use Composer\Downloader\FileDownloader; use Composer\Downloader\FileDownloader;
use Composer\EventDispatcher\EventDispatcher;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PreFileDownloadEvent;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Http\Response; use Composer\Util\Http\Response;
@ -156,6 +160,193 @@ class FileDownloaderTest extends TestCase
} }
} }
public function testDownloadWithCustomProcessedUrl()
{
$self = $this;
$path = $this->getUniqueTmpDirectory();
$config = new Config(false, $path);
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
$packageMock->expects($this->any())
->method('getDistUrl')
->will($this->returnValue('url'));
$packageMock->expects($this->any())
->method('getDistUrls')
->will($this->returnValue(array('url')));
$rootPackageMock = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
$rootPackageMock->expects($this->any())
->method('getScripts')
->will($this->returnValue(array()));
$composerMock = $this->getMockBuilder('Composer\Composer')->getMock();
$composerMock->expects($this->any())
->method('getPackage')
->will($this->returnValue($rootPackageMock));
$composerMock->expects($this->any())
->method('getConfig')
->will($this->returnValue($config));
$expectedUrl = 'foobar';
$expectedCacheKey = '/'.sha1($expectedUrl).'.';
$dispatcher = new EventDispatcher(
$composerMock,
$this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock()
);
$dispatcher->addListener(PluginEvents::PRE_FILE_DOWNLOAD, function ( PreFileDownloadEvent $event ) use ($expectedUrl) {
$event->setProcessedUrl($expectedUrl);
});
$cacheMock = $this->getMockBuilder('Composer\Cache')
->disableOriginalConstructor()
->getMock();
$cacheMock
->expects($this->any())
->method('copyTo')
->will($this->returnCallback(function ($cacheKey) use ($self, $expectedCacheKey) {
$self->assertEquals($expectedCacheKey, $cacheKey, 'Failed assertion on $cacheKey argument of Cache::copyTo method:');
return false;
}));
$cacheMock
->expects($this->any())
->method('copyFrom')
->will($this->returnCallback(function ($cacheKey) use ($self, $expectedCacheKey) {
$self->assertEquals($expectedCacheKey, $cacheKey, 'Failed assertion on $cacheKey argument of Cache::copyFrom method:');
return false;
}));
$httpDownloaderMock = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
$httpDownloaderMock
->expects($this->any())
->method('addCopy')
->will($this->returnCallback(function ($url) use ($self, $expectedUrl) {
$self->assertEquals($expectedUrl, $url, 'Failed assertion on $url argument of HttpDownloader::addCopy method:');
return \React\Promise\resolve(
new Response(array('url' => 'http://example.org/'), 200, array(), 'file~')
);
}));
$downloader = $this->getDownloader(null, $config, $dispatcher, $cacheMock, $httpDownloaderMock);
try {
$loop = new Loop($this->httpDownloader);
$promise = $downloader->download($packageMock, $path);
$loop->wait(array($promise));
$this->fail('Download was expected to throw');
} catch (\Exception $e) {
if (is_dir($path)) {
$fs = new Filesystem();
$fs->removeDirectory($path);
} elseif (is_file($path)) {
unlink($path);
}
$this->assertInstanceOf('UnexpectedValueException', $e, $e->getMessage());
$this->assertStringContainsString('could not be saved to', $e->getMessage());
}
}
public function testDownloadWithCustomCacheKey()
{
$self = $this;
$path = $this->getUniqueTmpDirectory();
$config = new Config(false, $path);
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
$packageMock->expects($this->any())
->method('getDistUrl')
->will($this->returnValue('url'));
$packageMock->expects($this->any())
->method('getDistUrls')
->will($this->returnValue(array('url')));
$rootPackageMock = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
$rootPackageMock->expects($this->any())
->method('getScripts')
->will($this->returnValue(array()));
$composerMock = $this->getMockBuilder('Composer\Composer')->getMock();
$composerMock->expects($this->any())
->method('getPackage')
->will($this->returnValue($rootPackageMock));
$composerMock->expects($this->any())
->method('getConfig')
->will($this->returnValue($config));
$expectedUrl = 'url';
$customCacheKey = 'xyzzy';
$expectedCacheKey = '/'.sha1($customCacheKey).'.';
$dispatcher = new EventDispatcher(
$composerMock,
$this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock()
);
$dispatcher->addListener(PluginEvents::PRE_FILE_DOWNLOAD, function ( PreFileDownloadEvent $event ) use ($customCacheKey) {
$event->setCustomCacheKey($customCacheKey);
});
$cacheMock = $this->getMockBuilder('Composer\Cache')
->disableOriginalConstructor()
->getMock();
$cacheMock
->expects($this->any())
->method('copyTo')
->will($this->returnCallback(function ($cacheKey) use ($self, $expectedCacheKey) {
$self->assertEquals($expectedCacheKey, $cacheKey, 'Failed assertion on $cacheKey argument of Cache::copyTo method:');
return false;
}));
$cacheMock
->expects($this->any())
->method('copyFrom')
->will($this->returnCallback(function ($cacheKey) use ($self, $expectedCacheKey) {
$self->assertEquals($expectedCacheKey, $cacheKey, 'Failed assertion on $cacheKey argument of Cache::copyFrom method:');
return false;
}));
$httpDownloaderMock = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
$httpDownloaderMock
->expects($this->any())
->method('addCopy')
->will($this->returnCallback(function ($url) use ($self, $expectedUrl) {
$self->assertEquals($expectedUrl, $url, 'Failed assertion on $url argument of HttpDownloader::addCopy method:');
return \React\Promise\resolve(
new Response(array('url' => 'http://example.org/'), 200, array(), 'file~')
);
}));
$downloader = $this->getDownloader(null, $config, $dispatcher, $cacheMock, $httpDownloaderMock);
try {
$loop = new Loop($this->httpDownloader);
$promise = $downloader->download($packageMock, $path);
$loop->wait(array($promise));
$this->fail('Download was expected to throw');
} catch (\Exception $e) {
if (is_dir($path)) {
$fs = new Filesystem();
$fs->removeDirectory($path);
} elseif (is_file($path)) {
unlink($path);
}
$this->assertInstanceOf('UnexpectedValueException', $e, $e->getMessage());
$this->assertStringContainsString('could not be saved to', $e->getMessage());
}
}
public function testCacheGarbageCollectionIsCalled() public function testCacheGarbageCollectionIsCalled()
{ {
$expectedTtl = '99999999'; $expectedTtl = '99999999';