From 568100d8698a74f5bd9c00af0f642c430232ac04 Mon Sep 17 00:00:00 2001 From: fengzero Date: Tue, 10 Oct 2023 08:18:49 +0000 Subject: [PATCH 1/7] ft: modbus tcp --- tests/ft/modbus/__init__.py | 3 +++ tests/ft/modbus/test_modbus_tcp.py | 20 ++++++++++++++++++++ tests/ft/neuron/common.py | 6 +++++- tests/ft/neuron/process.py | 6 ------ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 tests/ft/modbus/__init__.py create mode 100644 tests/ft/modbus/test_modbus_tcp.py diff --git a/tests/ft/modbus/__init__.py b/tests/ft/modbus/__init__.py new file mode 100644 index 00000000..6da12771 --- /dev/null +++ b/tests/ft/modbus/__init__.py @@ -0,0 +1,3 @@ +import sys + +sys.path.append("tests/ft") diff --git a/tests/ft/modbus/test_modbus_tcp.py b/tests/ft/modbus/test_modbus_tcp.py new file mode 100644 index 00000000..7b58fb1e --- /dev/null +++ b/tests/ft/modbus/test_modbus_tcp.py @@ -0,0 +1,20 @@ +import neuron.api as api +from neuron.common import * + + +@pytest.fixture(autouse=True, scope='class') +def simulator_setup_teardown(): + port = random_port() + p = process.start_simulator( + ['./modbus_simulator', 'tcp', f'{port}', 'ip_v4']) + + yield + process.stop_simulator(p) + + +class TestModbusTCP: + + @description(given="name and password", when="login", then="login success with token") + def test_login_success(self): + response = api.login() + assert 200 == response.status_code diff --git a/tests/ft/neuron/common.py b/tests/ft/neuron/common.py index b369b46a..f4d1654b 100644 --- a/tests/ft/neuron/common.py +++ b/tests/ft/neuron/common.py @@ -1,6 +1,6 @@ import time -import sys from functools import wraps +import random import pytest @@ -25,6 +25,10 @@ class description(object): return wrapper +def random_port(): + return random.randint(30000, 65535) + + @pytest.fixture(autouse=True, scope='class') def class_setup_and_teardown(): process.remove_persistence() diff --git a/tests/ft/neuron/process.py b/tests/ft/neuron/process.py index 82e4dc76..9288a20f 100644 --- a/tests/ft/neuron/process.py +++ b/tests/ft/neuron/process.py @@ -1,8 +1,6 @@ import os import time -import pytest import subprocess -import random def remove_persistence(dir='build/'): @@ -34,7 +32,3 @@ def start_simulator(args, dir='build/simulator'): def stop_simulator(process): process.terminate() - - -def random_port(): - return random.randint(30000, 65535) From fb924091dd81ecb3ed6a959da1d6c8041ffe68e6 Mon Sep 17 00:00:00 2001 From: fengzero Date: Wed, 11 Oct 2023 07:06:32 +0000 Subject: [PATCH 2/7] driver test --- tests/ft/driver/test_driver.py | 123 +++++++++++++++++++++++++++++++++ tests/ft/driver/test_modbus.py | 40 +++++++++++ tests/ft/log/test_log.py | 30 ++++---- tests/ft/neuron/api.py | 42 ++++++++++- tests/ft/neuron/config.py | 66 +++++++++++++++++- 5 files changed, 283 insertions(+), 18 deletions(-) create mode 100644 tests/ft/driver/test_driver.py create mode 100644 tests/ft/driver/test_modbus.py diff --git a/tests/ft/driver/test_driver.py b/tests/ft/driver/test_driver.py new file mode 100644 index 00000000..b28bed60 --- /dev/null +++ b/tests/ft/driver/test_driver.py @@ -0,0 +1,123 @@ +import neuron.api as api +import neuron.error as error +import neuron.config as config +from neuron.common import * + + +class TestDriver: + + @description(given="running neuron", when="add driver node", then="add success") + @pytest.mark.parametrize('node,plugin', [('modbus-tcp-1', config.PLUGIN_MODBUS_TCP), + ('modbus-rtu-1', config.PLUGIN_MODBUS_RTU)]) + def test_create_node(self, node, plugin): + response = api.add_node(node=node, + plugin=plugin) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + @description(given="created node", when="get node state", then="state is init") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_node_init(self, node): + response = api.get_nodes_state(node=node) + assert 200 == response.status_code + assert config.NEU_NODE_STATE_INIT == response.json()['running'] + + @description(given="created node", when="stop node", then="stop failed") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_init_node_stop(self, node): + response = api.node_ctl(node=node, ctl=config.NEU_CTL_STOP) + assert 409 == response.status_code + + @description(given="modbus tcp node", when="setting modbus tcp node", then="setting success") + def test_modbus_tcp_setting(self): + response = api.modbus_tcp_node_setting(node='modbus-tcp-1', port=502) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + @description(given="modbus rtu node", when="setting modbus rtu node", then="setting success") + def test_modbus_rtu_setting(self): + response = api.modbus_rtu_node_setting(node='modbus-rtu-1', port=502) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + def test_wait_state(self): + time.sleep(4) + + @description(given="configured node", when="get node state", then="state is running") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_node_ready(self, node): + response = api.get_nodes_state(node=node) + assert 200 == response.status_code + assert config.NEU_NODE_STATE_RUNNING == response.json()['running'] + + @description(given="running modbus tcp node", when="setting modbus tcp node", then="state not change") + def test_running_modbus_tcp_setting(self): + response = api.modbus_tcp_node_setting(node='modbus-tcp-1', port=502) + assert 200 == response.status_code + + response = api.get_nodes_state(node='modbus-tcp-1') + assert 200 == response.status_code + assert config.NEU_NODE_STATE_RUNNING == response.json()['running'] + + @description(given="running modbus rtu node", when="setting modbus rtu node", then="state not change") + def test_running_modbus_rtu_setting(self): + response = api.modbus_rtu_node_setting(node='modbus-rtu-1', port=502) + assert 200 == response.status_code + + response = api.get_nodes_state(node='modbus-tcp-1') + assert 200 == response.status_code + assert config.NEU_NODE_STATE_RUNNING == response.json()['running'] + + @description(given="running node", when="stop node", then="state is stopped") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_node_stop(self, node): + response = api.node_ctl(node=node, ctl=config.NEU_CTL_STOP) + assert 200 == response.status_code + response = api.get_nodes_state(node=node) + assert 200 == response.status_code + assert config.NEU_NODE_STATE_STOPPED == response.json()['running'] + + @description(given="stopped modbus tcp node", when="setting modbus tcp node", then="state not change") + def test_stopped_modbus_tcp_setting(self): + response = api.modbus_tcp_node_setting(node='modbus-tcp-1', port=502) + assert 200 == response.status_code + + response = api.get_nodes_state(node='modbus-tcp-1') + assert 200 == response.status_code + assert config.NEU_NODE_STATE_STOPPED == response.json()['running'] + + @description(given="stopped modbus rtu node", when="setting modbus rtu node", then="state not change") + def test_stopped_modbus_rtu_setting(self): + response = api.modbus_rtu_node_setting(node='modbus-rtu-1', port=502) + assert 200 == response.status_code + + response = api.get_nodes_state(node='modbus-tcp-1') + assert 200 == response.status_code + assert config.NEU_NODE_STATE_STOPPED == response.json()['running'] + + @description(given="stopped node", when="stop node", then="stop failed") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_stop_node_stop(self, node): + response = api.node_ctl(node=node, ctl=config.NEU_CTL_STOP) + assert 409 == response.status_code + + @description(given="stopped node", when="start node", then="state is running") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_node_start(self, node): + response = api.node_ctl(node=node, ctl=config.NEU_CTL_START) + assert 200 == response.status_code + response = api.get_nodes_state(node=node) + assert 200 == response.status_code + assert config.NEU_NODE_STATE_RUNNING == response.json()['running'] + + @description(given="running node", when="start node", then="start failed") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_start_node_start(self, node): + response = api.node_ctl(node=node, ctl=config.NEU_CTL_START) + assert 409 == response.status_code + + @description(given="create node", when="del node", then="del success") + @pytest.mark.parametrize('node', ['modbus-tcp-1', 'modbus-rtu-1']) + def test_del_node(self, node): + response = api.del_node(node=node) + assert 200 == response.status_code diff --git a/tests/ft/driver/test_modbus.py b/tests/ft/driver/test_modbus.py new file mode 100644 index 00000000..8d91c91a --- /dev/null +++ b/tests/ft/driver/test_modbus.py @@ -0,0 +1,40 @@ +import neuron.api as api +import neuron.error as error +import neuron.config as config +from neuron.common import * + + +@pytest.fixture(params=[('modbus-tcp', config.PLUGIN_MODBUS_TCP), + ('modbus-rtu', config.PLUGIN_MODBUS_RTU)], scope='class') +def param(request): + return request.param + + +@pytest.fixture(autouse=True, scope='class') +def simulator_setup_teardown(param): + port = random_port() + if param[1] == config.PLUGIN_MODBUS_TCP: + p = process.start_simulator( + ['./modbus_simulator', 'tcp', f'{port}', 'ip_v4']) + else: + p = process.start_simulator( + ['./modbus_simulator', 'rtu', f'{port}', 'ip_v4']) + + response = api.add_node(node=param[0], plugin=param[1]) + assert 200 == response.status_code + + if param[1] == config.PLUGIN_MODBUS_TCP: + response = api.modbus_tcp_node_setting( + node=param[0], port=port) + else: + response = api.modbus_rtu_node_setting( + node=param[0], port=port) + + yield + process.stop_simulator(p) + + +class TestModbus: + + def test_read(self): + print("x") diff --git a/tests/ft/log/test_log.py b/tests/ft/log/test_log.py index 185f2c99..7898bfae 100644 --- a/tests/ft/log/test_log.py +++ b/tests/ft/log/test_log.py @@ -10,7 +10,7 @@ class TestLog: @description(given="node", when="change log_level to debug", then="change success") def test_change_log_level_debug(self): - response = api.add_node(node='modbus-tcp-1', plugin=modbus_tcp) + response = api.add_node(node='modbus-tcp-1', plugin=PLUGIN_MODBUS_TCP) assert 200 == response.status_code assert 0 == response.json()['error'] @@ -18,54 +18,54 @@ class TestLog: assert 200 == response.status_code assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "debug" == response.json()['states'][0]['log_level'] + assert "debug" == response.json()['log_level'] @description(given="node", when="change log_level to info", then="change success") def test_change_log_level_info(self): response = api.change_log_level(node='modbus-tcp-1', level='info') assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "info" == response.json()['states'][0]['log_level'] + assert "info" == response.json()['log_level'] @description(given="node", when="change log_level to warn", then="change success") def test_change_log_level_warn(self): response = api.change_log_level(node='modbus-tcp-1', level='warn') assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "warn" == response.json()['states'][0]['log_level'] + assert "warn" == response.json()['log_level'] @description(given="node", when="change log_level to error", then="change success") def test_change_log_level_error(self): response = api.change_log_level(node='modbus-tcp-1', level='error') assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "error" == response.json()['states'][0]['log_level'] + assert "error" == response.json()['log_level'] @description(given="node", when="change log_level to fatal", then="change success") def test_change_log_level_fatal(self): response = api.change_log_level(node='modbus-tcp-1', level='fatal') assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "fatal" == response.json()['states'][0]['log_level'] + assert "fatal" == response.json()['log_level'] @description(given="node", when="change log_level to notice", then="change success") def test_change_log_level_notice(self): response = api.change_log_level(node='modbus-tcp-1', level='notice') assert 0 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "notice" == response.json()['states'][0]['log_level'] + assert "notice" == response.json()['log_level'] @description(given="node", when="change log_level to invalid level", then="change failed") def test_change_log_level_invalid(self): @@ -73,6 +73,6 @@ class TestLog: assert 400 == response.status_code assert 1003 == response.json()['error'] - response = api.get_nodes_state() + response = api.get_nodes_state('modbus-tcp-1') assert 200 == response.status_code - assert "notice" == response.json()['states'][0]['log_level'] \ No newline at end of file + assert "notice" == response.json()['log_level'] diff --git a/tests/ft/neuron/api.py b/tests/ft/neuron/api.py index fd293524..615f9dcf 100644 --- a/tests/ft/neuron/api.py +++ b/tests/ft/neuron/api.py @@ -17,11 +17,49 @@ def get_license(jwt=config.default_jwt): def upload_license(license, jwt=config.default_jwt): return requests.post(url=config.BASE_URL + '/api/v2/license', headers={"Authorization": jwt}, json={"license": license}) + def change_log_level(node, level, jwt=config.default_jwt): return requests.put(url=config.BASE_URL + '/api/v2/log/level', headers={"Authorization": jwt}, json={"node": node, "level": level}) + def add_node(node, plugin, jwt=config.default_jwt): return requests.post(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, json={"name": node, "plugin": plugin}) -def get_nodes_state(jwt=config.default_jwt): - return requests.get(url=config.BASE_URL + '/api/v2/node/state', headers={"Authorization": jwt}) + +def del_node(node, jwt=config.default_jwt): + return requests.delete(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, json={"name": node}) + + +def get_nodes(type, jwt=config.default_jwt): + return requests.get(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, params={"type": type}) + + +def node_ctl(node, ctl, jwt=config.default_jwt): + return requests.post(url=config.BASE_URL + '/api/v2/node/ctl', headers={"Authorization": jwt}, json={"node": node, "cmd": ctl}) + + +def get_nodes_state(node, jwt=config.default_jwt): + return requests.get(url=config.BASE_URL + '/api/v2/node/state', headers={"Authorization": jwt}, params={"node": node}) + + +def node_setting(node, json, jwt=config.default_jwt): + return requests.post(url=config.BASE_URL + '/api/v2/node/setting', headers={"Authorization": jwt}, json={"node": node, "params": json}) + + +def get_node_setting(node, jwt=config.default_jwt): + return requests.get(url=config.BASE_URL + '/api/v2/node/setting', headers={"Authorization": jwt}, params={"node": node}) + + +# plugin setting + + +def modbus_tcp_node_setting(node, port, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000): + return node_setting(node, json={"connection_mode": connection_mode, "transport_mode": transport_mode, "interval": interval, + "host": host, "port": port, "timeout": timeout}) + + +def modbus_rtu_node_setting(node, port, connection_mode=0, transport_mode=0, interval=10, host='127.0.0.1', timeout=3000, link=1, device="", stop=0, parity=0, baud=4, data=3): + return node_setting(node, json={"connection_mode": connection_mode, "transport_mode": transport_mode, + "interval": interval, "host": host, "port": port, "timeout": timeout, + "link": link, "device": device, "stop": stop, "parity": parity, + "baud": baud, "data": data}) diff --git a/tests/ft/neuron/config.py b/tests/ft/neuron/config.py index 78e172ca..9a59c33d 100644 --- a/tests/ft/neuron/config.py +++ b/tests/ft/neuron/config.py @@ -1,3 +1,67 @@ BASE_URL = "http://127.0.0.1:7000" default_jwt = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJuZXVyb24iLCJib2R5RW5jb2RlIjowLCJleHAiOjE3MTc4MzUyNjIsImlhdCI6MTY4NjI5OTI2MiwiaXNzIjoibmV1cm9uIn0.tJ8Z12S5lzzyqvJedFr11w0FmQ8l9inFHuzcuA_3uKoNBJSZlQAkcWyDAO2XELyuZFtHPrk8pJFgEqTzwphtBAybVXbeHBRWED5XuHvYqznzwk1J2UCOuw_ehmHnLszZHRAcMoeLWIRIx0KM7BXvZAyFA2J1axJntxfRrurNMn6MbfnGGtza6hJfuQ6pG-h4cHhrBOogf8nw3f8RLfd16vbWobhEp8KBUrwsfn2Iv4hMXvZMekv_PXboLO74f7oMkEL6pdM9g6G6rDBTjTU8FssfeyJcAP7Xb9mS2G7GNW5B8twtPVLtpOQH9VNbLa4OQxdMb0WN86i9vSDiCOoN6A" -modbus_tcp = "Modbus TCP" \ No newline at end of file + +NEU_NODE_DRIVER = 1 +NEU_NODE_APP = 2 + +NEU_CTL_START = 0 +NEU_CTL_STOP = 1 + +NEU_NODE_STATE_INIT = 1 +NEU_NODE_STATE_READY = 2 +NEU_NODE_STATE_RUNNING = 3 +NEU_NODE_STATE_STOPPED = 4 + +NEU_NODE_LINK_STATE_DISCONNECTED = 0 +NEU_NODE_LINK_STATE_CONNECTED = 1 + +NEU_TAG_ATTRIBUTE_READ = 1 +NEU_TAG_ATTRIBUTE_WRITE = 2 +NEU_TAG_ATTRIBUTE_SUBSCRIBE = 4 + +NEU_TYPE_INT8 = 1 +NEU_TYPE_UINT8 = 2 +NEU_TYPE_INT16 = 3 +NEU_TYPE_UINT16 = 4 +NEU_TYPE_INT32 = 5 +NEU_TYPE_UINT32 = 6 +NEU_TYPE_INT64 = 7 +NEU_TYPE_UINT64 = 8 +NEU_TYPE_FLOAT = 9 +NEU_TYPE_DOUBLE = 10 +NEU_TYPE_BIT = 11 +NEU_TYPE_BOOL = 12 +NEU_TYPE_STRING = 13 +NEU_TYPE_BYTES = 14 +NEU_TYPE_ERROR = 15 +NEU_TYPE_WORD = 16 +NEU_TYPE_DWORD = 17 +NEU_TYPE_LWORD = 18 + +NEU_BAUD_115200 = 0 +NEU_BAUD_57600 = 1 +NEU_BAUD_38400 = 2 +NEU_BAUD_19200 = 3 +NEU_BAUD_9600 = 4 +NEU_BAUD_4800 = 5 +NEU_BAUD_2400 = 6 +NEU_BAUD_1800 = 7 +NEU_BAUD_1200 = 8 +NEU_BAUD_600 = 9 + +NEU_PARITY_NONE = 0 +NEU_PARITY_ODD = 1 +NEU_PARITY_EVEN = 2 +NEU_PARITY_MARK = 3 +NEU_PARITY_SPACE = 4 + +NEU_STOP_1 = 0 +NEU_STOP_2 = 1 + +NEU_DATA_5 = 0 +NEU_DATA_6 = 1 +NEU_DATA_7 = 2 +NEU_DATA_8 = 3 + +PLUGIN_MODBUS_TCP = "Modbus TCP" +PLUGIN_MODBUS_RTU = "Modbus RTU" From 96a4158e784f36da20f7c8c7976f8e0b6f518fc3 Mon Sep 17 00:00:00 2001 From: fengzero Date: Wed, 11 Oct 2023 07:13:46 +0000 Subject: [PATCH 3/7] version: 2.7.0-dev --- .github/workflows/ci.yml | 4 ++-- version | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85b7914a..c15639e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,8 +8,8 @@ on: - published env: - VERSION: 2.6.0 - UI_VERSION: 2.6.0 + VERSION: 2.7.0 + UI_VERSION: 2.7.0 BRANCH: main jobs: diff --git a/version b/version index 4c41a25b..a9d23659 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.6.0-dev \ No newline at end of file +2.7.0-dev \ No newline at end of file From da05941676523696fa04a13b573e7f8ae356e3ab Mon Sep 17 00:00:00 2001 From: fengzero Date: Thu, 12 Oct 2023 02:41:33 +0000 Subject: [PATCH 4/7] modbus ft --- simulator/modbus_s.c | 5 +- tests/ft/driver/test_modbus.py | 443 ++++++++++++++++++++++++++++++++- tests/ft/neuron/api.py | 88 +++++++ tests/ft/neuron/common.py | 4 + tests/ft/neuron/config.py | 3 + tests/ft/setup.py | 2 +- 6 files changed, 535 insertions(+), 10 deletions(-) diff --git a/simulator/modbus_s.c b/simulator/modbus_s.c index d6fb9c15..38e1657b 100644 --- a/simulator/modbus_s.c +++ b/simulator/modbus_s.c @@ -215,13 +215,14 @@ ssize_t modbus_s_tcp_req(uint8_t *req, uint16_t req_len, uint8_t *res, break; case MODBUS_WRITE_S_COIL: case MODBUS_WRITE_M_COIL: - case MODBUS_WRITE_S_HOLD_REG: + case MODBUS_WRITE_S_HOLD_REG: case MODBUS_WRITE_M_HOLD_REG: nlog_info( "write register: slave: %d, function: %d, address: %d, n: %d, " "nbyte: %d\n", code->slave_id, code->function, ntohs(address->start_address), - code->function != MODBUS_WRITE_S_HOLD_REG ? ntohs(address->n_reg) : 1, + code->function != MODBUS_WRITE_S_HOLD_REG ? ntohs(address->n_reg) + : 1, code->function != MODBUS_WRITE_S_HOLD_REG ? data->n_byte : 2); modbus_write(&tcp_registers[code->slave_id - 1], code->function, address, data, value); diff --git a/tests/ft/driver/test_modbus.py b/tests/ft/driver/test_modbus.py index 8d91c91a..f20c3070 100644 --- a/tests/ft/driver/test_modbus.py +++ b/tests/ft/driver/test_modbus.py @@ -3,6 +3,9 @@ import neuron.error as error import neuron.config as config from neuron.common import * +tcp_port = random_port() +rtu_port = random_port() + @pytest.fixture(params=[('modbus-tcp', config.PLUGIN_MODBUS_TCP), ('modbus-rtu', config.PLUGIN_MODBUS_RTU)], scope='class') @@ -12,29 +15,455 @@ def param(request): @pytest.fixture(autouse=True, scope='class') def simulator_setup_teardown(param): - port = random_port() if param[1] == config.PLUGIN_MODBUS_TCP: p = process.start_simulator( - ['./modbus_simulator', 'tcp', f'{port}', 'ip_v4']) + ['./modbus_simulator', 'tcp', f'{tcp_port}', 'ip_v4']) else: p = process.start_simulator( - ['./modbus_simulator', 'rtu', f'{port}', 'ip_v4']) + ['./modbus_simulator', 'rtu', f'{rtu_port}', 'ip_v4']) response = api.add_node(node=param[0], plugin=param[1]) assert 200 == response.status_code + response = api.add_group(node=param[0], group='group') + assert 200 == response.status_code + if param[1] == config.PLUGIN_MODBUS_TCP: response = api.modbus_tcp_node_setting( - node=param[0], port=port) + node=param[0], port=tcp_port) else: response = api.modbus_rtu_node_setting( - node=param[0], port=port) + node=param[0], port=rtu_port) yield process.stop_simulator(p) +hold_bit = [{"name": "hold_bit", "address": "1!400001.15", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +hold_int16 = [{"name": "hold_int16", "address": "1!400001", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] +hold_uint16 = [{"name": "hold_uint16", "address": "1!400002", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] +hold_int32 = [{"name": "hold_int32", "address": "1!400003", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] +hold_uint32 = [{"name": "hold_uint32", "address": "1!400015", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] +hold_float = [{"name": "hold_float", "address": "1!400017", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] +hold_string = [{"name": "hold_string", "address": "1!400020.10", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] +hold_bytes = [{"name": "hold_bytes", "address": "1!400040.10", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BYTES}] + +coil_bit_1 = [{"name": "coil_bit_1", "address": "1!000001", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] +coil_bit_2 = [{"name": "coil_bit_2", "address": "1!000002", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] +coil_bit_3 = [{"name": "coil_bit_3", "address": "1!000003", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] +coil_bit_4 = [{"name": "coil_bit_4", "address": "1!000005", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] +coil_bit_5 = [{"name": "coil_bit_5", "address": "1!000010", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + +input_bit_1 = [{"name": "input_bit_1", "address": "1!100001", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +input_bit_2 = [{"name": "input_bit_2", "address": "1!100002", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +input_bit_3 = [{"name": "input_bit_3", "address": "1!100003", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +input_bit_4 = [{"name": "input_bit_4", "address": "1!100005", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +input_bit_5 = [{"name": "input_bit_5", "address": "1!100010", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] + +input_register_bit = [{"name": "input_register_bit", "address": "1!30101.15", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT}] +input_register_int16 = [{"name": "input_register_int16", "address": "1!30101", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_INT16}] +input_register_uint16 = [{"name": "input_register_uint16", "address": "1!30102", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_UINT16}] +input_register_int32 = [{"name": "input_register_int32", "address": "1!30103", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_INT32}] +input_register_uint32 = [{"name": "input_register_uint32", "address": "1!30115", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_UINT32}] +input_register_float = [{"name": "input_register_float", "address": "1!30117", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_FLOAT}] +input_register_string = [{"name": "input_register_string", "address": "1!30120.10", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_STRING}] +input_register_bytes = [{"name": "input_register_bytes", "address": "1!30130.10", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BYTES}] + +hold_int16_s = [{"name": "hold_int16_s", "address": "1!400001", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_INT16, "value": 1}] +hold_uint16_s = [{"name": "hold_uint16_s", "address": "1!400002", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_UINT16, "value": 1}] +hold_int32_s = [{"name": "hold_int32_s", "address": "1!400003", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_INT32, "value": 1}] +hold_uint32_s = [{"name": "hold_uint32_s", "address": "1!400015", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_UINT32, "value": 1}] +hold_float_s = [{"name": "hold_float_s", "address": "1!400017", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_FLOAT, "value": 1.0}] +hold_string_s = [{"name": "hold_string_s", "address": "1!400020.10", + "attribute": config.NEU_TAG_ATTRIBUTE_RW_STATIC, "type": config.NEU_TYPE_STRING, "value": "a"}] + +hold_int16_decimal = [{"name": "hold_int16_decimal", "address": "1!40103", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": 0.1}] +hold_uint16_decimal = [{"name": "hold_uint16_decimal", "address": "1!400105", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16, "decimal": 0.2}] +hold_int32_decimal = [{"name": "hold_int32_decimal", "address": "1!400199", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32, "decimal": 0.3}] +hold_uint32_decimal = [{"name": "hold_uint32_decimal", "address": "1!400115", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32, "decimal": 0.3}] +hold_float_decimal = [{"name": "hold_float_decimal", "address": "1!400119", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT, "decimal": 0.5}] +hold_double_decimal = [{"name": "hold_double_decimal", "address": "1!4000127", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_DOUBLE, "decimal": 0.6}] + +hold_float_precision = [{"name": "hold_float_precision", "address": "1!4000235", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT, "precision": 3}] +hold_double_precision = [{"name": "hold_double_precision", "address": "1!4000240", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_DOUBLE, "precision": 3}] + + class TestModbus: - def test_read(self): - print("x") + @description(given="created modbus node", when="add multiple tags", then="add success") + def test_add_tags(self, param): + api.add_tags_check(node=param[0], group='group', tags=hold_bit) + api.add_tags_check(node=param[0], group='group', tags=hold_int16) + api.add_tags_check(node=param[0], group='group', tags=hold_uint16) + api.add_tags_check(node=param[0], group='group', tags=hold_int32) + api.add_tags_check(node=param[0], group='group', tags=hold_uint32) + api.add_tags_check(node=param[0], group='group', tags=hold_float) + api.add_tags_check(node=param[0], group='group', tags=hold_string) + api.add_tags_check(node=param[0], group='group', tags=hold_bytes) + + api.add_tags_check( + node=param[0], group='group', tags=input_register_bit) + api.add_tags_check( + node=param[0], group='group', tags=input_register_int16) + api.add_tags_check( + node=param[0], group='group', tags=input_register_uint16) + api.add_tags_check( + node=param[0], group='group', tags=input_register_int32) + api.add_tags_check( + node=param[0], group='group', tags=input_register_uint32) + api.add_tags_check( + node=param[0], group='group', tags=input_register_float) + api.add_tags_check( + node=param[0], group='group', tags=input_register_string) + api.add_tags_check( + node=param[0], group='group', tags=input_register_bytes) + + api.add_tags_check(node=param[0], group='group', tags=coil_bit_1) + api.add_tags_check(node=param[0], group='group', tags=coil_bit_2) + api.add_tags_check(node=param[0], group='group', tags=coil_bit_3) + api.add_tags_check(node=param[0], group='group', tags=coil_bit_4) + api.add_tags_check(node=param[0], group='group', tags=coil_bit_5) + + api.add_tags_check(node=param[0], group='group', tags=input_bit_1) + api.add_tags_check(node=param[0], group='group', tags=input_bit_2) + api.add_tags_check(node=param[0], group='group', tags=input_bit_3) + api.add_tags_check(node=param[0], group='group', tags=input_bit_4) + api.add_tags_check(node=param[0], group='group', tags=input_bit_5) + + @description(given="created modbus node", when="add static tags", then="add success") + def test_add_static_tags(self, param): + api.add_tags_check(node=param[0], group='group', tags=hold_int16_s) + api.add_tags_check(node=param[0], group='group', tags=hold_uint16_s) + api.add_tags_check(node=param[0], group='group', tags=hold_int32_s) + api.add_tags_check(node=param[0], group='group', tags=hold_uint32_s) + api.add_tags_check(node=param[0], group='group', tags=hold_float_s) + api.add_tags_check(node=param[0], group='group', tags=hold_string_s) + + @description(given="created modbus node", when="add wrong tags", then="add failed") + def test_add_wrong_tags(self, param): + wrong_tag1 = [{"name": "winput_bit_1", "address": "1!100001", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + wrong_tag2 = [{"name": "winput_bit_1", "address": "1!100001", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_INT16}] + wrong_tag3 = [{"name": "whold_bytes_1", "address": "1!400001.9", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BYTES}] + wrong_tag4 = [{"name": "whold_string_1", "address": "1!400001.130", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + wrong_tag5 = [{"name": "whold_bytes_2", "address": "1!400001.130", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BYTES}] + + response = api.add_tags(node=param[0], group='group', tags=wrong_tag1) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT == response.json()[ + 'error'] + + response = api.add_tags(node=param[0], group='group', tags=wrong_tag2) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_TYPE_NOT_SUPPORT == response.json()[ + 'error'] + + response = api.add_tags(node=param[0], group='group', tags=wrong_tag3) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_ADDRESS_FORMAT_INVALID == response.json()[ + 'error'] + + response = api.add_tags(node=param[0], group='group', tags=wrong_tag4) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_ADDRESS_FORMAT_INVALID == response.json()[ + 'error'] + + response = api.add_tags(node=param[0], group='group', tags=wrong_tag5) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_ADDRESS_FORMAT_INVALID == response.json()[ + 'error'] + + @description(given="created modbus node and tags", when="write/read tags", then="write/read success") + def test_write_read_tags(self, param): + api.write_tag_check( + node=param[0], group='group', tag=hold_int16[0]['name'], value=-123) + api.write_tag_check( + node=param[0], group='group', tag=hold_uint16[0]['name'], value=123) + api.write_tag_check( + node=param[0], group='group', tag=hold_int32[0]['name'], value=-1234) + api.write_tag_check( + node=param[0], group='group', tag=hold_uint32[0]['name'], value=1234) + api.write_tag_check( + node=param[0], group='group', tag=hold_float[0]['name'], value=13.4121) + api.write_tag_check( + node=param[0], group='group', tag=hold_string[0]['name'], value='hello') + api.write_tag_check( + node=param[0], group='group', tag=hold_bytes[0]['name'], value=[0x1, 0x2, 0x3, 0x4]) + api.write_tag_check( + node=param[0], group='group', tag=coil_bit_1[0]['name'], value=1) + api.write_tag_check( + node=param[0], group='group', tag=coil_bit_2[0]['name'], value=0) + api.write_tag_check( + node=param[0], group='group', tag=coil_bit_3[0]['name'], value=1) + api.write_tag_check( + node=param[0], group='group', tag=coil_bit_4[0]['name'], value=1) + api.write_tag_check( + node=param[0], group='group', tag=coil_bit_5[0]['name'], value=0) + + time.sleep(0.30) + assert -123 == api.read_tag( + node=param[0], group='group', tag=hold_int16[0]['name']) + assert 123 == api.read_tag( + node=param[0], group='group', tag=hold_uint16[0]['name']) + assert -1234 == api.read_tag( + node=param[0], group='group', tag=hold_int32[0]['name']) + assert 1234 == api.read_tag( + node=param[0], group='group', tag=hold_uint32[0]['name']) + assert compare_float(13.4121, api.read_tag( + node=param[0], group='group', tag=hold_float[0]['name'])) + assert 'hello' == api.read_tag( + node=param[0], group='group', tag=hold_string[0]['name']) + bytes = api.read_tag( + node=param[0], group='group', tag=hold_bytes[0]['name']) + assert len(bytes) == 10 + assert bytes == [0x1, 0x2, 0x3, 0x4, 0, 0, 0, 0, 0, 0] + + assert 1 == api.read_tag( + node=param[0], group='group', tag=coil_bit_1[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=coil_bit_2[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=coil_bit_3[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=coil_bit_4[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=coil_bit_5[0]['name']) + + @description(given="created modbus node and tags", when="read tags", then="read success") + def test_read_tags(self, param): + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_register_bit[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_register_uint16[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_register_int16[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_register_uint32[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_register_int32[0]['name']) + compare_float(0, api.read_tag( + node=param[0], group='group', tag=input_register_float[0]['name'])) + assert '' == api.read_tag( + node=param[0], group='group', tag=input_register_string[0]['name']) + bytes = api.read_tag( + node=param[0], group='group', tag=input_register_bytes[0]['name']) + assert len(bytes) == 10 + assert bytes == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_bit_1[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_bit_2[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_bit_3[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_bit_4[0]['name']) + assert 0 == api.read_tag( + node=param[0], group='group', tag=input_bit_5[0]['name']) + + @description(given="created modbus node, a tag with same name/address that in different groups", when="read tags", then="read success") + def test_read_tag_in_diff_group(self, param): + response = api.add_group(node=param[0], group='group1') + assert 200 == response.status_code + + api.add_tags_check(node=param[0], group='group1', tags=hold_int16) + api.write_tag_check( + node=param[0], group='group', tag=hold_int16[0]['name'], value=222) + time.sleep(0.30) + assert 222 == api.read_tag( + node=param[0], group='group', tag=hold_int16[0]['name']) + assert 222 == api.read_tag( + node=param[0], group='group1', tag=hold_int16[0]['name']) + + @description(given="created modbus node, a tag with same name diff address that in different groups", when="read tags", then="read success") + def test_read_tag_in_diff_address_group(self, param): + t_tag = [{"name": "t_tag", "address": "1!400031", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + + api.add_tags_check(node=param[0], group='group1', tags=t_tag) + api.write_tag_check( + node=param[0], group='group', tag=hold_int16[0]['name'], value=333) + api.write_tag_check( + node=param[0], group='group1', tag=t_tag[0]['name'], value=444) + time.sleep(0.30) + assert 333 == api.read_tag( + node=param[0], group='group', tag=hold_int16[0]['name']) + assert 444 == api.read_tag( + node=param[0], group='group1', tag=t_tag[0]['name']) + + @description(given="created modbus node/tags", when="update tags", then="update success") + def test_update_tag(self, param): + up_tag = [{"name": "up_tag", "address": "1!400031", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + api.add_tags_check(node=param[0], group='group', tags=up_tag) + + up_tag[0]['address'] = '2!400041' + up_tag[0]['type'] = config.NEU_TYPE_FLOAT + response = api.update_tags( + node=param[0], group='group', tags=up_tag) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + @description(given="created modbus node/tags", when="update tag with unmatch address/type", then="update failed") + def test_update_wrong_tag(self, param): + up_tag = [{"name": "up_tag", "address": "1!400031", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + up_tag[0]['address'] = '2!400041' + up_tag[0]['type'] = config.NEU_TYPE_BIT + response = api.update_tags( + node=param[0], group='group', tags=up_tag) + assert 200 == response.status_code + assert error.NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT == response.json()[ + 'error'] + + @description(given="created modbus node", when="write tag that donot exist in neuron", then="write failed") + def test_write_not_exist_tag(self, param): + response = api.write_tag( + node=param[0], group='group', tag='not_exist', value=1) + assert 404 == response.status_code + assert error.NEU_ERR_TAG_NOT_EXIST == response.json()['error'] + + response = api.write_tag( + node=param[0], group='groupxx', tag='not_exist', value=1) + assert 404 == response.status_code + assert error.NEU_ERR_GROUP_NOT_EXIST == response.json()['error'] + + response = api.write_tag( + node="nonode", group='group', tag='not_exist', value=1) + assert 404 == response.status_code + assert error.NEU_ERR_NODE_NOT_EXIST == response.json()['error'] + + @description(given="created modbus node/tag", when="write only read tag", then="write failed") + def test_write_only_read_tag(self, param): + r_tag = [{"name": "r_tag", "address": "1!400031", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_INT16}] + api.add_tags_check(node=param[0], group='group', tags=r_tag) + + response = api.write_tag( + node=param[0], group='group', tag=r_tag[0]['name'], value=1) + assert 200 == response.status_code + assert error.NEU_ERR_PLUGIN_TAG_NOT_ALLOW_WRITE == response.json()[ + 'error'] + + @description(given="created modbus node/tag", when="node stopped and read/write tag", then="read/write failed") + def test_read_write_tag_stopped_node(self, param): + response = api.node_ctl(node=param[0], ctl=config.NEU_CTL_STOP) + assert 200 == response.status_code + + error_code = api.read_tag_error(node=param[0], group='group', + tag=hold_int16[0]['name']) + assert error.NEU_ERR_PLUGIN_NOT_RUNNING == error_code + + response = api.write_tag( + node=param[0], group='group', tag=hold_int16[0]['name'], value=1) + assert 200 == response.status_code + assert error.NEU_ERR_PLUGIN_NOT_RUNNING == response.json()['error'] + + response = api.node_ctl(node=param[0], ctl=config.NEU_CTL_START) + assert 200 == response.status_code + + @description(given="created modbus node", when="add decimal", then="add success") + def test_add_decimal_tag(self, param): + api.add_tags_check( + node=param[0], group='group', tags=hold_int16_decimal) + api.add_tags_check( + node=param[0], group='group', tags=hold_uint16_decimal) + api.add_tags_check( + node=param[0], group='group', tags=hold_int32_decimal) + api.add_tags_check( + node=param[0], group='group', tags=hold_uint32_decimal) + api.add_tags_check( + node=param[0], group='group', tags=hold_float_decimal) + api.add_tags_check( + node=param[0], group='group', tags=hold_double_decimal) + + @description(given="created modbus node/tag", when="read/write decimal tag", then="read/write success") + def test_read_write_decimal_tag(self, param): + api.write_tag_check( + node=param[0], group='group', tag=hold_int16_decimal[0]['name'], value=11) + api.write_tag_check( + node=param[0], group='group', tag=hold_uint16_decimal[0]['name'], value=23) + api.write_tag_check( + node=param[0], group='group', tag=hold_int32_decimal[0]['name'], value=123) + api.write_tag_check( + node=param[0], group='group', tag=hold_uint32_decimal[0]['name'], value=123) + api.write_tag_check( + node=param[0], group='group', tag=hold_float_decimal[0]['name'], value=121.314) + api.write_tag_check( + node=param[0], group='group', tag=hold_double_decimal[0]['name'], value=513.11) + + time.sleep(0.3) + assert 11 == api.read_tag( + node=param[0], group='group', tag=hold_int16_decimal[0]['name']) + assert 23 == api.read_tag( + node=param[0], group='group', tag=hold_uint16_decimal[0]['name']) + assert 123 == api.read_tag( + node=param[0], group='group', tag=hold_int32_decimal[0]['name']) + assert 123 == api.read_tag( + node=param[0], group='group', tag=hold_uint32_decimal[0]['name']) + compare_float(121.314, api.read_tag( + node=param[0], group='group', tag=hold_float_decimal[0]['name'])) + assert 513.11 == api.read_tag( + node=param[0], group='group', tag=hold_double_decimal[0]['name']) + + @description(given="created modbus node", when="add precision tag", then="add success") + def test_add_precision_tag(self, param): + api.add_tags_check( + node=param[0], group='group', tags=hold_float_precision) + api.add_tags_check( + node=param[0], group='group', tags=hold_double_precision) + + @description(given="created modbus node/tag", when="read/write precision tag", then="read/write success") + def test_read_write_precision_tag(self, param): + api.write_tag_check( + node=param[0], group='group', tag=hold_float_precision[0]['name'], value=121.3149121) + api.write_tag_check( + node=param[0], group='group', tag=hold_double_precision[0]['name'], value=513.1279112) + time.sleep(0.3) + compare_float(121.314, api.read_tag( + node=param[0], group='group', tag=hold_float_precision[0]['name'])) + compare_float(513.127, api.read_tag( + node=param[0], group='group', tag=hold_double_precision[0]['name'])) diff --git a/tests/ft/neuron/api.py b/tests/ft/neuron/api.py index 615f9dcf..d61ab773 100644 --- a/tests/ft/neuron/api.py +++ b/tests/ft/neuron/api.py @@ -1,5 +1,6 @@ import requests import neuron.config as config +import neuron.error as error def login(user='admin', password='0000'): @@ -50,6 +51,93 @@ def get_node_setting(node, jwt=config.default_jwt): return requests.get(url=config.BASE_URL + '/api/v2/node/setting', headers={"Authorization": jwt}, params={"node": node}) +def add_group(node, group, interval=100): + return requests.post(url=config.BASE_URL + '/api/v2/group', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "interval": interval}) + + +def del_group(node, group): + return requests.delete(url=config.BASE_URL + '/api/v2/group', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group}) + + +def update_group(node, group, new_name="", interval=0): + if len(new_name) > 0 and interval > 0: + return requests.put(url=config.BASE_URL + '/api/v2/group', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "new_name": new_name, "interval": interval}) + elif len(new_name) > 0: + return requests.put(url=config.BASE_URL + '/api/v2/group', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "new_name": new_name}) + elif interval > 0: + return requests.put(url=config.BASE_URL + '/api/v2/group', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "interval": interval}) + else: + assert False + + +def add_tags(node, group, tags): + return requests.post(url=config.BASE_URL + '/api/v2/tags', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tags": tags}) + + +def add_tags_check(node, group, tags): + response = add_tags(node=node, group=group, tags=tags) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + +def del_tags(node, group, tags): + return requests.delete(url=config.BASE_URL + '/api/v2/tags', headers={"Authorizatioin": config.default_jwt}, json={"node": node, "group": group, "tags": tags}) + + +def update_tags(node, group, tags): + return requests.put(url=config.BASE_URL + '/api/v2/tags', headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tags": tags}) + + +def get_tags(node, group): + return requests.get(url=config.BASE_URL + "/api/v2/tags", headers={"Authorization": config.default_jwt}, params={"node": node, "group": group}) + + +def read_tags(node, group): + return requests.post(url=config.BASE_URL + "/api/v2/read", headers={"Authorization": config.default_jwt}, json={"node": node, "group": group}) + + +def read_tag(node, group, tag): + response = read_tags(node, group) + assert 200 == response.status_code + x = list(filter(lambda x: x['name'] == tag, + response.json()['tags'])) + assert len(x) == 1 + try: + x[0]['value'] + except KeyError: + print(x[0]) + finally: + return x[0]['value'] + + +def read_tag_error(node, group, tag): + response = read_tags(node, group) + assert 200 == response.status_code + x = list(filter(lambda x: x['name'] == tag, + response.json()['tags'])) + assert len(x) == 1 + try: + x[0]['error'] + except KeyError: + print(x[0]) + finally: + return x[0]['error'] + + +def write_tag(node, group, tag, value): + return requests.post(url=config.BASE_URL + "/api/v2/write", headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tag": tag, "value": value}) + + +def write_tag_check(node, group, tag, value): + response = write_tag(node, group, tag, value) + assert 200 == response.status_code + assert error.NEU_ERR_SUCCESS == response.json()['error'] + + +def write_tags(node, group, tag_values): + return requests.post(url=config.BASE_URL + "/api/v2/writes", headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tags": tag_values}) + + # plugin setting diff --git a/tests/ft/neuron/common.py b/tests/ft/neuron/common.py index f4d1654b..ceb2b358 100644 --- a/tests/ft/neuron/common.py +++ b/tests/ft/neuron/common.py @@ -29,6 +29,10 @@ def random_port(): return random.randint(30000, 65535) +def compare_float(v1, v2, delta=0.001): + return abs(v1 - v2) < delta + + @pytest.fixture(autouse=True, scope='class') def class_setup_and_teardown(): process.remove_persistence() diff --git a/tests/ft/neuron/config.py b/tests/ft/neuron/config.py index 9a59c33d..863acfd5 100644 --- a/tests/ft/neuron/config.py +++ b/tests/ft/neuron/config.py @@ -18,6 +18,9 @@ NEU_NODE_LINK_STATE_CONNECTED = 1 NEU_TAG_ATTRIBUTE_READ = 1 NEU_TAG_ATTRIBUTE_WRITE = 2 NEU_TAG_ATTRIBUTE_SUBSCRIBE = 4 +NEU_TAG_ATTRIBUTE_STATIC = 8 +NEU_TAG_ATTRIBUTE_RW = NEU_TAG_ATTRIBUTE_READ | NEU_TAG_ATTRIBUTE_WRITE +NEU_TAG_ATTRIBUTE_RW_STATIC = NEU_TAG_ATTRIBUTE_RW | NEU_TAG_ATTRIBUTE_STATIC NEU_TYPE_INT8 = 1 NEU_TYPE_UINT8 = 2 diff --git a/tests/ft/setup.py b/tests/ft/setup.py index 4288fce8..1a4efbad 100644 --- a/tests/ft/setup.py +++ b/tests/ft/setup.py @@ -1,4 +1,4 @@ from distutils.core import setup -setup(name='neuronft', version="0.0.1", +setup(name='neuronft', version="0.0.2", description='ft module', author='neuron', py_modules=['neuron.api', 'neuron.common', 'neuron.config', 'neuron.process', 'neuron.error']) From 2611199aeb76be568f2e5c835af11940066e785a Mon Sep 17 00:00:00 2001 From: fengzero Date: Thu, 12 Oct 2023 07:09:46 +0000 Subject: [PATCH 5/7] ft: remove dup case --- ft/modbus_rtu_test.robot | 197 ------------------------------- ft/modbus_tcp_test.robot | 248 --------------------------------------- ft/node_ctl_test.robot | 86 -------------- 3 files changed, 531 deletions(-) delete mode 100644 ft/modbus_rtu_test.robot delete mode 100644 ft/modbus_tcp_test.robot delete mode 100644 ft/node_ctl_test.robot diff --git a/ft/modbus_rtu_test.robot b/ft/modbus_rtu_test.robot deleted file mode 100644 index 27c475a7..00000000 --- a/ft/modbus_rtu_test.robot +++ /dev/null @@ -1,197 +0,0 @@ -*** Settings *** -Resource resource/api.resource -Resource resource/common.resource -Resource resource/error.resource -Resource resource/driver.resource -Suite Setup Modbus Test Setup -Suite Teardown Modbus Test Teardown - -*** Variables *** -${modbus_rtu_node} modbus_rtu_node -${PLUGIN-MODBUS-RTU} Modbus RTU - -${MODBUS_RTU_CONFIG} {"link": 1, "timeout": 3000, "interval": 10, "device": "", "stop": 0, "parity": 0, "baud": 4,"data": 3, "host": "127.0.0.1", "port": 60503, "connection_mode": 0, "transport_mode": 0} -${MODBUS_RTU_CONFIG_WRANING} {"link": 1, "host": "127.0.0.1","port": 60503,"connection_mode": 0} - -${hold_bit} {"name": "hold_bit", "address": "1!400001.15", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${hold_int16} {"name": "hold_int16", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_uint16} {"name": "hold_uint16", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT16}} -${hold_int32} {"name": "hold_int32", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT32}} -${hold_uint32} {"name": "hold_uint32", "address": "1!400015", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT32}} -${hold_float} {"name": "hold_float", "address": "1!400017", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_FLOAT}} -${hold_string} {"name": "hold_string", "address": "1!400020.10", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} - -${coil_bit_1} {"name": "coil_bit_1", "address": "1!000001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_2} {"name": "coil_bit_2", "address": "1!000002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_3} {"name": "coil_bit_3", "address": "1!000003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_4} {"name": "coil_bit_4", "address": "1!000005", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_5} {"name": "coil_bit_5", "address": "1!000010", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} - -${input_bit_1} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_2} {"name": "input_bit_2", "address": "1!100002", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_3} {"name": "input_bit_3", "address": "1!100003", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_4} {"name": "input_bit_4", "address": "1!100005", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_5} {"name": "input_bit_5", "address": "1!100010", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} - -${input_register_bit} {"name": "input_register_bit", "address": "1!30101.15", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_register_int16} {"name": "input_register_int16", "address": "1!30101", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} -${input_register_uint16} {"name": "input_register_uint16", "address": "1!30102", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_UINT16}} -${input_register_int32} {"name": "input_register_int32", "address": "1!30103", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT32}} -${input_register_uint32} {"name": "input_register_uint32", "address": "1!30115", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_UINT32}} -${input_register_float} {"name": "input_register_float", "address": "1!30117", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_FLOAT}} -${input_register_string} {"name": "input_register_string", "address": "1!30120.10", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_STRING}} - -${hold_int16_address_update} {"name": "hold_int16", "address": "1!400100", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_type_update} {"name": "hold_int16", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT32}} - -${input_bit_1_name_wrong} {"name": "input_bit", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_1_attribute_unmatch} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${input_bit_1_type_unmatch} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} - -${hold_int16_1} {"name": "hold_int16_1", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_2} {"name": "hold_int16_2", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_3} {"name": "hold_int16_3", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_string_tags_1} {"name": "hold_string_tags_1", "address": "1!40001.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} -${hold_string_tags_2} {"name": "hold_string_tags_2", "address": "1!40003.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} -${hold_string_tags_3} {"name": "hold_string_tags_3", "address": "1!40005.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} - -*** Test Cases *** -Set a node with right settings, it should be success. - [Template] Set a ${node} with right ${node_settings}, it will be success. - ${modbus_rtu_node} ${MODBUS_RTU_CONFIG} - -Set a node with wrong settings, it should be failure. - [Template] Set a ${node} with wrong ${node_settings}, it will be failure. - ${modbus_rtu_node} ${MODBUS_RTU_CONFIG_WRANING} - -Set tags with multiple address and types and attribute, it should be success. - [Template] Add a ${tag} with right address and type and attribute from ${node}, it will be success. - ${hold_int16} ${modbus_rtu_node} - ${hold_uint16} ${modbus_rtu_node} - ${hold_int32} ${modbus_rtu_node} - ${hold_uint32} ${modbus_rtu_node} - ${hold_float} ${modbus_rtu_node} - ${hold_string} ${modbus_rtu_node} - - ${coil_bit_1} ${modbus_rtu_node} - ${coil_bit_2} ${modbus_rtu_node} - ${coil_bit_3} ${modbus_rtu_node} - ${coil_bit_4} ${modbus_rtu_node} - ${coil_bit_5} ${modbus_rtu_node} - - ${input_register_int16} ${modbus_rtu_node} - ${input_register_uint16} ${modbus_rtu_node} - ${input_register_int32} ${modbus_rtu_node} - ${input_register_uint32} ${modbus_rtu_node} - ${input_register_float} ${modbus_rtu_node} - ${input_register_string} ${modbus_rtu_node} - - ${input_bit_1} ${modbus_rtu_node} - ${input_bit_2} ${modbus_rtu_node} - ${input_bit_3} ${modbus_rtu_node} - ${input_bit_4} ${modbus_rtu_node} - ${input_bit_5} ${modbus_rtu_node} - -Set tags with unmatch address, type or attribute, it should be failure. - [Template] Set a ${tag} with unmatch address, type or attribute from ${node}, it will be failure and return ${resp_status} and ${error_code}. - ${input_bit_1_type_unmatch} ${modbus_rtu_node} 200 ${NEU_ERR_TAG_TYPE_NOT_SUPPORT} - ${input_bit_1_attribute_unmatch} ${modbus_rtu_node} 200 ${NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT} - -Write and Read all type tag with same slave id in hold register and coil, it should be success. - [Template] Write and Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${hold_int16} hold_int16 ${modbus_rtu_node} Compare Tag Value As Int 120 - ${hold_uint16} hold_uint16 ${modbus_rtu_node} Compare Tag Value As Int 65535 - ${hold_int32} hold_int32 ${modbus_rtu_node} Compare Tag Value As Int 77889912 - ${hold_uint32} hold_uint32 ${modbus_rtu_node} Compare Tag Value As Int 88991232 - ${hold_float} hold_float ${modbus_rtu_node} Compare Tag Value As Float 12.34 - ${hold_string} hold_string ${modbus_rtu_node} Compare Tag Value As Strings "abc123" - - ${coil_bit_1} coil_bit_1 ${modbus_rtu_node} Compare Tag Value As Int 1 - ${coil_bit_2} coil_bit_2 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${coil_bit_3} coil_bit_3 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${coil_bit_4} coil_bit_4 ${modbus_rtu_node} Compare Tag Value As Int 1 - ${coil_bit_5} coil_bit_5 ${modbus_rtu_node} Compare Tag Value As Int 1 - -Read all type tag with same slave id in input register and input, it should be success. - [Template] Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${input_register_int16} input_register_int16 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_register_uint16} input_register_uint16 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_register_int32} input_register_int32 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_register_uint32} input_register_uint32 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_register_float} input_register_float ${modbus_rtu_node} Compare Tag Value As Float 0 - ${input_register_string} input_register_string ${modbus_rtu_node} Compare Tag Value As Strings "" - - ${input_bit_1} input_bit_1 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_bit_2} input_bit_2 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_bit_3} input_bit_3 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_bit_4} input_bit_4 ${modbus_rtu_node} Compare Tag Value As Int 0 - ${input_bit_5} input_bit_5 ${modbus_rtu_node} Compare Tag Value As Int 0 - -Read some tags at time, it will be success. - [Template] Read some ${tags} from ${node}, it will be success. - ${input_register_int16},${input_register_uint16},${input_register_int32},${input_register_uint32},${input_register_float},${input_register_string},${input_register_bit} ${modbus_rtu_node} - ${hold_int16},${hold_uint16},${hold_int32},${hold_uint32},${hold_float},${hold_string},${hold_bit} ${modbus_rtu_node} - ${coil_bit_1},${coil_bit_2},${coil_bit_3},${coil_bit_4},${coil_bit_5} ${modbus_rtu_node} - ${input_bit_1},${input_bit_2},${input_bit_3},${input_bit_4},${input_bit_5} ${modbus_rtu_node} - -Write and read a tag with same name and same address that in different groups, it should be success. - ${groups}= Create List group-1 group-2 group-3 - Write and read a ${hold_int16} with same hold_int16 and same address in different ${groups} that from ${modbus_rtu_node}, using Compare Tag Value As Int to check the 2, it will be success. - -Write and read a tag with same name but different address that in different groups, it should be success. - ${groups}= Create List group-1 group-2 group-3 - Write and read ${hold_int16} ${hold_int16_address_update} with same hold_int16 but different address in different ${groups} that from ${modbus_rtu_node}, using Compare Tag Value As Int to check the 2, it will be success. - -Update a tag with right address and types and attribute, it will be success - [Template] Update a ${tag} by a ${tag_update} named ${tag_name} from ${node} , it can read and write, using ${check} to check the ${value}, it will be success. - ${hold_int16} ${hold_int16_address_update} hold_int16 ${modbus_rtu_node} Compare Tag Value As Int 120 - ${hold_int16} ${hold_int16_type_update} hold_int16 ${modbus_rtu_node} Compare Tag Value As Int 120 - -Update a tag with unmatch address and types and attribute, it should be failure. - [Template] Update a ${tag} by a ${tag_update} with the unmatch settings from ${node} , it will be failure and return ${resp_status} and ${error_code}. - ${input_bit_1} ${input_bit_1_attribute_unmatch} ${modbus_rtu_node} 200 ${NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT} - ${input_bit_1} ${input_bit_1_type_unmatch} ${modbus_rtu_node} 200 ${NEU_ERR_TAG_TYPE_NOT_SUPPORT} - ${input_bit_1} ${input_bit_1_name_wrong} ${modbus_rtu_node} 200 ${NEU_ERR_TAG_NOT_EXIST} - -Write 3 tags 1 time, it should return success - [Template] Write and Read ${tag_data1}, ${tag_data2} and ${tag_data3} named ${tag1}, ${tag2} and ${tag3} from ${node}, using ${check} to check the ${value1}, ${value2} and ${value3}, it will be success. - ${hold_int16_1} ${hold_int16_2} ${hold_int16_3} hold_int16_1 hold_int16_2 hold_int16_3 ${modbus_rtu_node} Compare Tag Value As Int 1 2 3 - ${coil_bit_1} ${coil_bit_2} ${coil_bit_3} coil_bit_1 coil_bit_2 coil_bit_3 ${modbus_rtu_node} Compare Tag Value As Int 1 0 1 - ${hold_string_tags_1} ${hold_string_tags_2} ${hold_string_tags_3} hold_string_tags_1 hold_string_tags_2 hold_string_tags_3 ${modbus_rtu_node} Compare Tag Value As Strings "a" "b" "c" - -Write a value to a tag that don't exit in plc or neuron, it will be failure. - [Template] Write a ${value} to a ${tag} with named ${tag_name} that don't exist in neuron or plc from ${node}, it will be failure. - 12 ${input_bit_1} input ${modbus_rtu_node} - -Write value to a tag without write attribute, it will be failure. - [Template] Write a ${value} to a ${tag} named ${tag_name} that without write attribute from ${node}, it will be failure. - 1 ${input_bit_1} input_bit_1 ${modbus_rtu_node} - -Write and read a value to a tag when the node is stoped, it will be failure. - [Template] Write and read a ${value} to a ${tag} named ${tag_name} when the ${node} is stoped, it will be failure. - 1 ${hold_int16} hold_int16 ${modbus_rtu_node} - -*** Keywords *** -Modbus Test Setup - Start Modbus-RTU Simulator - - Start Neuronx - - ${res}= Add Node ${modbus_rtu_node} ${PLUGIN-MODBUS-RTU} - Check Response Status ${res} 200 - - ${res}= Node Setting ${modbus_rtu_node} ${MODBUS_RTU_CONFIG} - Check Response Status ${res} 200 - - ${state}= Get Node State ${modbus_rtu_node} - Should Be Equal As Integers ${state}[running] ${NODE_STATE_RUNNING} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - -Modbus Test Teardown - Del Node ${modbus_rtu_node} - Stop Neuronx - Terminate All Processes kill=false - -Start Modbus-RTU Simulator - ${handle} = Start Process ${MODBUS_TCP_SERVER_SIMULATOR} rtu 60503 ip_v4 cwd=build/simulator - [Return] ${handle} diff --git a/ft/modbus_tcp_test.robot b/ft/modbus_tcp_test.robot deleted file mode 100644 index 901a9a1d..00000000 --- a/ft/modbus_tcp_test.robot +++ /dev/null @@ -1,248 +0,0 @@ -*** Settings *** -Library Process -Library OperatingSystem - -Resource resource/api.resource -Resource resource/common.resource -Resource resource/error.resource -Resource resource/driver.resource -Suite Setup Modbus Test Setup -Suite Teardown Modbus Test Teardown - -*** Variables *** -${PLUGIN-MODBUS-TCP} Modbus TCP - -${modbus_tcp_node} modbus_tcp_node - -${MODBUS_TCP_CONFIG} {"connection_mode": 0, "transport_mode": 0, "interval": 0, "host": "127.0.0.1","port": 60502,"timeout": 3000} - -${MODBUS_TCP_CONFIG_WRONG} {"connection_mode": 0,"host": "127.0.0.1", "port": 60502} - -${hold_bit} {"name": "hold_bit", "address": "1!400001.15", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${hold_int16} {"name": "hold_int16", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_uint16} {"name": "hold_uint16", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT16}} -${hold_int32} {"name": "hold_int32", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT32}} -${hold_uint32} {"name": "hold_uint32", "address": "1!400015", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT32}} -${hold_float} {"name": "hold_float", "address": "1!400017", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_FLOAT}} -${hold_string} {"name": "hold_string", "address": "1!400020.10", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} -${hold_int16_s} {"name": "hold_int16_s", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_INT16}, "value": 1} -${hold_uint16_s} {"name": "hold_uint16_s", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_UINT16}, "value": 1} -${hold_int32_s} {"name": "hold_int32_s", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_INT32}, "value": 1} -${hold_uint32_s} {"name": "hold_uint32_s", "address": "1!400015", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_UINT32}, "value": 1} -${hold_float_s} {"name": "hold_float_s", "address": "1!400017", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_FLOAT}, "value": 1.0} -${hold_string_s} {"name": "hold_string_s", "address": "1!400020.10", "attribute": ${TAG_ATTRIBUTE_STATIC_RW}, "type": ${TAG_TYPE_STRING}, "value": "a"} - -${coil_bit_1} {"name": "coil_bit_1", "address": "1!000001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_2} {"name": "coil_bit_2", "address": "1!000002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_3} {"name": "coil_bit_3", "address": "1!000003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_4} {"name": "coil_bit_4", "address": "1!000005", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${coil_bit_5} {"name": "coil_bit_5", "address": "1!000010", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} - -${input_bit_1} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_2} {"name": "input_bit_2", "address": "1!100002", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_3} {"name": "input_bit_3", "address": "1!100003", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_4} {"name": "input_bit_4", "address": "1!100005", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_5} {"name": "input_bit_5", "address": "1!100010", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} - -${input_register_bit} {"name": "input_register_bit", "address": "1!30101.15", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_register_int16} {"name": "input_register_int16", "address": "1!30101", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} -${input_register_uint16} {"name": "input_register_uint16", "address": "1!30102", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_UINT16}} -${input_register_int32} {"name": "input_register_int32", "address": "1!30103", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT32}} -${input_register_uint32} {"name": "input_register_uint32", "address": "1!30115", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_UINT32}} -${input_register_float} {"name": "input_register_float", "address": "1!30117", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_FLOAT}} -${input_register_string} {"name": "input_register_string", "address": "1!30120.10", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_STRING}} - -${hold_int16_address_update} {"name": "hold_int16", "address": "1!400100", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_type_update} {"name": "hold_int16", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT32}} - -${input_bit_1_name_wrong} {"name": "input_bit", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_BIT}} -${input_bit_1_attribute_unmatch} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_BIT}} -${input_bit_1_type_unmatch} {"name": "input_bit_1", "address": "1!100001", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} - -${hold_int16_decimal} {"name": "hold_int16_decimal", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}, "decimal": 0.1} -${hold_uint16_decimal} {"name": "hold_uint16_decimal", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT16}, "decimal": 0.1} -${hold_int32_decimal} {"name": "hold_int32_decimal", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT32}, "decimal": 0.1} -${hold_uint32_decimal} {"name": "hold_uint32_decimal", "address": "1!400015", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_UINT32}, "decimal": 0.1} -${hold_float_decimal} {"name": "hold_float_decimal", "address": "1!400017", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_FLOAT}, "decimal": 0.1} -${hold_double_decimal} {"name": "hold_double_decimal", "address": "1!400027", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_DOUBLE}, "decimal": 0.1} - -${hold_float_precision} {"name": "hold_float_precision", "address": "1!400030", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_FLOAT}, "precision": 2} -${hold_double_precision} {"name": "hold_double_precision", "address": "1!400040", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_DOUBLE}, "precision": 2} - -${hold_int16_1} {"name": "hold_int16_1", "address": "1!400001", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_2} {"name": "hold_int16_2", "address": "1!400002", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_int16_3} {"name": "hold_int16_3", "address": "1!400003", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_INT16}} -${hold_string_tags_1} {"name": "hold_string_tags_1", "address": "1!40001.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} -${hold_string_tags_2} {"name": "hold_string_tags_2", "address": "1!40003.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} -${hold_string_tags_3} {"name": "hold_string_tags_3", "address": "1!40005.4", "attribute": ${TAG_ATTRIBUTE_RW}, "type": ${TAG_TYPE_STRING}} - -*** Test Cases *** -Set a node with right settings, it should be success. - [Template] Set a ${node} with right ${node_settings}, it will be success. - ${modbus_tcp_node} ${MODBUS_TCP_CONFIG} - -Set a node with wrong settings, it should be failure. - [Template] Set a ${node} with wrong ${node_settings}, it will be failure. - ${modbus_tcp_node} ${MODBUS_TCP_CONFIG_WRONG} - -Set tags with multiple address and types and attribute, it should be success. - [Template] Add a ${tag} with right address and type and attribute from ${node}, it will be success. - ${hold_int16} ${modbus_tcp_node} - ${hold_uint16} ${modbus_tcp_node} - ${hold_int32} ${modbus_tcp_node} - ${hold_uint32} ${modbus_tcp_node} - ${hold_float} ${modbus_tcp_node} - ${hold_string} ${modbus_tcp_node} - ${hold_int16_s} ${modbus_tcp_node} - ${hold_uint16_s} ${modbus_tcp_node} - ${hold_int32_s} ${modbus_tcp_node} - ${hold_uint32_s} ${modbus_tcp_node} - ${hold_float_s} ${modbus_tcp_node} - ${hold_string_s} ${modbus_tcp_node} - - ${coil_bit_1} ${modbus_tcp_node} - ${coil_bit_2} ${modbus_tcp_node} - ${coil_bit_3} ${modbus_tcp_node} - ${coil_bit_4} ${modbus_tcp_node} - ${coil_bit_5} ${modbus_tcp_node} - - ${input_register_int16} ${modbus_tcp_node} - ${input_register_uint16} ${modbus_tcp_node} - ${input_register_int32} ${modbus_tcp_node} - ${input_register_uint32} ${modbus_tcp_node} - ${input_register_float} ${modbus_tcp_node} - ${input_register_string} ${modbus_tcp_node} - - ${input_bit_1} ${modbus_tcp_node} - ${input_bit_2} ${modbus_tcp_node} - ${input_bit_3} ${modbus_tcp_node} - ${input_bit_4} ${modbus_tcp_node} - ${input_bit_5} ${modbus_tcp_node} - -Set tags with unmatch address, type or attribute, it should be failure. - [Template] Set a ${tag} with unmatch address, type or attribute from ${node}, it will be failure and return ${resp_status} and ${error_code}. - ${input_bit_1_type_unmatch} ${modbus_tcp_node} 200 ${NEU_ERR_TAG_TYPE_NOT_SUPPORT} - ${input_bit_1_attribute_unmatch} ${modbus_tcp_node} 200 ${NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT} - -Write and Read all type tag with same slave id in hold register and coil, it should be success. - [Template] Write and Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${hold_int16} hold_int16 ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_uint16} hold_uint16 ${modbus_tcp_node} Compare Tag Value As Int 65535 - ${hold_int32} hold_int32 ${modbus_tcp_node} Compare Tag Value As Int 77889912 - ${hold_uint32} hold_uint32 ${modbus_tcp_node} Compare Tag Value As Int 88991232 - ${hold_float} hold_float ${modbus_tcp_node} Compare Tag Value As Float 12.34 - ${hold_string} hold_string ${modbus_tcp_node} Compare Tag Value As Strings "abc123" - - ${coil_bit_1} coil_bit_1 ${modbus_tcp_node} Compare Tag Value As Int 1 - ${coil_bit_2} coil_bit_2 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${coil_bit_3} coil_bit_3 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${coil_bit_4} coil_bit_4 ${modbus_tcp_node} Compare Tag Value As Int 1 - ${coil_bit_5} coil_bit_5 ${modbus_tcp_node} Compare Tag Value As Int 1 - -Read all type tag with same slave id in input register and input, it should be success. - [Template] Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${input_register_int16} input_register_int16 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_register_uint16} input_register_uint16 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_register_int32} input_register_int32 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_register_uint32} input_register_uint32 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_register_float} input_register_float ${modbus_tcp_node} Compare Tag Value As Float 0 - ${input_register_string} input_register_string ${modbus_tcp_node} Compare Tag Value As Strings "" - - ${input_bit_1} input_bit_1 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_bit_2} input_bit_2 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_bit_3} input_bit_3 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_bit_4} input_bit_4 ${modbus_tcp_node} Compare Tag Value As Int 0 - ${input_bit_5} input_bit_5 ${modbus_tcp_node} Compare Tag Value As Int 0 - -Read some tags at time, it will be success. - [Template] Read some ${tags} from ${node}, it will be success. - ${input_register_int16},${input_register_uint16},${input_register_int32},${input_register_uint32},${input_register_float},${input_register_string},${input_register_bit} ${modbus_tcp_node} - ${hold_int16},${hold_uint16},${hold_int32},${hold_uint32},${hold_float},${hold_string},${hold_bit} ${modbus_tcp_node} - ${coil_bit_1},${coil_bit_2},${coil_bit_3},${coil_bit_4},${coil_bit_5} ${modbus_tcp_node} - ${input_bit_1},${input_bit_2},${input_bit_3},${input_bit_4},${input_bit_5} ${modbus_tcp_node} - -Write and read a tag with same name and same address that in different groups, it should be success. - ${groups}= Create List group-1 group-2 group-3 - Write and read a ${hold_int16} with same hold_int16 and same address in different ${groups} that from ${modbus_tcp_node}, using Compare Tag Value As Int to check the 2, it will be success. - -Write and read a tag with same name but different address that in different groups, it should be success. - ${groups}= Create List group-1 group-2 group-3 - Write and read ${hold_int16} ${hold_int16_address_update} with same hold_int16 but different address in different ${groups} that from ${modbus_tcp_node}, using Compare Tag Value As Int to check the 2, it will be success. - -Update a tag with right address and types and attribute, it will be success - [Template] Update a ${tag} by a ${tag_update} named ${tag_name} from ${node} , it can read and write, using ${check} to check the ${value}, it will be success. - ${hold_int16} ${hold_int16_address_update} hold_int16 ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_int16} ${hold_int16_type_update} hold_int16 ${modbus_tcp_node} Compare Tag Value As Int 120 - -Write 3 tags 1 time, it should return success - [Template] Write and Read ${tag_data1}, ${tag_data2} and ${tag_data3} named ${tag1}, ${tag2} and ${tag3} from ${node}, using ${check} to check the ${value1}, ${value2} and ${value3}, it will be success. - ${hold_int16_1} ${hold_int16_2} ${hold_int16_3} hold_int16_1 hold_int16_2 hold_int16_3 ${modbus_tcp_node} Compare Tag Value As Int 1 2 3 - ${coil_bit_1} ${coil_bit_2} ${coil_bit_3} coil_bit_1 coil_bit_2 coil_bit_3 ${modbus_tcp_node} Compare Tag Value As Int 1 0 1 - ${hold_string_tags_1} ${hold_string_tags_2} ${hold_string_tags_3} hold_string_tags_1 hold_string_tags_2 hold_string_tags_3 ${modbus_tcp_node} Compare Tag Value As Strings "a" "b" "c" - -Add a tag with decimal, it should return success - [Template] Add a ${tag} with right address and type and attribute from ${node}, it will be success. - ${hold_int16_decimal} ${modbus_tcp_node} - ${hold_uint16_decimal} ${modbus_tcp_node} - ${hold_int32_decimal} ${modbus_tcp_node} - ${hold_uint32_decimal} ${modbus_tcp_node} - ${hold_float_decimal} ${modbus_tcp_node} - ${hold_double_decimal} ${modbus_tcp_node} - -Write and read a value to a tag with decimal, it should return success - [Template] Write and Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${hold_int16_decimal} hold_int16_decimal ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_uint16_decimal} hold_uint16_decimal ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_int32_decimal} hold_int32_decimal ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_uint32_decimal} hold_uint32_decimal ${modbus_tcp_node} Compare Tag Value As Int 120 - ${hold_float_decimal} hold_float_decimal ${modbus_tcp_node} Compare Tag Value As Float 120.5 - ${hold_double_decimal} hold_double_decimal ${modbus_tcp_node} Compare Tag Value As Float 120.5 - -Add a tag with precision, it should return success - [Template] Add a ${tag} with right address and type and attribute from ${node}, it will be success. - ${hold_float_precision} ${modbus_tcp_node} - ${hold_double_precision} ${modbus_tcp_node} - -Write and read a value to a tag with precision, it should return success - [Template] Write and Read a ${tag} named ${tag_name} from ${node}, using ${check} to check the ${value}, it will be success. - ${hold_float_precision} hold_float_precision ${modbus_tcp_node} Compare Tag Value As Float 120.5 - ${hold_double_precision} hold_double_precision ${modbus_tcp_node} Compare Tag Value As Float 1111111111111111111111111111111111111111.1 - -Update a tag with unmatch address and types and attribute, it should be failure. - [Template] Update a ${tag} by a ${tag_update} with the unmatch settings from ${node} , it will be failure and return ${resp_status} and ${error_code}. - ${input_bit_1} ${input_bit_1_attribute_unmatch} ${modbus_tcp_node} 200 ${NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT} - ${input_bit_1} ${input_bit_1_type_unmatch} ${modbus_tcp_node} 200 ${NEU_ERR_TAG_TYPE_NOT_SUPPORT} - ${input_bit_1} ${input_bit_1_name_wrong} ${modbus_tcp_node} 200 ${NEU_ERR_TAG_NOT_EXIST} - -Write a value to a tag that don't exit in plc or neuron, it will be failure. - [Template] Write a ${value} to a ${tag} with named ${tag_name} that don't exist in neuron or plc from ${node}, it will be failure. - 12 ${input_bit_1} input ${modbus_tcp_node} - -Write value to a tag without write attribute, it will be failure. - [Template] Write a ${value} to a ${tag} named ${tag_name} that without write attribute from ${node}, it will be failure. - 1 ${input_bit_1} input_bit_1 ${modbus_tcp_node} - -Write and read a value to a tag when the node is stoped, it will be failure. - [Template] Write and read a ${value} to a ${tag} named ${tag_name} when the ${node} is stoped, it will be failure. - 1 ${hold_int16} hold_int16 ${modbus_tcp_node} - -*** Keywords *** -Modbus Test Setup - Start Modbus Simulator - - Start Neuronx - - ${res}= Add Node ${modbus_tcp_node} ${PLUGIN-MODBUS-TCP} - Check Response Status ${res} 200 - - ${res}= Node Setting ${modbus_tcp_node} ${MODBUS_TCP_CONFIG} - Check Response Status ${res} 200 - - ${state}= Get Node State ${modbus_tcp_node} - Should Be Equal As Integers ${state}[running] ${NODE_STATE_RUNNING} - # Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_CONNECTED} - -Modbus Test Teardown - Del Node ${modbus_tcp_node} - Stop Neuronx - Terminate All Processes kill=false diff --git a/ft/node_ctl_test.robot b/ft/node_ctl_test.robot deleted file mode 100644 index 3d9c4471..00000000 --- a/ft/node_ctl_test.robot +++ /dev/null @@ -1,86 +0,0 @@ -*** Settings *** -Resource resource/api.resource -Resource resource/common.resource -Resource resource/error.resource -Suite Setup Start Neuronx -Suite Teardown Stop Neuronx - - -*** Test Cases *** -Start an unconfigured node, it should return failure - ${res}= Add Node modbus-node ${PLUGIN-MODBUS-TCP} - Sleep 1s - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_INIT} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - - ${res} = Node Ctl modbus-node ${NODE_CTL_START} - Check Response Status ${res} 409 - Check Error Code ${res} ${NEU_ERR_NODE_NOT_READY} - -Stop node that is ready(init/idle), it should return failure - ${res} = Node Ctl modbus-node ${NODE_CTL_STOP} - Check Response Status ${res} 409 - Check Error Code ${res} ${NEU_ERR_NODE_NOT_RUNNING} - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_INIT} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - - [Teardown] Del Node modbus-node - -Start the configured node, it should return success - ${res}= Add Node modbus-node ${PLUGIN-MODBUS-TCP} - Sleep 1s - - Node Setting modbus-node ${MODBUS_TCP_CONFIG} - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_RUNNING} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - - ${res} = Node Ctl modbus-node ${NODE_CTL_STOP} - Check Response Status ${res} 200 - Check Error Code ${res} ${NEU_ERR_SUCCESS} - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_STOP} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - -Stop node that is stopped, it should return failure - ${res} = Node Ctl modbus-node ${NODE_CTL_STOP} - Check Response Status ${res} 409 - Check Error Code ${res} ${NEU_ERR_NODE_IS_STOPED} - -Start the stopped node, it should return success - ${res} = Node Ctl modbus-node ${NODE_CTL_START} - Check Response Status ${res} 200 - Check Error Code ${res} ${NEU_ERR_SUCCESS} - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_RUNNING} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - -Start the running node, it should return failure - ${res} = Node Ctl modbus-node ${NODE_CTL_START} - Check Response Status ${res} 409 - Check Error Code ${res} ${NEU_ERR_NODE_IS_RUNNING} - -When setting up a READY/RUNNING/STOPED node, the node status will not change - ${res} = Node Setting modbus-node ${MODBUS_TCP_CONFIG} - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_RUNNING} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - - ${res} = Node Ctl modbus-node ${NODE_CTL_STOP} - Check Response Status ${res} 200 - Check Error Code ${res} ${NEU_ERR_SUCCESS} - - ${res} = Node Setting modbus-node ${MODBUS_TCP_CONFIG} - - ${state} = Get Node State modbus-node - Should Be Equal As Integers ${state}[running] ${NODE_STATE_STOP} - Should Be Equal As Integers ${state}[link] ${NODE_LINK_STATE_DISCONNECTED} - - [Teardown] Del Node modbus-node \ No newline at end of file From 91b9eb066d5b3b842fab93a7b5ec494118908a60 Mon Sep 17 00:00:00 2001 From: fengzero Date: Thu, 12 Oct 2023 07:12:15 +0000 Subject: [PATCH 6/7] fix(ci): ui version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c15639e4..e22f4890 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ on: env: VERSION: 2.7.0 - UI_VERSION: 2.7.0 + UI_VERSION: 2.6.1 BRANCH: main jobs: From 3dd3e54e9c6118b6af3f9d1cc9f5196cf8de3913 Mon Sep 17 00:00:00 2001 From: fengzero Date: Thu, 12 Oct 2023 07:15:21 +0000 Subject: [PATCH 7/7] fix(ft): path --- tests/ft/driver/__init__.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/ft/driver/__init__.py diff --git a/tests/ft/driver/__init__.py b/tests/ft/driver/__init__.py new file mode 100644 index 00000000..6da12771 --- /dev/null +++ b/tests/ft/driver/__init__.py @@ -0,0 +1,3 @@ +import sys + +sys.path.append("tests/ft")