Commit 07eb4877 authored by Flavio TARSETTI's avatar Flavio TARSETTI
Browse files

Merge branch 'algorithm_editor_for_new_loop_user_types' into 'v2'

Implement support for new loop related algorithms

See merge request !105
parents e39ce4a2 57d46376
Pipeline #32251 passed with stage
in 33 minutes and 54 seconds
......@@ -27,6 +27,8 @@ import pytest
from PyQt5 import QtCore
from beat.backend.python.algorithm import Algorithm
from ..backend.asset import Asset
from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel
......@@ -101,14 +103,16 @@ class TestHelperMethods:
@pytest.mark.parametrize(
["algorithm_name", "new_type", "field_to_add"],
[
("autonomous/add/1", "legacy", None),
("autonomous/add/1", "sequential", None),
("sequential/add/1", "autonomous", None),
("sequential/add/1", "loop_user", None),
("sequential/add/1", "loop", None),
("autonomous/loop/1", "sequential", None),
("autonomous/loop/1", "sequential", "results"),
("autonomous/add/1", "sequential", "results"),
("autonomous/add/1", Algorithm.LEGACY, None),
("autonomous/add/1", Algorithm.SEQUENTIAL, None),
("sequential/add/1", Algorithm.AUTONOMOUS, None),
("sequential/add/1", Algorithm.SEQUENTIAL_LOOP_PROCESSOR, None),
("sequential/add/1", Algorithm.SEQUENTIAL_LOOP_EVALUATOR, None),
("sequential/add/1", Algorithm.AUTONOMOUS_LOOP_PROCESSOR, None),
("sequential/add/1", Algorithm.AUTONOMOUS_LOOP_EVALUATOR, None),
("autonomous/loop_evaluator/1", Algorithm.SEQUENTIAL, None),
("autonomous/loop_evaluator/1", Algorithm.SEQUENTIAL, "results"),
("autonomous/add/1", Algorithm.SEQUENTIAL, "results"),
],
)
def test_code_update(self, test_prefix, algorithm_name, new_type, field_to_add):
......@@ -156,7 +160,7 @@ class TestPropertyEditor:
assert editor.dump() == {
"language": "unknown",
"api_version": DEFAULT_API_VERSION,
"type": "sequential",
"type": Algorithm.SEQUENTIAL,
"schema_version": DEFAULT_SCHEMA_VERSION,
"splittable": False,
}
......@@ -170,8 +174,8 @@ class TestPropertyEditor:
# Make the list in an order different than the one they were put in the
# group otherwise, dataChanged won't be emitted
for button in [
editor.sequential_loopuser_radiobutton,
editor.autonomous_loopuser_radiobutton,
editor.sequential_loop_processor_radiobutton,
editor.autonomous_loop_processor_radiobutton,
editor.autonomous_radiobutton,
editor.sequential_radiobutton,
]:
......@@ -179,11 +183,15 @@ class TestPropertyEditor:
button.toggle()
assert editor.canBeSplitable()
with qtbot.waitSignal(editor.dataChanged):
editor.loop_radiobutton.toggle()
for radiobutton in [
editor.sequential_loop_evaluator_radiobutton,
editor.autonomous_loop_evaluator_radiobutton,
]:
with qtbot.waitSignal(editor.dataChanged):
radiobutton.toggle()
assert not editor.canBeSplitable()
assert not editor.splittable_checkbox.isEnabled()
assert not editor.canBeSplitable()
assert not editor.splittable_checkbox.isEnabled()
with qtbot.waitSignal(editor.dataChanged):
editor.analyzer_checkbox.toggle()
......@@ -203,18 +211,22 @@ class TestPropertyEditor:
editor.analyzer_checkbox.toggle()
assert editor.hasOutputs()
with qtbot.waitSignal(editor.dataChanged):
editor.loop_radiobutton.toggle()
assert not editor.hasOutputs()
buttons = editor.button_group.buttons()
buttons.append(buttons.pop(buttons.index(editor.button_group.checkedButton())))
for button in buttons:
with qtbot.waitSignal(editor.dataChanged):
button.toggle()
assert editor.hasOutputs()
@pytest.mark.parametrize(
["algorithm_type", "has_loop"],
[
("sequential", False),
("autonomous", False),
("loop", True),
("autonomous_loop_user", True),
("sequential_loop_user", True),
(Algorithm.SEQUENTIAL, False),
(Algorithm.AUTONOMOUS, False),
(Algorithm.AUTONOMOUS_LOOP_PROCESSOR, True),
(Algorithm.SEQUENTIAL_LOOP_PROCESSOR, True),
(Algorithm.AUTONOMOUS_LOOP_EVALUATOR, True),
(Algorithm.SEQUENTIAL_LOOP_EVALUATOR, True),
],
)
def test_has_loop(self, qtbot, algorithm_type, has_loop):
......@@ -232,11 +244,12 @@ class TestPropertyEditor:
@pytest.mark.parametrize(
["algorithm_type", "schema_version"],
[
("sequential", DEFAULT_SCHEMA_VERSION),
("autonomous", DEFAULT_SCHEMA_VERSION),
("loop", 3),
("sequential_loop_user", 3),
("autonomous_loop_user", 3),
(Algorithm.SEQUENTIAL, DEFAULT_SCHEMA_VERSION),
(Algorithm.AUTONOMOUS, DEFAULT_SCHEMA_VERSION),
(Algorithm.SEQUENTIAL_LOOP_PROCESSOR, 3),
(Algorithm.AUTONOMOUS_LOOP_PROCESSOR, 3),
(Algorithm.SEQUENTIAL_LOOP_EVALUATOR, 3),
(Algorithm.AUTONOMOUS_LOOP_EVALUATOR, 3),
],
)
def test_schema_version(self, qtbot, algorithm_type, schema_version):
......@@ -391,13 +404,12 @@ class TestGroupEditor:
editor = GroupEditor(model)
qtbot.addWidget(editor)
is_loop = reference_json.get("type") in [
"loop",
"autonomous_loop_user",
"sequential_loop_user",
Algorithm.SEQUENTIAL_LOOP_PROCESSOR,
Algorithm.AUTONOMOUS_LOOP_PROCESSOR,
Algorithm.SEQUENTIAL_LOOP_EVALUATOR,
Algorithm.AUTONOMOUS_LOOP_EVALUATOR,
]
has_no_output = (
reference_json.get("type") == "loop" or "results" in reference_json
)
has_no_output = "results" in reference_json
for index, group in enumerate(groups):
editor.load(group)
if not has_no_output:
......
......@@ -34,6 +34,7 @@ from PyQt5.QtWidgets import QButtonGroup
from PyQt5.QtWidgets import QCheckBox
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QGroupBox
from PyQt5.QtWidgets import QHeaderView
from PyQt5.QtWidgets import QHBoxLayout
......@@ -45,6 +46,8 @@ from PyQt5.QtWidgets import QTableWidgetItem
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget
from beat.backend.python.algorithm import Algorithm
from ..backend.asset import AssetType
from ..backend.asset import Asset
from ..backend.assetmodel import AssetModel
......@@ -64,10 +67,13 @@ DEFAULT_SCHEMA_VERSION = 2
DEFAULT_API_VERSION = 2
ALGORITHM_PROCESS_METHOD_MAP = {
"legacy": "def process(self, inputs, outputs):",
"sequential": "def process(self, inputs, data_loaders, outputs):",
"autonomous": "def process(self, data_loaders, outputs):",
"loop_user": "def process(self, data_loaders, channel):",
Algorithm.LEGACY: "def process(self, inputs, outputs):",
Algorithm.SEQUENTIAL: "def process(self, inputs, data_loaders, outputs):",
Algorithm.AUTONOMOUS: "def process(self, data_loaders, outputs):",
Algorithm.SEQUENTIAL_LOOP_PROCESSOR: "def process(self, inputs, data_loaders, outputs, channel):",
Algorithm.AUTONOMOUS_LOOP_PROCESSOR: "def process(self, data_loaders, outputs, channel):",
Algorithm.SEQUENTIAL_LOOP_EVALUATOR: "def process(self, inputs, data_loaders, outputs, channel):",
Algorithm.AUTONOMOUS_LOOP_EVALUATOR: "def process(self, data_loaders, outputs, channel):",
}
ANALYZER_PROCESS_METHOD_MAP = {
......@@ -155,39 +161,57 @@ class PropertyEditor(QWidget):
self.analyzer_checkbox = QCheckBox()
self.splittable_checkbox = QCheckBox(self.tr("Splittable"))
self.sequential_radiobutton = QRadioButton(self.tr("Sequential"))
self.sequential_radiobutton.setProperty(ALGORITHM_TYPE, "sequential")
self.sequential_radiobutton.setProperty(ALGORITHM_TYPE, Algorithm.SEQUENTIAL)
self.autonomous_radiobutton = QRadioButton(self.tr("Autonomous"))
self.autonomous_radiobutton.setProperty(ALGORITHM_TYPE, "autonomous")
self.sequential_loopuser_radiobutton = QRadioButton(
self.tr("Sequential loop user")
self.autonomous_radiobutton.setProperty(ALGORITHM_TYPE, Algorithm.AUTONOMOUS)
self.sequential_loop_processor_radiobutton = QRadioButton(
self.tr("Sequential loop processor")
)
self.sequential_loopuser_radiobutton.setProperty(
ALGORITHM_TYPE, "sequential_loop_user"
self.sequential_loop_processor_radiobutton.setProperty(
ALGORITHM_TYPE, Algorithm.SEQUENTIAL_LOOP_PROCESSOR
)
self.autonomous_loopuser_radiobutton = QRadioButton(
self.tr("Autonomous loop user")
self.autonomous_loop_processor_radiobutton = QRadioButton(
self.tr("Autonomous loop processor")
)
self.autonomous_loopuser_radiobutton.setProperty(
ALGORITHM_TYPE, "autonomous_loop_user"
self.autonomous_loop_processor_radiobutton.setProperty(
ALGORITHM_TYPE, Algorithm.AUTONOMOUS_LOOP_PROCESSOR
)
self.sequential_loop_evaluator_radiobutton = QRadioButton(
self.tr("Sequential loop evaluator")
)
self.sequential_loop_evaluator_radiobutton.setProperty(
ALGORITHM_TYPE, Algorithm.SEQUENTIAL_LOOP_EVALUATOR
)
self.autonomous_loop_evaluator_radiobutton = QRadioButton(
self.tr("Autonomous loop evaluator")
)
self.autonomous_loop_evaluator_radiobutton.setProperty(
ALGORITHM_TYPE, Algorithm.AUTONOMOUS_LOOP_EVALUATOR
)
self.loop_radiobutton = QRadioButton(self.tr("Loop"))
self.loop_radiobutton.setProperty(ALGORITHM_TYPE, "loop")
self.button_group = QButtonGroup()
button_layout = QHBoxLayout()
button_layout = QGridLayout()
row = 0
col = 0
for button in [
self.sequential_radiobutton,
self.autonomous_radiobutton,
self.sequential_loopuser_radiobutton,
self.autonomous_loopuser_radiobutton,
self.loop_radiobutton,
self.sequential_loop_processor_radiobutton,
self.autonomous_loop_processor_radiobutton,
self.sequential_loop_evaluator_radiobutton,
self.autonomous_loop_evaluator_radiobutton,
]:
self.button_group.addButton(button)
button_layout.addWidget(button)
button_layout.addWidget(button, row, col)
col += 1
if col == 2:
row += 1
col = 0
self.sequential_radiobutton.setChecked(True)
button_layout.addStretch(1)
# button_layout.addStretch(1)
layout = QFormLayout(self)
layout.addRow(self.tr("Analyzer:"), self.analyzer_checkbox)
......@@ -196,9 +220,10 @@ class PropertyEditor(QWidget):
for widget in [
self.splittable_checkbox,
self.sequential_loopuser_radiobutton,
self.autonomous_loopuser_radiobutton,
self.loop_radiobutton,
self.sequential_loop_processor_radiobutton,
self.autonomous_loop_processor_radiobutton,
self.sequential_loop_evaluator_radiobutton,
self.autonomous_loop_evaluator_radiobutton,
]:
self.analyzer_checkbox.toggled.connect(
# target is declared so because otherwise it wouldn't be local
......@@ -219,7 +244,12 @@ class PropertyEditor(QWidget):
]:
widget.toggled.connect(self.dataChanged)
self.loop_radiobutton.toggled.connect(self.splittable_checkbox.setDisabled)
self.sequential_loop_evaluator_radiobutton.toggled.connect(
self.splittable_checkbox.setDisabled
)
self.autonomous_loop_evaluator_radiobutton.toggled.connect(
self.splittable_checkbox.setDisabled
)
@pyqtSlot(bool)
def __onAnalyzerToggled(self, checked):
......@@ -234,16 +264,14 @@ class PropertyEditor(QWidget):
return self.analyzer_checkbox.isChecked()
def hasOutputs(self):
return (
not self.analyzer_checkbox.isChecked()
and not self.loop_radiobutton.isChecked()
)
return not self.analyzer_checkbox.isChecked()
def hasLoop(self):
return self.button_group.checkedButton() in [
self.loop_radiobutton,
self.sequential_loopuser_radiobutton,
self.autonomous_loopuser_radiobutton,
self.sequential_loop_processor_radiobutton,
self.autonomous_loop_processor_radiobutton,
self.sequential_loop_evaluator_radiobutton,
self.autonomous_loop_evaluator_radiobutton,
]
def canBeSplitable(self):
......@@ -273,9 +301,10 @@ class PropertyEditor(QWidget):
schema_version = self.schema_version
if self.button_group.checkedButton() in [
self.loop_radiobutton,
self.sequential_loopuser_radiobutton,
self.autonomous_loopuser_radiobutton,
self.sequential_loop_processor_radiobutton,
self.autonomous_loop_processor_radiobutton,
self.sequential_loop_evaluator_radiobutton,
self.autonomous_loop_evaluator_radiobutton,
]:
schema_version = 3
......
Supports Markdown
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