Skip to content

Commit

Permalink
Merge pull request #172 from datmo/env-setup
Browse files Browse the repository at this point in the history
environment setup
  • Loading branch information
asampat3090 committed Jun 5, 2018
2 parents 345775e + 0f1da21 commit 6dc1194
Show file tree
Hide file tree
Showing 31 changed files with 852 additions and 382 deletions.
69 changes: 55 additions & 14 deletions datmo/cli/command/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from datmo.core.controller.environment.environment import EnvironmentController
from datmo.core.util.misc_functions import printable_string
from datmo.cli.command.project import ProjectCommand
from datmo.core.util.exceptions import EnvironmentDoesNotExist


class EnvironmentCommand(ProjectCommand):
Expand All @@ -19,36 +20,76 @@ def environment(self):
self.parse(["--help"])
return True

def setup(self, **kwargs):
name = kwargs.get("name", None)
available_environments = self.environment_controller.get_supported_environments(
)
if not name:
for idx, n in enumerate(available_environments):
self.cli_helper.echo("(%s) %s" % (idx + 1, n))
input_name = self.cli_helper.prompt(
__("prompt", "cli.environment.setup.name"))
try:
name_index = int(input_name)
except ValueError:
name_index = 0
if name_index > 0 and name_index < len(available_environments):
name = available_environments[name_index - 1]
elif name_index == 0:
name = input_name
else:
self.cli_helper.echo(
__("error", "cli.environment.setup.argument", input_name))
try:
options = {"name": name}
environment_obj = self.environment_controller.setup(
options=options)
self.cli_helper.echo(
__("info", "cli.environment.setup.success",
(environment_obj.name, environment_obj.id)))
return environment_obj
except EnvironmentDoesNotExist:
self.cli_helper.echo(
__("error", "cli.environment.setup.argument", name))

def create(self, **kwargs):
self.cli_helper.echo(__("info", "cli.environment.create"))
environment_obj = self.environment_controller.create(kwargs)
created_environment_id = environment_obj.id
created_environment_obj = self.environment_controller.create(kwargs)
environments = self.environment_controller.list()
for environment_obj in environments:
if created_environment_id == environment_obj.id:
self.cli_helper.echo(__("info", "cli.environment.create.alreadyexist", created_environment_id))
return created_environment_id
self.cli_helper.echo(__("info", "cli.environment.create.success", environment_obj.id))
return created_environment_id
if created_environment_obj == environment_obj:
self.cli_helper.echo(
__("info", "cli.environment.create.alreadyexist",
created_environment_obj.id))
return created_environment_obj
self.cli_helper.echo(
__("info", "cli.environment.create.success",
created_environment_obj.id))
return created_environment_obj

def delete(self, **kwargs):
environment_id = kwargs.get('environment_id')
if self.environment_controller.delete(environment_id):
self.cli_helper.echo(__("info", "cli.environment.delete.success", environment_id))
self.cli_helper.echo(
__("info", "cli.environment.delete.success", environment_id))
return True

def ls(self):
environments = self.environment_controller.list()
header_list = ["id", "created at", "message"]
header_list = ["id", "created at", "name", "description"]
t = prettytable.PrettyTable(header_list)
environment_ids = []
for environment_obj in environments:
environment_ids.append(environment_obj.id)
environment_created_at = printable_string(
environment_obj.created_at.strftime("%Y-%m-%d %H:%M:%S"))
environment_message = printable_string(environment_obj.description) \
if environment_obj.description is not None else ''
t.add_row([environment_obj.id, environment_created_at, environment_message])

environment_name = printable_string(environment_obj.name) \
if environment_obj.name is not None else ""
environment_description = printable_string(environment_obj.description) \
if environment_obj.description is not None else ""
t.add_row([
environment_obj.id, environment_created_at, environment_name,
environment_description
])
self.cli_helper.echo(t)
return environment_ids
return environments
10 changes: 5 additions & 5 deletions datmo/cli/command/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ def create(self, **kwargs):
# creating snapshot with task id if it exists
if task_id is not None:
excluded_args = [
"environment_id", "environment_definition_paths",
"paths", "config_filepath", "config_filename",
"stats_filepath", "stats_filename"
"environment_id", "environment_paths", "paths",
"config_filepath", "config_filename", "stats_filepath",
"stats_filename"
]
for arg in excluded_args:
if arg in kwargs and kwargs[arg] is not None:
Expand All @@ -53,9 +53,9 @@ def create(self, **kwargs):

# Environment
if kwargs.get("environment_id", None) or kwargs.get(
"environment_definition_paths", None):
"environment_paths", None):
mutually_exclusive_args = [
"environment_id", "environment_definition_paths"
"environment_id", "environment_paths"
]
mutually_exclusive(mutually_exclusive_args, kwargs,
snapshot_dict)
Expand Down
9 changes: 6 additions & 3 deletions datmo/cli/command/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ def run(self, **kwargs):

# Create input dictionaries
snapshot_dict = {}
if kwargs['environment_definition_paths']:
snapshot_dict["environment_definition_paths"] =\
kwargs['environment_definition_paths']

# Environment
if kwargs.get("environment_id", None) or kwargs.get(
"environment_paths", None):
mutually_exclusive_args = ["environment_id", "environment_paths"]
mutually_exclusive(mutually_exclusive_args, kwargs, snapshot_dict)
task_dict = {
"ports": kwargs['ports'],
"interactive": kwargs['interactive']
Expand Down
136 changes: 108 additions & 28 deletions datmo/cli/command/tests/test_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,55 +53,138 @@ def __set_variables(self):
self.environment_command = EnvironmentCommand(self.temp_dir,
self.cli_helper)

def test_environment_setup_parameter(self):
# Setup the environement by passing name
self.__set_variables()
definition_filepath = os.path.join(
self.environment_command.environment_controller.
environment_directory, "Dockerfile")

# Test pass with correct input
test_name = "xgboost:cpu"
self.environment_command.parse(
["environment", "setup", "--name", test_name])
result = self.environment_command.execute()

assert result
assert os.path.isfile(definition_filepath)
assert "FROM datmo/xgboost:cpu" in open(definition_filepath,
"r").read()

# Test fail with wrong input
test_name = "random"
self.environment_command.parse(
["environment", "setup", "--name", test_name])
result = self.environment_command.execute()
assert not result

def test_environment_setup_prompt(self):
# Setup the environement by passing name
self.__set_variables()
definition_filepath = os.path.join(
self.environment_command.environment_controller.
environment_directory, "Dockerfile")

# Test success with correct prompt input using numbers
self.environment_command.parse(["environment", "setup"])

@self.environment_command.cli_helper.input("1\n")
def dummy(self):
return self.environment_command.execute()

result = dummy(self)

assert result
assert os.path.isfile(definition_filepath)
assert "FROM datmo/xgboost:cpu" in open(definition_filepath,
"r").read()

# Test success with correct prompt input using string
test_name = "xgboost:cpu"
self.environment_command.parse(["environment", "setup"])

@self.environment_command.cli_helper.input(test_name + "\n")
def dummy(self):
return self.environment_command.execute()

result = dummy(self)

assert result
assert os.path.isfile(definition_filepath)
assert "FROM datmo/xgboost:cpu" in open(definition_filepath,
"r").read()

# Test failure with prompt input number out of range
self.environment_command.parse(["environment", "setup"])

@self.environment_command.cli_helper.input("-1\n")
def dummy(self):
return self.environment_command.execute()

result = dummy(self)

assert not result

# Test failure with prompt input string incorrect
self.environment_command.parse(["environment", "setup"])

@self.environment_command.cli_helper.input("random\n")
def dummy(self):
return self.environment_command.execute()

result = dummy(self)

assert not result

def test_environment_create(self):
# 1) Environment definition file in `datmo_environment` folder
# 1) Environment definition file in project environment directory (with name / description)
# 2) Environment definition file passed as an option
# 3) Environment definition file in root project folder
# 4) Environment definition file in root project folder (should return the same environment)
# 5) No environment definition file present
# 6) No environment definition file present (should return the same environment)
self.__set_variables()
# Test option 1
# Create environment definition in `datmo_environment` folder
datmo_environment_folder = os.path.join(self.temp_dir,
"datmo_environment")

definition_filepath = os.path.join(datmo_environment_folder,
"Dockerfile")
# Create environment definition in project environment directory
definition_filepath = os.path.join(
self.environment_command.environment_controller.
environment_directory, "Dockerfile")
random_text = str(uuid.uuid1())
with open(definition_filepath, "wb") as f:
f.write(to_bytes("FROM datmo/xgboost:cpu" + "\n"))
f.write(to_bytes(str("RUN echo " + random_text)))

self.environment_command.parse(["environment", "create"])
self.environment_command.parse([
"environment", "create", "--name", "test", "--description",
"test description"
])
result = self.environment_command.execute()

assert result
assert result.name == "test"
assert result.description == "test description"

# remove datmo_environment directory
shutil.rmtree(datmo_environment_folder)
shutil.rmtree(self.environment_command.environment_controller.
environment_directory)

# Test option 2
random_datmo_environment_folder = os.path.join(self.temp_dir,
"random_datmo_dir")
os.makedirs(random_datmo_environment_folder)
random_dir = os.path.join(self.temp_dir, "random_datmo_dir")
os.makedirs(random_dir)

definition_filepath = os.path.join(random_datmo_environment_folder,
"Dockerfile")
definition_filepath = os.path.join(random_dir, "Dockerfile")
random_text = str(uuid.uuid1())
with open(definition_filepath, "wb") as f:
f.write(to_bytes("FROM datmo/xgboost:cpu" + "\n"))
f.write(to_bytes(str("RUN echo " + random_text)))

self.environment_command.parse([
"environment", "create", "--environment-def", definition_filepath
])
self.environment_command.parse(
["environment", "create", "--paths", definition_filepath])
result = self.environment_command.execute()

assert result

# remove datmo environment directory
shutil.rmtree(random_datmo_environment_folder)
# remove directory with Dockerfile
shutil.rmtree(random_dir)

# Test option 3
definition_filepath = os.path.join(self.temp_dir, "Dockerfile")
Expand All @@ -112,7 +195,6 @@ def test_environment_create(self):

self.environment_command.parse(["environment", "create"])
result = self.environment_command.execute()

assert result

# Test option 4
Expand All @@ -125,33 +207,31 @@ def test_environment_create(self):
# Test option 5
self.environment_command.parse(["environment", "create"])
result = self.environment_command.execute()

assert result

# Test option 6
self.environment_command.parse(["environment", "create"])
result_2 = self.environment_command.execute()

assert result == result_2

@pytest_docker_environment_failed_instantiation(test_datmo_dir)
def test_environment_delete(self):
self.__set_variables()
self.environment_command.parse(["environment", "create"])
environment_id = self.environment_command.execute()
environment_obj = self.environment_command.execute()

self.environment_command.parse(
["environment", "delete", "--id", environment_id])
["environment", "delete", "--id", environment_obj.id])
result = self.environment_command.execute()

assert result

def test_environment_ls(self):
self.__set_variables()
self.environment_command.parse(["environment", "create"])
environment_id = self.environment_command.execute()
created_environment_obj = self.environment_command.execute()

self.environment_command.parse(["environment", "ls"])
environment_ids = self.environment_command.execute()
environment_objs = self.environment_command.execute()

assert environment_id in environment_ids
assert created_environment_obj in environment_objs

0 comments on commit 6dc1194

Please sign in to comment.