Error message when specified directory is invalid

Catch possible exceptions which relate to a situation when the
directory (provided by a user) doesn't exist or the directory doesn't
have sufficient permissions or when it is not directory at all. Catch
these exceptions and display appropriate error messages.

Closes-bug: #1330429
Change-Id: I3551dc42e527d60a2d8b2040418b2594e08e3b09
This commit is contained in:
Andrey Tykhonov
2015-09-24 18:20:40 +03:00
parent 4ede2b4d77
commit f73a04275d
5 changed files with 125 additions and 4 deletions

View File

@@ -92,6 +92,14 @@ class LabelEmptyKeyError(BadDataException):
"""Should be raised when user provides labels with empty key."""
class InvalidDirectoryException(FuelClientException):
pass
class InvalidFileException(FuelClientException):
pass
def exceptions_decorator(func):
"""Handles HTTP errors and expected exceptions that may occur
in methods of APIClient class

View File

@@ -88,16 +88,25 @@ class Serializer(object):
def write_to_path(self, path, data):
full_path = self.prepare_path(path)
with open(full_path, "w+") as file_to_write:
self.write_to_file(file_to_write, data)
try:
with open(full_path, "w") as file_to_write:
self.write_to_file(file_to_write, data)
except IOError as e:
raise error.InvalidFileException(
"Can't write to file '{0}': {1}.".format(
full_path, e.strerror))
return full_path
def read_from_file(self, path):
return self.read_from_full_path(self.prepare_path(path))
def read_from_full_path(self, full_path):
with open(full_path, "r") as file_to_read:
return self.serializer["r"](file_to_read.read())
try:
with open(full_path, "r") as file_to_read:
return self.serializer["r"](file_to_read.read())
except IOError as e:
raise error.InvalidFileException(
"Can't open file '{0}': {1}.".format(full_path, e.strerror))
def write_to_file(self, file_obj, data):
"""Writes to opened file or file like object

View File

@@ -17,6 +17,7 @@ import os
import shutil
from fuelclient.cli.error import ActionException
from fuelclient.cli.error import InvalidDirectoryException
from fuelclient.cli.error import ServerDataException
from fuelclient.cli.serializers import listdir_without_extensions
from fuelclient.objects.base import BaseObject
@@ -156,6 +157,7 @@ class Environment(BaseObject):
def write_network_data(self, network_data, directory=os.curdir,
serializer=None):
self._check_dir(directory)
return (serializer or self.serializer).write_to_path(
self.get_network_data_path(directory),
network_data
@@ -163,6 +165,7 @@ class Environment(BaseObject):
def write_settings_data(self, settings_data, directory=os.curdir,
serializer=None):
self._check_dir(directory)
return (serializer or self.serializer).write_to_path(
self.get_settings_data_path(directory),
settings_data
@@ -171,6 +174,7 @@ class Environment(BaseObject):
def write_vmware_settings_data(self, settings_data, directory=None,
serializer=None):
directory = directory or os.curdir
self._check_dir(directory)
return (serializer or self.serializer).write_to_path(
self.get_vmware_settings_data_path(directory),
settings_data
@@ -186,22 +190,34 @@ class Environment(BaseObject):
def read_network_data(self, directory=os.curdir,
serializer=None):
self._check_dir(directory)
network_file_path = self.get_network_data_path(directory)
return (serializer or self.serializer).read_from_file(
network_file_path)
def read_settings_data(self, directory=os.curdir, serializer=None):
self._check_dir(directory)
settings_file_path = self.get_settings_data_path(directory)
return (serializer or self.serializer).read_from_file(
settings_file_path)
def _check_dir(self, directory):
if not os.path.exists(directory):
raise InvalidDirectoryException(
"Directory '{0}' doesn't exist.".format(directory))
if not os.path.isdir(directory):
raise InvalidDirectoryException(
"Error: '{0}' is not a directory.".format(directory))
def read_vmware_settings_data(self, directory=os.curdir, serializer=None):
self._check_dir(directory)
return (serializer or self.serializer).read_from_file(
self.get_vmware_settings_data_path(directory))
def read_network_template_data(self, directory=os.curdir,
serializer=None):
"""Used by 'fuel' command line utility."""
self._check_dir(directory)
network_template_file_path = self.get_network_template_data_path(
directory)
return self.read_network_template_data_from_file(
@@ -366,7 +382,9 @@ class Environment(BaseObject):
def read_deployment_info(self, fact_type,
directory=os.path.curdir, serializer=None):
self._check_dir(directory)
dir_name = self._get_fact_dir_name(fact_type, directory=directory)
self._check_dir(dir_name)
return map(
lambda f: (serializer or self.serializer).read_from_file(f),
[os.path.join(dir_name, json_file)

View File

@@ -435,3 +435,80 @@ class TestDeployChanges(base.BaseTestCase):
add_node = "--env-id=1 node set --node 1 --role=controller"
deploy_changes = "deploy-changes --env 1"
self.run_cli_commands((env_create, add_node, deploy_changes))
class TestDirectoryDoesntExistErrorMessages(base.BaseTestCase):
def test_settings_upload(self):
self.check_for_stderr(
"settings --upload --dir /foo/bar/baz --env 1",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_deployment_upload(self):
self.check_for_stderr(
"deployment --upload --dir /foo/bar/baz --env 1",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_net_upload(self):
self.check_for_stderr(
"net --upload --dir /foo/bar/baz --env 1 network",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_env_download(self):
self.load_data_to_nailgun_server()
release_id = self.get_first_deployable_release_id()
self.run_cli_commands((
"env create --name=NewEnv --release={0}".format(release_id),
"--env-id=1 node set --node 2 --role=controller"
))
self.check_for_stderr(
"network --download --dir /foo/bar/baz --env 1",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_download_network_configuration(self):
self.load_data_to_nailgun_server()
release_id = self.get_first_deployable_release_id()
self.run_cli_commands((
"env create --name=NewEnv --release={0}".format(release_id),
"--env-id=1 node set --node 2 --role=controller"
))
self.check_for_stderr(
"--env 1 network --download --dir /foo/bar/baz",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_download_default_settings(self):
self.load_data_to_nailgun_server()
release_id = self.get_first_deployable_release_id()
self.run_cli_commands((
"env create --name=NewEnv --release={0}".format(release_id),
"--env-id=1 node set --node 2 --role=controller"
))
self.check_for_stderr(
"--env 1 settings --default --dir /foo/bar/baz",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_upload_network_configuration(self):
self.check_for_stderr(
"--env 1 network --upload --dir /foo/bar/baz",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)
def test_upload_network_template(self):
self.check_for_stderr(
"--env 1 network-template --upload --dir /foo/bar/baz",
"Directory '/foo/bar/baz' doesn't exist.\n",
check_errors=False
)

View File

@@ -18,6 +18,7 @@ import json
import mock
import yaml
from fuelclient.cli import error
from fuelclient.cli.serializers import Serializer
from fuelclient.tests import base
@@ -55,3 +56,11 @@ class TestSerializers(base.UnitTestCase):
serialized = serialize(self.DATA)
deserialized = Serializer(format).deserialize(serialized)
self.assertEqual(self.DATA, deserialized)
def test_write_to_path_invalid_file_exception(self):
serializer = Serializer('json')
with self.assertRaises(error.InvalidFileException):
mo = mock.mock_open()
with mock.patch('__main__.open', mo, create=True) as mocked_open:
mocked_open.side_effect = IOError()
serializer.write_to_path('/foo/bar/baz', self.DATA)