Normalize method names for RunTimePaths class

This patch normalizes method name for RunTimePaths, according
to the following policy, so that it is more easy to understand
the characteristics of each method functions

 - Use @propery for the functions without any arguments
 - Use get_foo for the functions which take arguments
 - Use foo_dir for directory paths

This patch also fixes wrong path handling in storlet app log.

Change-Id: I9275a84a2881b29a91eb55efaa6bc5607f1e723c
This commit is contained in:
Takashi Kajinami 2019-07-20 22:28:42 +09:00
parent ecbeae721b
commit 4450bf1e23
7 changed files with 214 additions and 147 deletions
storlets/gateway
tests/unit/gateway

@ -31,3 +31,7 @@ class FileManagementError(Exception):
class StorletGatewayLoadError(Exception):
pass
class StorletLoggerError(IOError):
pass

@ -16,46 +16,47 @@
import os
from contextlib import contextmanager
NOTOPEN = 0
OPEN = 1
CLOSED = 2
from storlets.gateway.common.exceptions import StorletLoggerError
class StorletLogger(object):
def __init__(self, path, name):
self.full_path = os.path.join(path, '%s.log' % name)
self._status = NOTOPEN
def __init__(self, path):
self.log_path = path
self._file = None
def open(self):
if self._status == OPEN:
raise Exception('StorletLogger has been open')
if self._file is not None:
raise StorletLoggerError('StorletLogger is already open')
try:
self._file = open(self.full_path, 'a')
log_dir_path = os.path.dirname(self.log_path)
if not os.path.exists(log_dir_path):
os.makedirs(log_dir_path)
self._file = open(self.log_path, 'a')
except Exception:
raise
else:
self._status = OPEN
def getfd(self):
if self._status != OPEN:
if self._file is None:
# TODO(kota_): Is it safe to return None?
return None
return self._file.fileno()
def getsize(self):
statinfo = os.stat(self.full_path)
statinfo = os.stat(self.log_path)
return statinfo.st_size
def close(self):
if self._status != OPEN:
raise Exception('StorletLogger is not open')
if self._file is None:
raise StorletLoggerError('StorletLogger is not open')
try:
self._file.close()
except Exception:
raise
else:
self._status = CLOSED
self._file = None
@contextmanager
def activate(self):

@ -212,8 +212,9 @@ class StorletGatewayDocker(StorletGatewayBase):
run_time_sbox.activate_storlet_daemon(sreq, docker_updated)
self._add_system_params(sreq)
slog_path = self.paths.slog_path(sreq.storlet_main)
storlet_pipe_path = self.paths.host_storlet_pipe(sreq.storlet_main)
slog_path = self.paths.get_host_slog_path(sreq.storlet_main)
storlet_pipe_path = \
self.paths.get_host_storlet_pipe(sreq.storlet_main)
sprotocol = StorletInvocationProtocol(sreq,
storlet_pipe_path,
@ -238,7 +239,7 @@ class StorletGatewayDocker(StorletGatewayBase):
:params params: Request parameters
"""
sreq.params['storlet_execution_path'] = self. \
paths.sbox_storlet_exec(sreq.storlet_main)
paths.get_sbox_storlet_dir(sreq.storlet_main)
def _upload_storlet_logs(self, slog_path, sreq):
"""
@ -273,10 +274,10 @@ class StorletGatewayDocker(StorletGatewayBase):
# Determine the cache we are to work with
# e.g. dependency or storlet
if is_storlet:
cache_dir = self.paths.get_host_storlet_cache_dir()
cache_dir = self.paths.host_storlet_cache_dir
get_func = sreq.file_manager.get_storlet
else:
cache_dir = self.paths.get_host_dependency_cache_dir()
cache_dir = self.paths.host_dependency_cache_dir
get_func = sreq.file_manager.get_dependency
if not os.path.exists(cache_dir):
@ -330,7 +331,8 @@ class StorletGatewayDocker(StorletGatewayBase):
# 1. The Docker container does not hold a copy of the object
# 2. The Docker container holds an older version of the object
update_docker = False
docker_storlet_path = self.paths.host_storlet(sreq.storlet_main)
docker_storlet_path = \
self.paths.get_host_storlet_dir(sreq.storlet_main)
docker_target_path = os.path.join(docker_storlet_path, obj_name)
if not os.path.exists(docker_storlet_path):
@ -367,7 +369,7 @@ class StorletGatewayDocker(StorletGatewayBase):
:returns: True if the Docker container was updated
"""
# where at the host side, reside the storlet containers
storlet_path = self.paths.host_storlet_prefix()
storlet_path = self.paths.host_storlet_base_dir
if not os.path.exists(storlet_path):
os.makedirs(storlet_path, 0o755)

@ -112,27 +112,26 @@ class RunTimePaths(object):
:param conf: gateway conf
"""
self.scope = scope
self.factory_pipe_suffix = 'factory_pipe'
self.sandbox_pipe_prefix = '/mnt/channels'
self.storlet_pipe_suffix = '_storlet_pipe'
self.factory_pipe_name = 'factory_pipe'
self.sandbox_pipe_dir = '/mnt/channels'
self.sandbox_storlet_dir_prefix = '/home/swift'
self.host_root = conf.get('host_root', '/home/docker_device')
self.host_pipe_root = \
self.sandbox_storlet_base_dir = '/home/swift'
self.host_root_dir = conf.get('host_root', '/home/docker_device')
self.host_pipe_root_dir = \
conf.get('pipes_dir',
os.path.join(self.host_root, 'pipes', 'scopes'))
self.host_storlet_root = \
os.path.join(self.host_root_dir, 'pipes', 'scopes'))
self.host_storlet_root_dir = \
conf.get('storlets_dir',
os.path.join(self.host_root, 'storlets', 'scopes'))
self.host_log_path_root = \
os.path.join(self.host_root_dir, 'storlets', 'scopes'))
self.host_log_root_dir = \
conf.get('log_dir',
os.path.join(self.host_root, 'logs', 'scopes'))
self.host_cache_root = \
os.path.join(self.host_root_dir, 'logs', 'scopes'))
self.host_cache_root_dir = \
conf.get('cache_dir',
os.path.join(self.host_root, 'cache', 'scopes'))
os.path.join(self.host_root_dir, 'cache', 'scopes'))
self.host_restart_script_dir = \
conf.get('script_dir',
os.path.join(self.host_root, 'scripts'))
os.path.join(self.host_root_dir, 'scripts'))
self.host_storlet_python_lib_dir = ('/usr/local/lib/python2.7/'
'dist-packages/storlets')
@ -143,48 +142,50 @@ class RunTimePaths(object):
self.host_storlet_native_bin_dir = '/usr/local/libexec/storlets'
self.sandbox_storlet_native_bin_dir = '/usr/local/libexec/storlets'
def host_pipe_prefix(self):
return os.path.join(self.host_pipe_root, self.scope)
@property
def host_pipe_dir(self):
return os.path.join(self.host_pipe_root_dir, self.scope)
def create_host_pipe_prefix(self):
path = self.host_pipe_prefix()
def create_host_pipe_dir(self):
path = self.host_pipe_dir
if not os.path.exists(path):
os.makedirs(path)
# 0777 should be 0700 when we get user namespaces in Docker
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
return path
@property
def host_factory_pipe(self):
return os.path.join(self.host_pipe_prefix(),
self.factory_pipe_suffix)
return os.path.join(self.host_pipe_dir, self.factory_pipe_name)
def host_storlet_pipe(self, storlet_id):
return os.path.join(self.host_pipe_prefix(),
storlet_id)
def get_host_storlet_pipe(self, storlet_id):
return os.path.join(self.host_pipe_dir, storlet_id)
def sbox_storlet_pipe(self, storlet_id):
return os.path.join(self.sandbox_pipe_prefix,
storlet_id)
def get_sbox_storlet_pipe(self, storlet_id):
return os.path.join(self.sandbox_pipe_dir, storlet_id)
def sbox_storlet_exec(self, storlet_id):
return os.path.join(self.sandbox_storlet_dir_prefix, storlet_id)
def get_sbox_storlet_dir(self, storlet_id):
return os.path.join(self.sandbox_storlet_base_dir, storlet_id)
def host_storlet_prefix(self):
return os.path.join(self.host_storlet_root, self.scope)
@property
def host_storlet_base_dir(self):
return os.path.join(self.host_storlet_root_dir, self.scope)
def host_storlet(self, storlet_id):
return os.path.join(self.host_storlet_prefix(), storlet_id)
def get_host_storlet_dir(self, storlet_id):
return os.path.join(self.host_storlet_base_dir, storlet_id)
def slog_path(self, storlet_id):
log_dir = os.path.join(self.host_log_path_root, self.scope, storlet_id)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
return log_dir
def get_host_slog_path(self, storlet_id):
return os.path.join(
self.host_log_root_dir, self.scope, storlet_id,
'storlet_invoke.log')
def get_host_storlet_cache_dir(self):
return os.path.join(self.host_cache_root, self.scope, 'storlet')
@property
def host_storlet_cache_dir(self):
return os.path.join(self.host_cache_root_dir, self.scope, 'storlet')
def get_host_dependency_cache_dir(self):
return os.path.join(self.host_cache_root, self.scope, 'dependency')
@property
def host_dependency_cache_dir(self):
return os.path.join(self.host_cache_root_dir, self.scope, 'dependency')
"""---------------------------------------------------------------------------
Docker Stateful Container API
@ -245,7 +246,7 @@ class RunTimeSandbox(object):
0 when the daemon factory is not responsive
-1 when it fails to send command to the process
"""
pipe_path = self.paths.host_factory_pipe()
pipe_path = self.paths.host_factory_pipe
client = SBusClient(pipe_path)
try:
resp = client.ping()
@ -293,10 +294,10 @@ class RunTimeSandbox(object):
docker_container_name = '%s_%s' % (self.docker_image_name_prefix,
self.scope)
pipe_mount = '%s:%s' % (self.paths.host_pipe_prefix(),
self.paths.sandbox_pipe_prefix)
storlet_mount = '%s:%s:ro' % (self.paths.host_storlet_prefix(),
self.paths.sandbox_storlet_dir_prefix)
pipe_mount = '%s:%s' % (self.paths.host_pipe_dir,
self.paths.sandbox_pipe_dir)
storlet_mount = '%s:%s:ro' % (self.paths.host_storlet_base_dir,
self.paths.sandbox_storlet_base_dir)
storlet_python_lib_mount = '%s:%s:ro' % (
self.paths.host_storlet_python_lib_dir,
self.paths.sandbox_storlet_python_lib_dir)
@ -330,7 +331,7 @@ class RunTimeSandbox(object):
Restarts the scope's sandbox
"""
self.paths.create_host_pipe_prefix()
self.paths.create_host_pipe_dir()
docker_image_name = self.scope
try:
@ -354,12 +355,12 @@ class RunTimeSandbox(object):
"""
Start SDaemon process in the scope's sandbox
"""
pipe_path = self.paths.host_factory_pipe()
pipe_path = self.paths.host_factory_pipe
client = SBusClient(pipe_path)
try:
resp = client.start_daemon(
language.lower(), spath, storlet_id,
self.paths.sbox_storlet_pipe(storlet_id),
self.paths.get_sbox_storlet_pipe(storlet_id),
self.storlet_daemon_debug_level,
self.storlet_daemon_thread_pool_size,
language_version)
@ -377,7 +378,7 @@ class RunTimeSandbox(object):
"""
Stop SDaemon process in the scope's sandbox
"""
pipe_path = self.paths.host_factory_pipe()
pipe_path = self.paths.host_factory_pipe
client = SBusClient(pipe_path)
try:
resp = client.stop_daemon(storlet_id)
@ -394,7 +395,7 @@ class RunTimeSandbox(object):
"""
Get the status of SDaemon process in the scope's sandbox
"""
pipe_path = self.paths.host_factory_pipe()
pipe_path = self.paths.host_factory_pipe
client = SBusClient(pipe_path)
try:
resp = client.daemon_status(storlet_id)
@ -416,12 +417,11 @@ class RunTimeSandbox(object):
:param dependencies: A list of dependency file
:returns: classpath string
"""
class_path = os.path.join(self.paths.sbox_storlet_exec(storlet_main),
storlet_id)
class_path = os.path.join(
self.paths.get_sbox_storlet_dir(storlet_main), storlet_id)
dep_path_list = \
[os.path.join(self.paths.sbox_storlet_exec(storlet_main),
dep)
[os.path.join(self.paths.get_sbox_storlet_dir(storlet_main), dep)
for dep in dependencies]
return class_path + ':' + ':'.join(dep_path_list)
@ -496,9 +496,7 @@ class StorletInvocationProtocol(object):
timeout, logger, extra_sources=None):
self.srequest = srequest
self.storlet_pipe_path = storlet_pipe_path
self.storlet_logger_path = storlet_logger_path
self.storlet_logger = StorletLogger(self.storlet_logger_path,
'storlet_invoke')
self.storlet_logger = StorletLogger(storlet_logger_path)
self.logger = logger
self.timeout = timeout
@ -525,9 +523,6 @@ class StorletInvocationProtocol(object):
'user_metadata': source.user_metadata,
'data_iter': source.data_iter})
if not os.path.exists(storlet_logger_path):
os.makedirs(storlet_logger_path)
@property
def input_data_read_fd(self):
"""

@ -0,0 +1,76 @@
# Copyright (c) 2010-2015 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import shutil
import tempfile
import unittest
from storlets.gateway.common.exceptions import StorletLoggerError
from storlets.gateway.common.logger import StorletLogger
class TestStorletLogger(unittest.TestCase):
def setUp(self):
self.log_dir = tempfile.mkdtemp()
self.log_path = tempfile.mktemp(dir=self.log_dir)
self.logger = StorletLogger(self.log_path)
def tearDown(self):
if os.path.isdir(self.log_dir):
shutil.rmtree(self.log_dir)
def test_open_close(self):
self.assertIsNone(self.logger._file)
self.logger.open()
self.assertIsNotNone(self.logger._file)
self.assertTrue(os.path.isfile(self.log_path))
self.logger.close()
self.assertIsNone(self.logger._file)
# Make sure that log_dir is deleted
shutil.rmtree(self.log_dir)
# As log_dir does not exists, open should create it
self.logger.open()
self.assertIsNotNone(self.logger._file)
self.assertTrue(os.path.isdir(self.log_dir))
self.assertTrue(os.path.isfile(self.log_path))
self.logger.close()
self.assertIsNone(self.logger._file)
# opened twice
self.logger.open()
with self.assertRaises(StorletLoggerError):
self.logger.open()
self.logger.close()
# closed twice
self.logger.open()
self.logger.close()
with self.assertRaises(StorletLoggerError):
self.logger.close()
def test_getfd(self):
self.assertIsNone(self.logger.getfd())
self.logger.open()
self.assertIsNotNone(self.logger.getfd())
self.logger.close()
def test_getsize(self):
self.logger.open()
self.logger._file.write('a' * 1024)
self.logger.close()
self.assertEqual(1024, self.logger.getsize())

@ -507,8 +507,7 @@ use = egg:swift#catch_errors
mock_close)
@mock.patch('storlets.gateway.gateways.docker.runtime.select.select',
lambda r, w, x, timeout=None: (r, w, x))
@mock.patch('storlets.gateway.common.stob.os.read',
mock_read)
@mock.patch('storlets.gateway.common.stob.os.read', mock_read)
@mock.patch(invocation_protocol, mock_writer)
def test_invocation_flow(client):
client.ping.return_value = SBusResponse(True, 'OK')

@ -106,19 +106,20 @@ class TestRuntimePaths(unittest.TestCase):
def tearDown(self):
pass
def test_host_pipe_prefix(self):
def test_host_pipe_dir(self):
self.assertEqual(
self.paths.host_pipe_prefix(),
os.path.join(self.pipes_dir, self.scope))
os.path.join(self.pipes_dir, self.scope),
self.paths.host_pipe_dir)
def test_create_host_pipe_prefix(self):
pipedir = self.paths.host_pipe_prefix()
def test_create_host_pipe_dir(self):
pipedir = self.paths.host_pipe_dir
# When the directory exists
with mock.patch('os.path.exists', return_value=True), \
mock.patch('os.makedirs') as m, \
mock.patch('os.chmod') as c:
self.paths.create_host_pipe_prefix()
self.assertEqual(os.path.join(self.pipes_dir, self.scope),
self.paths.create_host_pipe_dir())
self.assertEqual(0, m.call_count)
cargs, ckwargs = c.call_args
# Make sure about the target directory
@ -128,7 +129,8 @@ class TestRuntimePaths(unittest.TestCase):
with mock.patch('os.path.exists', return_value=False), \
mock.patch('os.makedirs') as m, \
mock.patch('os.chmod') as c:
self.paths.create_host_pipe_prefix(),
self.assertEqual(os.path.join(self.pipes_dir, self.scope),
self.paths.create_host_pipe_dir())
self.assertEqual(1, m.call_count)
# Make sure about the target directory
margs, mkwargs = m.call_args
@ -138,61 +140,49 @@ class TestRuntimePaths(unittest.TestCase):
def test_host_factory_pipe(self):
self.assertEqual(
self.paths.host_factory_pipe(),
self.paths.host_factory_pipe,
os.path.join(self.pipes_dir, self.scope, 'factory_pipe'))
def test_host_storlet_pipe(self):
def test_get_host_storlet_pipe(self):
self.assertEqual(
self.paths.host_storlet_pipe(self.storlet_id),
os.path.join(self.pipes_dir, self.scope, self.storlet_id))
os.path.join(self.pipes_dir, self.scope, self.storlet_id),
self.paths.get_host_storlet_pipe(self.storlet_id))
def test_sbox_storlet_pipe(self):
def test_get_sbox_storlet_pipe(self):
self.assertEqual(
self.paths.sbox_storlet_pipe(self.storlet_id),
os.path.join('/mnt/channels', self.storlet_id))
os.path.join('/mnt/channels', self.storlet_id),
self.paths.get_sbox_storlet_pipe(self.storlet_id))
def test_sbox_storlet_exec(self):
def test_get_sbox_storlet_dir(self):
self.assertEqual(
self.paths.sbox_storlet_exec(self.storlet_id),
os.path.join('/home/swift', self.storlet_id))
os.path.join('/home/swift', self.storlet_id),
self.paths.get_sbox_storlet_dir(self.storlet_id))
def test_host_storlet_prefix(self):
def test_host_storlet_base_dir(self):
self.assertEqual(
self.paths.host_storlet_prefix(),
self.paths.host_storlet_base_dir,
os.path.join(self.storlets_dir, self.scope))
def test_host_storlet(self):
def test_get_host_storlet_dir(self):
self.assertEqual(
self.paths.host_storlet(self.storlet_id),
os.path.join(self.storlets_dir, self.scope,
self.storlet_id))
os.path.join(self.storlets_dir, self.scope, self.storlet_id),
self.paths.get_host_storlet_dir(self.storlet_id))
def test_slog_path(self):
with mock.patch('os.path.exists', return_value=True), \
mock.patch('os.makedirs') as m:
self.assertEqual(
self.paths.slog_path(self.storlet_id),
os.path.join(self.log_dir, self.scope,
self.storlet_id))
self.assertEqual(0, m.call_count)
with mock.patch('os.path.exists', return_value=False), \
mock.patch('os.makedirs') as m:
self.assertEqual(
self.paths.slog_path(self.storlet_id),
os.path.join(self.log_dir, self.scope,
self.storlet_id))
self.assertEqual(1, m.call_count)
def test_get_host_storlet_cache_dir(self):
def test_get_host_slog_path(self):
self.assertEqual(
self.paths.get_host_storlet_cache_dir(),
os.path.join(self.cache_dir, self.scope, 'storlet'))
os.path.join(self.log_dir, self.scope, self.storlet_id,
'storlet_invoke.log'),
self.paths.get_host_slog_path(self.storlet_id))
def test_get_host_dependency_cache_dir(self):
def test_host_storlet_cache_dir(self):
self.assertEqual(
self.paths.get_host_dependency_cache_dir(),
os.path.join(self.cache_dir, self.scope, 'dependency'))
os.path.join(self.cache_dir, self.scope, 'storlet'),
self.paths.host_storlet_cache_dir)
def test_host_dependency_cache_dir(self):
self.assertEqual(
os.path.join(self.cache_dir, self.scope, 'dependency'),
self.paths.host_dependency_cache_dir)
def test_runtime_paths_default(self):
# CHECK: docs says we need 4 dirs for communicate
@ -215,36 +205,36 @@ class TestRuntimePaths(unittest.TestCase):
# For pipe
self.assertEqual('/home/docker_device/pipes/scopes/account',
runtime_paths.host_pipe_prefix())
runtime_paths.host_pipe_dir)
# 1. host_factory_pipe_path <pipes_dir>/<scope>/factory_pipe
self.assertEqual(
'/home/docker_device/pipes/scopes/account/factory_pipe',
runtime_paths.host_factory_pipe())
runtime_paths.host_factory_pipe)
# 2. host_storlet_pipe_path <pipes_dir>/<scope>/<storlet_id>
self.assertEqual(
'/home/docker_device/pipes/scopes/account/Storlet-1.0.jar',
runtime_paths.host_storlet_pipe(storlet_id))
runtime_paths.get_host_storlet_pipe(storlet_id))
# 3. Yes, right now, we don't have the path for #3 in Python
# 4. sandbox_storlet_pipe_path | /mnt/channels/<storlet_id>
self.assertEqual('/mnt/channels/Storlet-1.0.jar',
runtime_paths.sbox_storlet_pipe(storlet_id))
runtime_paths.get_sbox_storlet_pipe(storlet_id))
# This looks like for jar load?
self.assertEqual('/home/docker_device/storlets/scopes/account',
runtime_paths.host_storlet_prefix())
runtime_paths.host_storlet_base_dir)
self.assertEqual(
'/home/docker_device/storlets/scopes/account/Storlet-1.0.jar',
runtime_paths.host_storlet(storlet_id))
runtime_paths.get_host_storlet_dir(storlet_id))
# And this one is a mount poit in sand box?
self.assertEqual('/home/swift/Storlet-1.0.jar',
runtime_paths.sbox_storlet_exec(storlet_id))
runtime_paths.get_sbox_storlet_dir(storlet_id))
@with_tempdir
def test_create_host_pipe_prefix_with_real_dir(self, temp_dir):
def test_create_host_pipe_dir_with_real_dir(self, temp_dir):
runtime_paths = RunTimePaths('account', {'host_root': temp_dir})
runtime_paths.create_host_pipe_prefix()
path = runtime_paths.host_pipe_prefix()
runtime_paths.create_host_pipe_dir()
path = runtime_paths.host_pipe_dir
self.assertTrue(os.path.exists(path))
self.assertTrue(os.path.isdir(path))
permission = oct(os.stat(path)[ST_MODE])[-3:]
@ -324,7 +314,7 @@ class TestRunTimeSandbox(unittest.TestCase):
return (self.stdout, self.stderr)
with mock.patch('storlets.gateway.gateways.docker.runtime.'
'RunTimePaths.create_host_pipe_prefix'), \
'RunTimePaths.create_host_pipe_dir'), \
mock.patch('storlets.gateway.gateways.docker.runtime.'
'subprocess.Popen') as popen:
_wait = self.sbox.wait
@ -341,7 +331,7 @@ class TestRunTimeSandbox(unittest.TestCase):
self.sbox.wait = _wait
with mock.patch('storlets.gateway.gateways.docker.runtime.'
'RunTimePaths.create_host_pipe_prefix'), \
'RunTimePaths.create_host_pipe_dir'), \
mock.patch('storlets.gateway.gateways.docker.runtime.'
'subprocess.Popen') as popen:
_wait = self.sbox.wait
@ -360,7 +350,7 @@ class TestRunTimeSandbox(unittest.TestCase):
self.sbox.wait = _wait
with mock.patch('storlets.gateway.gateways.docker.runtime.'
'RunTimePaths.create_host_pipe_prefix'), \
'RunTimePaths.create_host_pipe_dir'), \
mock.patch('storlets.gateway.gateways.docker.runtime.'
'subprocess.Popen') as popen:
_wait = self.sbox.wait
@ -379,7 +369,7 @@ class TestRunTimeSandbox(unittest.TestCase):
self.sbox.wait = _wait
with mock.patch('storlets.gateway.gateways.docker.runtime.'
'RunTimePaths.create_host_pipe_prefix'), \
'RunTimePaths.create_host_pipe_dir'), \
mock.patch('storlets.gateway.gateways.docker.runtime.'
'subprocess.Popen') as popen:
_wait = self.sbox.wait