Commit 0d6ff0f9 authored by Flavio TARSETTI's avatar Flavio TARSETTI

Merge branch '185_experience_environment_improvement' into 'master'

Experience environment improvement

See merge request !113
parents 52a19134 50dfd546
Pipeline #35611 passed with stages
in 14 minutes and 46 seconds
This diff is collapsed.
......@@ -39,11 +39,10 @@ from click_plugins import with_plugins
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QCoreApplication
from beat.core.dock import Host
from beat.cmdline.click_helper import AliasedGroup
from beat.cmdline.decorators import raise_on_error
from beat.cmdline.decorators import verbosity_option
from beat.cmdline import environments
from ..utils import setup_logger
from ..utils import check_prefix_folders
......@@ -64,19 +63,13 @@ global logger
logger = None
def dump_environments(environments_file_path):
logger.info("Generating environments information")
Host(images_cache=environments_file_path, raise_on_errors=False)
logger.info("Done")
def setup_environment_cache(ctx, param, value):
"""Click option callback to setup environment cache"""
if not value:
environments = ctx.meta["environments"]
if not os.path.exists(environments):
dump_environments(environments)
environments_file_path = ctx.meta["environments"]
if not os.path.exists(environments_file_path):
ctx.invoke(environments.list, type_="all", output=environments_file_path)
def check_prefix(prefix_path):
......@@ -194,15 +187,22 @@ Example:
@editor.command(epilog=ENV_REFRESH_EPILOG)
@click.option(
"--type",
"-t",
"type_",
type=click.Choice(["docker", "remote", "all"], case_sensitive=False),
default="all",
)
@click.pass_context
@raise_on_error
def refresh_env(ctx):
def refresh_env(ctx, type_):
"""Update environments cache"""
environments_file_path = ctx.meta["environments"]
if os.path.exists(environments_file_path):
os.remove(environments_file_path)
dump_environments(environments_file_path)
ctx.invoke(environments.list, type_=type_, output=environments_file_path)
@editor.group(cls=AliasedGroup)
......
......@@ -94,8 +94,29 @@ def test_prefix():
env_file.write(
json.dumps(
{
"Test Env": {"name": "Python 2.7", "version": "1.3.0"},
"Another test Env": {"name": "another test", "version": "1.1.1"},
"remote": [
{
"name": "Python 2.7",
"version": "1.3.0",
"queues": {"queue1": {}, "queue2": {}},
},
{
"name": "Python",
"version": "2.0.0",
"queues": {
"queue_extra_long": {},
"queue_long": {},
"queue_short": {},
},
},
],
"docker": {
"Docker test env": {"name": "Pytorch", "version": "1.1.1"},
"Second Docker test env": {
"name": "Pytorch 1.0",
"version": "2.1.1",
},
},
}
)
)
......
......@@ -27,7 +27,6 @@ import copy
import pytest
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QCheckBox
......@@ -62,6 +61,7 @@ from ..widgets.experimenteditor import typed_user_property
from ..widgets.experimenteditor import ExperimentResources
from ..widgets.experimenteditor import AlgorithmResourceModel
from ..widgets.experimenteditor import QueueResourceModel
from .conftest import prefix
from .conftest import sync_prefix
......@@ -116,6 +116,13 @@ def parameter_choice_map(prefix_path, algorithm_name):
}
def change_index(index):
if index > 0:
return index - 1
else:
return index + 1
# ------------------------------------------------------------------------------
# Fixtures
......@@ -280,6 +287,40 @@ class TestAlgorithmResourceModel:
assert algorithm_model.rowCount() == query.value("cnt")
class TestQueueResourceModel:
"""Test the model used to generate suitable algorithm selections"""
@pytest.fixture
def prefix_model(self, beat_context):
return ExperimentResources(beat_context)
def test_default(self, prefix_model):
model = QueueResourceModel()
query = QSqlQuery()
assert query.exec_("SELECT COUNT(name) AS cnt FROM queues")
query.next()
assert model.rowCount() > 0
assert model.rowCount() == query.value("cnt")
def test_types(self, prefix_model):
model = QueueResourceModel()
for type_ in ["remote", "docker"]:
model.setType(type_)
query = QSqlQuery()
assert query.exec_(
f"SELECT COUNT(name) AS cnt FROM queues WHERE env_type='{type_}'"
)
query.next()
assert model.rowCount() > 0
assert model.rowCount() == query.value("cnt")
class TestIOMapperDialog:
"""Test that the dialog used for input/output mapping works as expected"""
......@@ -506,7 +547,7 @@ class TestEnvironmentModel:
model = EnvironmentModel()
model.setContext(beat_context)
assert model.rowCount() == 2
assert model.rowCount() == 4
def test_visual_name(self, beat_context):
model = EnvironmentModel()
......@@ -728,7 +769,6 @@ class TestExecutionPropertiesEditor(PropertiesEditorTestMixin, ParameterTestMixi
editor = self.editor_klass(test_prefix)
editor.setAlgorithmResourceModel(algorithm_model)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -745,7 +785,6 @@ class TestBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -762,7 +801,6 @@ class TestAnalyzerBlockEditor(PropertiesEditorTestMixin):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -779,7 +817,6 @@ class TestLoopBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
def test_edit_environment(
......@@ -1023,7 +1060,6 @@ class TestGlobalParametersEditor:
environment_model = EnvironmentModel()
environment_model.setContext(beat_context)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test", "Test2"]))
return editor
@pytest.mark.parametrize(
......@@ -1066,13 +1102,15 @@ class TestGlobalParametersEditor:
def test_change_environment(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged):
gpe_editor.environment_combobox.setCurrentIndex(1)
index = gpe_editor.environment_combobox.currentIndex()
gpe_editor.environment_combobox.setCurrentIndex(change_index(index))
assert gpe_editor.dump() != exp_globals
def test_change_queue(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged):
gpe_editor.queue_combobox.setCurrentIndex(1)
index = gpe_editor.queue_combobox.currentIndex()
gpe_editor.queue_combobox.setCurrentIndex(change_index(index))
assert gpe_editor.dump() != exp_globals
......@@ -1190,8 +1228,10 @@ class TestExperimentEditor:
block_editor = list_widget.widget_list[0]
properties_editor = block_editor.properties_editor
combobox = properties_editor.environment_combobox
with qtbot.waitSignal(experiment_editor.dataChanged):
combobox.setCurrentIndex(1)
index = combobox.currentIndex()
combobox.setCurrentIndex(change_index(index))
dump = experiment_editor.dump_json()
assert dump != experiment_declaration
......
This diff is collapsed.
......@@ -93,9 +93,11 @@ class MainWindow(QMainWindow):
self,
self.tr("About"),
self.tr(
f"{qApp.applicationName()}\n"
f"Version: {qApp.applicationVersion()}\n"
"Copyright Idiap Research Institute"
f"{qApp.applicationName()}<br>"
f"Version: {qApp.applicationVersion()}<br>"
"Copyright Idiap Research Institute<br>"
"<a target='_blank' href='https://icons8.com/icons/set/docker'>Docker</a> icon by <a target='_blank' href='https://icons8.com'>Icons8</a>"
"<a target='_blank' href='https://icons8.com/icons/set/cloud-development'>Cloud Development</a> icon by <a target='_blank' href='https://icons8.com'>Icons8</a>"
),
)
......
[buildout]
parts = scripts templates
parts = scripts
eggs = beat.editor
develop = .
newest = false
[scripts]
recipe = bob.buildout:scripts
[templates]
recipe = collective.recipe.cmd
cmds = ./bin/python conda/linkeditor.py
on_install = true
on_update = true
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''Ensures the editor JS code is available during tests'''
import os
import sys
import glob
key = '%%jsfiles%%'
scriptdir = os.path.realpath(os.path.dirname(sys.argv[0]))
try:
import pkg_resources
import beat.editorx
jsfiles = pkg_resources.resource_filename(beat.editor.__name__, 'js')
print('Running test (beat.editor import suceeded) - setting javascript path to %s' % jsfiles)
except ImportError as e:
jsfiles = os.path.realpath(os.path.join(scriptdir, '..', 'beat', 'editor',
'js'))
print('Running build (beat.editor import failed) - setting javascript path to %s' % jsfiles)
if not os.path.exists(jsfiles):
print(' Creating directory %s' % jsfiles)
os.makedirs(jsfiles)
templatedir = os.path.realpath(os.path.join(scriptdir, 'js'))
for k in glob.glob(os.path.join(templatedir, '*.template')):
output = os.path.splitext(k)[0]
print(' ** Replacing template %s -> %s' % (k, output))
with open(k, 'rt') as reader, open(output, 'wt') as writer:
for line in reader:
if key in line: line = line.replace(key, jsfiles)
writer.writelines([line])
......@@ -30,7 +30,7 @@ requirements:
- click
- click-plugins
- docopt
- beat.cmdline >=1.5.0b0
- beat.cmdline >=1.5.1b0
test:
requires:
......
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>resources/remap.png</file>
<qresource prefix="resources">
<file alias="remap">resources/remap.png</file>
<file alias="docker">resources/icons8-docker-50.png</file>
<file alias="remote">resources/icons8-cloud-development-50.png</file>
</qresource>
</RCC>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment