Commit 57d46376 authored by Samuel GAIST's avatar Samuel GAIST Committed by Samuel GAIST
Browse files

[widgets][algorithmeditor] Implement support for new loop related algorithms

The loop related algorithms are now:

- loop processor
- loop evaluator

Both being sequential or autonomous.
parent e39ce4a2
Pipeline #32235 passed with stage
in 12 minutes and 23 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