278 lines
11 KiB
Diff
278 lines
11 KiB
Diff
|
From bd5a5b58b438ff34d27781e28cd7fab93bfc9f3f Mon Sep 17 00:00:00 2001
|
||
|
From: Maximilian Bosch <maximilian@mbosch.me>
|
||
|
Date: Sat, 9 Mar 2019 23:26:30 +0100
|
||
|
Subject: [PATCH] Don't use `which` implementation to find required executables
|
||
|
|
||
|
Nix specific patch.
|
||
|
|
||
|
Rather than relying on a global state, we set an absolute store path for
|
||
|
all external dependencies to ensure their functionality.
|
||
|
---
|
||
|
integration_tests/__init__.py | 4 ++--
|
||
|
tests/engines/test_gif.py | 2 +-
|
||
|
tests/handlers/test_base_handler.py | 30 ++++++++++++++---------------
|
||
|
tests/optimizers/test_gifv.py | 2 +-
|
||
|
tests/test_server.py | 4 ++++
|
||
|
tests/test_utils.py | 3 +++
|
||
|
thumbor/server.py | 7 +------
|
||
|
7 files changed, 26 insertions(+), 26 deletions(-)
|
||
|
|
||
|
diff --git a/integration_tests/__init__.py b/integration_tests/__init__.py
|
||
|
index 9bdd0a3..7d9de8f 100644
|
||
|
--- a/integration_tests/__init__.py
|
||
|
+++ b/integration_tests/__init__.py
|
||
|
@@ -15,7 +15,7 @@ class EngineCase(AsyncHTTPTestCase):
|
||
|
def get_app(self):
|
||
|
cfg = Config(SECURITY_KEY='ACME-SEC')
|
||
|
server_params = ServerParameters(None, None, None, None, None, None)
|
||
|
- server_params.gifsicle_path = which('gifsicle')
|
||
|
+ server_params.gifsicle_path = '@gifsicle@'
|
||
|
|
||
|
cfg.DETECTORS = [
|
||
|
'thumbor.detectors.face_detector',
|
||
|
@@ -28,7 +28,7 @@ class EngineCase(AsyncHTTPTestCase):
|
||
|
cfg.FILE_LOADER_ROOT_PATH = os.path.join(os.path.dirname(__file__), 'imgs')
|
||
|
cfg.ENGINE = getattr(self, 'engine', None)
|
||
|
cfg.USE_GIFSICLE_ENGINE = True
|
||
|
- cfg.FFMPEG_PATH = which('ffmpeg')
|
||
|
+ cfg.FFMPEG_PATH = '@ffmpeg@'
|
||
|
cfg.ENGINE_THREADPOOL_SIZE = 10
|
||
|
cfg.OPTIMIZERS = [
|
||
|
'thumbor.optimizers.gifv',
|
||
|
diff --git a/tests/engines/test_gif.py b/tests/engines/test_gif.py
|
||
|
index c0c8430..ce0cc51 100644
|
||
|
--- a/tests/engines/test_gif.py
|
||
|
+++ b/tests/engines/test_gif.py
|
||
|
@@ -44,7 +44,7 @@ class GitEngineTestCase(TestCase):
|
||
|
def get_server(self):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
- server.gifsicle_path = which('gifsicle')
|
||
|
+ server.gifsicle_path = '@gifsicle@'
|
||
|
return server
|
||
|
|
||
|
def get_context(self, *args, **kwargs):
|
||
|
diff --git a/tests/handlers/test_base_handler.py b/tests/handlers/test_base_handler.py
|
||
|
index 69dc110..4493abe 100644
|
||
|
--- a/tests/handlers/test_base_handler.py
|
||
|
+++ b/tests/handlers/test_base_handler.py
|
||
|
@@ -557,7 +557,7 @@ class ImageOperationsWithAutoWebPTestCase(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
def get_as_webp(self, url):
|
||
|
@@ -657,7 +657,7 @@ class ImageOperationsWithAutoWebPWithResultStorageTestCase(BaseImagingTestCase):
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
ctx.request = self.get_request()
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
@property
|
||
|
@@ -783,7 +783,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase):
|
||
|
cfg = Config(SECURITY_KEY='ACME-SEC')
|
||
|
cfg.LOADER = "thumbor.loaders.file_loader"
|
||
|
cfg.FILE_LOADER_ROOT_PATH = self.loader_path
|
||
|
- cfg.FFMPEG_PATH = which('ffmpeg')
|
||
|
+ cfg.FFMPEG_PATH = '@ffmpeg@'
|
||
|
cfg.OPTIMIZERS = [
|
||
|
'thumbor.optimizers.gifv',
|
||
|
]
|
||
|
@@ -793,7 +793,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
def test_should_convert_animated_gif_to_mp4_when_filter_without_params(self):
|
||
|
@@ -828,7 +828,7 @@ class ImageOperationsImageCoverTestCase(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
def test_can_get_image_cover(self):
|
||
|
@@ -849,7 +849,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase):
|
||
|
cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path
|
||
|
|
||
|
cfg.USE_GIFSICLE_ENGINE = True
|
||
|
- cfg.FFMPEG_PATH = which('ffmpeg')
|
||
|
+ cfg.FFMPEG_PATH = '@ffmpeg@'
|
||
|
cfg.AUTO_WEBP = True
|
||
|
cfg.OPTIMIZERS = [
|
||
|
'thumbor.optimizers.gifv',
|
||
|
@@ -860,7 +860,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
|
||
|
return ctx
|
||
|
|
||
|
@@ -891,7 +891,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase):
|
||
|
cfg.RESULT_STORAGE = 'thumbor.result_storages.file_storage'
|
||
|
cfg.RESULT_STORAGE_EXPIRATION_SECONDS = 60
|
||
|
cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path
|
||
|
- cfg.FFMPEG_PATH = which('ffmpeg')
|
||
|
+ cfg.FFMPEG_PATH = '@ffmpeg@'
|
||
|
|
||
|
cfg.USE_GIFSICLE_ENGINE = True
|
||
|
cfg.AUTO_WEBP = True
|
||
|
@@ -904,7 +904,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
|
||
|
return ctx
|
||
|
|
||
|
@@ -1040,7 +1040,7 @@ class ImageOperationsWithMaxPixels(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
def test_should_error(self):
|
||
|
@@ -1061,7 +1061,7 @@ class ImageOperationsWithRespectOrientation(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
self.context = Context(server, cfg, importer)
|
||
|
- self.context.server.gifsicle_path = which('gifsicle')
|
||
|
+ self.context.server.gifsicle_path = '@gifsicle@'
|
||
|
return self.context
|
||
|
|
||
|
def test_should_be_ok_when_orientation_exif(self):
|
||
|
@@ -1153,7 +1153,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase):
|
||
|
cfg = Config(SECURITY_KEY='ACME-SEC')
|
||
|
cfg.LOADER = "thumbor.loaders.file_loader"
|
||
|
cfg.FILE_LOADER_ROOT_PATH = self.loader_path
|
||
|
- cfg.JPEGTRAN_PATH = which('jpegtran')
|
||
|
+ cfg.JPEGTRAN_PATH = '@jpegtran@'
|
||
|
cfg.PROGRESSIVE_JPEG = True,
|
||
|
cfg.RESULT_STORAGE_STORES_UNSAFE = True,
|
||
|
cfg.OPTIMIZERS = [
|
||
|
@@ -1175,9 +1175,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase):
|
||
|
f.write(response.body)
|
||
|
f.close()
|
||
|
|
||
|
- exiftool = which('exiftool')
|
||
|
- if not exiftool:
|
||
|
- raise AssertionError('exiftool was not found. Please install it to run thumbor\'s tests.')
|
||
|
+ exiftool = '@exiftool@'
|
||
|
|
||
|
command = [
|
||
|
exiftool,
|
||
|
@@ -1221,7 +1219,7 @@ class ImageOperationsWithoutStorage(BaseImagingTestCase):
|
||
|
server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
|
||
|
server.security_key = 'ACME-SEC'
|
||
|
ctx = Context(server, cfg, importer)
|
||
|
- ctx.server.gifsicle_path = which('gifsicle')
|
||
|
+ ctx.server.gifsicle_path = '@gifsicle@'
|
||
|
return ctx
|
||
|
|
||
|
def test_meta(self):
|
||
|
diff --git a/tests/optimizers/test_gifv.py b/tests/optimizers/test_gifv.py
|
||
|
index 229e9cd..066f2d5 100644
|
||
|
--- a/tests/optimizers/test_gifv.py
|
||
|
+++ b/tests/optimizers/test_gifv.py
|
||
|
@@ -31,7 +31,7 @@ class GifvOptimizerTest(TestCase):
|
||
|
def get_context(self):
|
||
|
conf = Config()
|
||
|
conf.STATSD_HOST = ''
|
||
|
- conf.FFMPEG_PATH = which('ffmpeg')
|
||
|
+ conf.FFMPEG_PATH = '@ffmpeg@'
|
||
|
ctx = Context(config=conf)
|
||
|
ctx.request = RequestParameters()
|
||
|
ctx.request.filters.append('gifv')
|
||
|
diff --git a/tests/test_server.py b/tests/test_server.py
|
||
|
index 5b31750..c2a65dc 100644
|
||
|
--- a/tests/test_server.py
|
||
|
+++ b/tests/test_server.py
|
||
|
@@ -11,6 +11,8 @@
|
||
|
from unittest import TestCase
|
||
|
import mock
|
||
|
|
||
|
+from nose.tools import nottest
|
||
|
+
|
||
|
from preggy import expect
|
||
|
|
||
|
from thumbor.app import ThumborServiceApp
|
||
|
@@ -118,6 +120,7 @@ class ServerTestCase(TestCase):
|
||
|
expect(server_parameters.security_key).to_equal('something')
|
||
|
|
||
|
@mock.patch.object(thumbor.server, 'which')
|
||
|
+ @nottest
|
||
|
def test_validate_gifsicle_path(self, which_mock):
|
||
|
server_parameters = mock.Mock(security_key=None)
|
||
|
conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True)
|
||
|
@@ -128,6 +131,7 @@ class ServerTestCase(TestCase):
|
||
|
expect(server_parameters.gifsicle_path).to_equal('/usr/bin/gifsicle')
|
||
|
|
||
|
@mock.patch.object(thumbor.server, 'which')
|
||
|
+ @nottest
|
||
|
def test_validate_null_gifsicle_path(self, which_mock):
|
||
|
server_parameters = mock.Mock(security_key=None)
|
||
|
conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True)
|
||
|
diff --git a/tests/test_utils.py b/tests/test_utils.py
|
||
|
index 38cd51b..7dd0b3e 100644
|
||
|
--- a/tests/test_utils.py
|
||
|
+++ b/tests/test_utils.py
|
||
|
@@ -10,6 +10,7 @@
|
||
|
|
||
|
from mock import Mock, patch
|
||
|
from unittest import TestCase
|
||
|
+from nose.tools import nottest
|
||
|
import logging
|
||
|
|
||
|
from preggy import expect
|
||
|
@@ -112,6 +113,7 @@ class UtilsTestCase(TestCase):
|
||
|
test_func()
|
||
|
mock_warn.assert_called_once_with('Deprecated function test_func: func2')
|
||
|
|
||
|
+ @nottest
|
||
|
def test_can_which_by_path(self):
|
||
|
result = which('/bin/ls')
|
||
|
expect(result).to_equal('/bin/ls')
|
||
|
@@ -119,6 +121,7 @@ class UtilsTestCase(TestCase):
|
||
|
result = which('/tmp')
|
||
|
expect(result).to_be_null()
|
||
|
|
||
|
+ @nottest
|
||
|
def test_can_which_by_env(self):
|
||
|
result = which('ls')
|
||
|
expect(result).to_equal('/bin/ls')
|
||
|
diff --git a/thumbor/server.py b/thumbor/server.py
|
||
|
index c75a769..821163b 100644
|
||
|
--- a/thumbor/server.py
|
||
|
+++ b/thumbor/server.py
|
||
|
@@ -89,12 +89,7 @@ def validate_config(config, server_parameters):
|
||
|
warnings.simplefilter('error', Image.DecompressionBombWarning)
|
||
|
|
||
|
if config.USE_GIFSICLE_ENGINE:
|
||
|
- server_parameters.gifsicle_path = which('gifsicle')
|
||
|
- if server_parameters.gifsicle_path is None:
|
||
|
- raise RuntimeError(
|
||
|
- 'If using USE_GIFSICLE_ENGINE configuration to True, the `gifsicle` binary must be in the PATH '
|
||
|
- 'and must be an executable.'
|
||
|
- )
|
||
|
+ server_parameters.gifsicle_path = '@gifsicle@'
|
||
|
|
||
|
|
||
|
def get_context(server_parameters, config, importer):
|
||
|
--
|
||
|
2.18.1
|
||
|
|