Remove costilius module
Rally droped to maintain python2.6 thus we don't need to maintain it anymore. Change-Id: I60031646247cc94ca3e8506888d2cbc82cac4bdb
This commit is contained in:
parent
670c2c6566
commit
3beac49204
|
@ -1,118 +0,0 @@
|
|||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""
|
||||
This module is a storage for different types of workarounds.
|
||||
"""
|
||||
|
||||
from distutils import spawn
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from rally.common.i18n import _LE
|
||||
from rally import exceptions
|
||||
|
||||
|
||||
try:
|
||||
from collections import OrderedDict # noqa
|
||||
except ImportError:
|
||||
# NOTE(andreykurilin): Python 2.6 issue. OrderedDict is not
|
||||
# present in `collections` library.
|
||||
from ordereddict import OrderedDict # noqa
|
||||
|
||||
|
||||
def is_py26():
|
||||
return sys.version_info[:2] == (2, 6)
|
||||
|
||||
|
||||
if is_py26():
|
||||
import simplejson as json
|
||||
else:
|
||||
import json
|
||||
|
||||
|
||||
def json_loads(*args, **kwargs):
|
||||
"""Deserialize a str or unicode instance to a Python object.
|
||||
|
||||
'simplejson' is used in Python 2.6 environment, because standard 'json'
|
||||
library not include several important features(for example
|
||||
'object_pairs_hook', which allows to deserialize input object to
|
||||
OrderedDict)
|
||||
"""
|
||||
|
||||
return json.loads(*args, **kwargs)
|
||||
|
||||
|
||||
def sp_check_output(*popenargs, **kwargs):
|
||||
"""Run command with arguments and return its output as a byte string.
|
||||
|
||||
If the exit code was non-zero it raises a CalledProcessError. The
|
||||
CalledProcessError object will have the return code in the returncode
|
||||
attribute and output in the output attribute.
|
||||
|
||||
The arguments are the same as for the Popen constructor.
|
||||
"""
|
||||
|
||||
if is_py26():
|
||||
# NOTE(andreykurilin): as I said before, support python 26 env is hard
|
||||
# task. Subprocess supports check_output function from Python 2.7, so
|
||||
# let's copy-paste code of this function from it.
|
||||
if "stdout" in kwargs:
|
||||
raise ValueError("stdout argument not allowed, "
|
||||
"it will be overridden.")
|
||||
process = subprocess.Popen(stdout=subprocess.PIPE,
|
||||
*popenargs, **kwargs)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
raise subprocess.CalledProcessError(retcode, cmd, output=output)
|
||||
return output
|
||||
return subprocess.check_output(*popenargs, **kwargs)
|
||||
|
||||
|
||||
def get_interpreter(python_version):
|
||||
"""Discovers PATH to find proper python interpreter
|
||||
|
||||
:param python_version: (major, minor) version numbers
|
||||
:type python_version: tuple
|
||||
"""
|
||||
|
||||
if not isinstance(python_version, tuple):
|
||||
msg = (_LE("given format of python version `%s` is invalid") %
|
||||
python_version)
|
||||
raise exceptions.InvalidArgumentsException(msg)
|
||||
|
||||
interpreter_name = "python%s.%s" % python_version
|
||||
interpreter = spawn.find_executable(interpreter_name)
|
||||
if interpreter:
|
||||
return interpreter
|
||||
else:
|
||||
interpreters = filter(
|
||||
os.path.isfile, [os.path.join(p, interpreter_name)
|
||||
for p in os.environ.get("PATH", "").split(":")])
|
||||
cmd = "%s -c 'import sys; print(sys.version_info[:2])'"
|
||||
for interpreter in interpreters:
|
||||
try:
|
||||
out = sp_check_output(cmd % interpreter, shell=True)
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
else:
|
||||
if out.strip() == str(python_version):
|
||||
return interpreter
|
|
@ -13,14 +13,13 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import json
|
||||
|
||||
from sqlalchemy.dialects import mysql as mysql_types
|
||||
from sqlalchemy.ext import mutable
|
||||
from sqlalchemy import types as sa_types
|
||||
|
||||
from rally.common import costilius
|
||||
|
||||
|
||||
class JSONEncodedDict(sa_types.TypeDecorator):
|
||||
"""Represents an immutable structure as a json-encoded string."""
|
||||
|
@ -34,8 +33,8 @@ class JSONEncodedDict(sa_types.TypeDecorator):
|
|||
|
||||
def process_result_value(self, value, dialect):
|
||||
if value is not None:
|
||||
value = costilius.json_loads(
|
||||
value, object_pairs_hook=costilius.OrderedDict)
|
||||
value = json.loads(
|
||||
value, object_pairs_hook=collections.OrderedDict)
|
||||
return value
|
||||
|
||||
|
||||
|
|
|
@ -13,16 +13,16 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import functools
|
||||
|
||||
from rally.common import costilius
|
||||
from rally.common import utils
|
||||
|
||||
|
||||
class ActionTimerMixin(object):
|
||||
|
||||
def __init__(self):
|
||||
self._atomic_actions = costilius.OrderedDict()
|
||||
self._atomic_actions = collections.OrderedDict()
|
||||
|
||||
def atomic_actions(self):
|
||||
"""Returns the content of each atomic action."""
|
||||
|
|
|
@ -22,7 +22,6 @@ import tempfile
|
|||
|
||||
from oslo_utils import encodeutils
|
||||
|
||||
from rally.common import costilius
|
||||
from rally.common.i18n import _
|
||||
from rally.common.io import subunit_v2
|
||||
from rally.common import logging
|
||||
|
@ -43,7 +42,7 @@ class TempestSetupFailure(exceptions.RallyException):
|
|||
def check_output(*args, **kwargs):
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
try:
|
||||
output = costilius.sp_check_output(*args, **kwargs)
|
||||
output = subprocess.check_output(*args, **kwargs)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.error("Failed cmd: '%s'" % e.cmd)
|
||||
LOG.error("Error output: '%s'" % encodeutils.safe_decode(e.output))
|
||||
|
@ -182,23 +181,8 @@ class Tempest(object):
|
|||
LOG.debug("No virtual environment for Tempest found.")
|
||||
LOG.info(_("Installing the virtual environment for Tempest."))
|
||||
LOG.debug("Virtual environment directory: %s" % path_to_venv)
|
||||
required_vers = (2, 7)
|
||||
if sys.version_info[:2] != required_vers:
|
||||
# NOTE(andreykurilin): let's try to find a suitable python
|
||||
# interpreter for Tempest
|
||||
python_interpreter = costilius.get_interpreter(required_vers)
|
||||
if not python_interpreter:
|
||||
raise exceptions.IncompatiblePythonVersion(
|
||||
version=sys.version, required_version=required_vers)
|
||||
LOG.info(
|
||||
_("Tempest requires Python %(required)s, '%(found)s' was "
|
||||
"found in your system and it will be used for installing"
|
||||
" virtual environment.") % {"required": required_vers,
|
||||
"found": python_interpreter})
|
||||
else:
|
||||
python_interpreter = sys.executable
|
||||
try:
|
||||
check_output(["virtualenv", "-p", python_interpreter, ".venv"],
|
||||
check_output(["virtualenv", "-p", sys.executable, ".venv"],
|
||||
cwd=self.path())
|
||||
# NOTE(kun): Using develop mode installation is for run
|
||||
# multiple tempest instance. However, dependency
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from rally.common import costilius
|
||||
from rally import exceptions
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
PATH = "rally.common.costilius"
|
||||
|
||||
|
||||
class SPCheckCallTestCase(test.TestCase):
|
||||
|
||||
@mock.patch("%s.subprocess" % PATH)
|
||||
@mock.patch("%s.is_py26" % PATH, return_value=True)
|
||||
def test_simulation_of_py26_env(self, mock_is_py26, mock_subprocess):
|
||||
output = "output"
|
||||
process = mock.MagicMock()
|
||||
process.communicate.return_value = (output, "unused_err")
|
||||
process.poll.return_value = None
|
||||
|
||||
mock_subprocess.Popen.return_value = process
|
||||
some_args = (1, 2)
|
||||
some_kwargs = {"a": 2}
|
||||
|
||||
self.assertEqual(output, costilius.sp_check_output(*some_args,
|
||||
**some_kwargs))
|
||||
|
||||
mock_subprocess.Popen.assert_called_once_with(
|
||||
stdout=mock_subprocess.PIPE, *some_args, **some_kwargs)
|
||||
self.assertFalse(mock_subprocess.check_output.called)
|
||||
|
||||
@mock.patch("%s.subprocess" % PATH)
|
||||
@mock.patch("%s.is_py26" % PATH, return_value=False)
|
||||
def test_simulation_of_any_not_py26_env(self, mock_is_py26,
|
||||
mock_subprocess):
|
||||
output = "output"
|
||||
mock_subprocess.check_output.return_value = output
|
||||
|
||||
some_args = (1, 2)
|
||||
some_kwargs = {"a": 2}
|
||||
|
||||
self.assertEqual(output, costilius.sp_check_output(*some_args,
|
||||
**some_kwargs))
|
||||
|
||||
mock_subprocess.check_output.assert_called_once_with(
|
||||
*some_args, **some_kwargs)
|
||||
self.assertFalse(mock_subprocess.Popen.called)
|
||||
|
||||
|
||||
class GetInterpreterTestCase(test.TestCase):
|
||||
def test_wrong_format(self):
|
||||
self.assertRaises(exceptions.InvalidArgumentsException,
|
||||
costilius.get_interpreter, "something_bad")
|
||||
|
||||
@mock.patch("%s.spawn" % PATH)
|
||||
@mock.patch("%s.sp_check_output" % PATH)
|
||||
@mock.patch("%s.os.path.isfile" % PATH)
|
||||
@mock.patch("%s.os.environ" % PATH)
|
||||
def test_found_correct_python_interpreter_with_distutils(
|
||||
self, mock_environ, mock_isfile, mock_sp_check_output, mock_spawn):
|
||||
vers = (2, 7)
|
||||
interpreter = "something"
|
||||
mock_spawn.find_executable.return_value = interpreter
|
||||
|
||||
self.assertEqual(interpreter, costilius.get_interpreter(vers))
|
||||
self.assertFalse(mock_environ.called)
|
||||
self.assertFalse(mock_isfile.called)
|
||||
self.assertFalse(mock_sp_check_output.called)
|
||||
|
||||
@mock.patch("%s.spawn" % PATH)
|
||||
@mock.patch("%s.sp_check_output" % PATH)
|
||||
@mock.patch("%s.os.path.isfile" % PATH, return_value=True)
|
||||
@mock.patch("%s.os.environ" % PATH)
|
||||
def test_found_correct_python_interpreter_without_distutils(
|
||||
self, mock_environ, mock_isfile, mock_sp_check_output, mock_spawn):
|
||||
vers = (2, 7)
|
||||
paths = ["one_path", "second_path"]
|
||||
mock_environ.get.return_value = ":".join(paths)
|
||||
mock_sp_check_output.return_value = "%s\n" % str(vers)
|
||||
mock_spawn.find_executable.return_value = None
|
||||
|
||||
found_interpreter = costilius.get_interpreter(vers)
|
||||
|
||||
self.assertEqual(1, mock_sp_check_output.call_count)
|
||||
self.assertIn(
|
||||
found_interpreter, ["%s/%s" % (f, "python2.7") for f in paths])
|
|
@ -13,9 +13,10 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
|
||||
import mock
|
||||
|
||||
from rally.common import costilius
|
||||
from rally.task import atomic
|
||||
from tests.unit import test
|
||||
|
||||
|
@ -39,7 +40,7 @@ class AtomicActionTestCase(test.TestCase):
|
|||
pass
|
||||
|
||||
expected = [("test", 20), ("test (2)", 12), ("some", 4)]
|
||||
self.assertEqual(costilius.OrderedDict(expected),
|
||||
self.assertEqual(collections.OrderedDict(expected),
|
||||
inst.atomic_actions())
|
||||
|
||||
@mock.patch("time.time", side_effect=[1, 3])
|
||||
|
@ -56,7 +57,7 @@ class AtomicActionTestCase(test.TestCase):
|
|||
pass
|
||||
|
||||
expected = [("test", 2)]
|
||||
self.assertEqual(costilius.OrderedDict(expected),
|
||||
self.assertEqual(collections.OrderedDict(expected),
|
||||
inst.atomic_actions())
|
||||
|
||||
@mock.patch("time.time", side_effect=[1, 3])
|
||||
|
@ -70,7 +71,7 @@ class AtomicActionTestCase(test.TestCase):
|
|||
|
||||
inst = Some()
|
||||
self.assertEqual(5, inst.some_func(2, 3))
|
||||
self.assertEqual(costilius.OrderedDict({"some": 2}),
|
||||
self.assertEqual(collections.OrderedDict({"some": 2}),
|
||||
inst.atomic_actions())
|
||||
|
||||
@mock.patch("time.time", side_effect=[1, 3])
|
||||
|
@ -87,7 +88,7 @@ class AtomicActionTestCase(test.TestCase):
|
|||
|
||||
inst = TestTimer()
|
||||
self.assertRaises(TestException, inst.some_func)
|
||||
self.assertEqual(costilius.OrderedDict({"test": 2}),
|
||||
self.assertEqual(collections.OrderedDict({"test": 2}),
|
||||
inst.atomic_actions())
|
||||
|
||||
@mock.patch("time.time", side_effect=[1, 3, 1, 3])
|
||||
|
@ -106,20 +107,20 @@ class AtomicActionTestCase(test.TestCase):
|
|||
|
||||
inst = TestAtomicTimer()
|
||||
self.assertEqual(5, inst.some_func(2, 3))
|
||||
self.assertEqual(costilius.OrderedDict({"some": 2}),
|
||||
self.assertEqual(collections.OrderedDict({"some": 2}),
|
||||
inst.atomic_actions())
|
||||
|
||||
inst = TestAtomicTimer()
|
||||
self.assertEqual(5, inst.some_func(2, 3, atomic_action=False))
|
||||
self.assertEqual(costilius.OrderedDict(),
|
||||
self.assertEqual(collections.OrderedDict(),
|
||||
inst.atomic_actions())
|
||||
|
||||
inst = TestAtomicTimer()
|
||||
self.assertEqual(5, inst.other_func(2, 3))
|
||||
self.assertEqual(costilius.OrderedDict(),
|
||||
self.assertEqual(collections.OrderedDict(),
|
||||
inst.atomic_actions())
|
||||
|
||||
inst = TestAtomicTimer()
|
||||
self.assertEqual(5, inst.other_func(2, 3, foo=True))
|
||||
self.assertEqual(costilius.OrderedDict({"some": 2}),
|
||||
self.assertEqual(collections.OrderedDict({"some": 2}),
|
||||
inst.atomic_actions())
|
||||
|
|
|
@ -94,22 +94,18 @@ class TempestUtilsTestCase(BaseTestCase):
|
|||
self.assertFalse(mock_check_output.called)
|
||||
|
||||
@mock.patch("%s.tempest.sys" % TEMPEST_PATH)
|
||||
@mock.patch("%s.tempest.costilius.get_interpreter" % TEMPEST_PATH,
|
||||
return_value="python")
|
||||
@mock.patch("os.path.isdir", return_value=False)
|
||||
@mock.patch("%s.tempest.check_output" % TEMPEST_PATH,
|
||||
return_value="some_output")
|
||||
def test__venv_install_when_venv_not_exist(self, mock_check_output,
|
||||
mock_isdir,
|
||||
mock_get_interpreter, mock_sys):
|
||||
mock_isdir, mock_sys):
|
||||
mock_sys.version_info = "not_py27_env"
|
||||
|
||||
self.verifier._install_venv()
|
||||
|
||||
mock_isdir.assert_called_once_with(self.verifier.path(".venv"))
|
||||
mock_check_output.assert_has_calls([
|
||||
mock.call(["virtualenv", "-p", mock_get_interpreter.return_value,
|
||||
".venv"], cwd="/tmp"),
|
||||
mock.call(["virtualenv", "-p", mock_sys.executable, ".venv"],
|
||||
cwd="/tmp"),
|
||||
mock.call(["/tmp/tools/with_venv.sh", "pip", "install", "-r",
|
||||
"requirements.txt", "-r", "test-requirements.txt"],
|
||||
cwd="/tmp"),
|
||||
|
@ -118,14 +114,13 @@ class TempestUtilsTestCase(BaseTestCase):
|
|||
])
|
||||
|
||||
@mock.patch("%s.tempest.sys" % TEMPEST_PATH)
|
||||
@mock.patch("%s.tempest.costilius.get_interpreter" % TEMPEST_PATH,
|
||||
return_value=None)
|
||||
@mock.patch("os.path.isdir", return_value=False)
|
||||
def test__venv_install_fails__when_py27_is_not_present(
|
||||
self, mock_isdir, mock_get_interpreter, mock_sys):
|
||||
self, mock_isdir, mock_sys):
|
||||
mock_sys.version_info = "not_py27_env"
|
||||
mock_sys.executable = "fake_path"
|
||||
|
||||
self.assertRaises(exceptions.IncompatiblePythonVersion,
|
||||
self.assertRaises(tempest.TempestSetupFailure,
|
||||
self.verifier._install_venv)
|
||||
|
||||
mock_isdir.assert_called_once_with(self.verifier.path(".venv"))
|
||||
|
|
Loading…
Reference in New Issue