Commit 4b2ecce9 authored by Pavel Vainerman's avatar Pavel Vainerman

Работа над тестами.

- (VTypes): Нашёл и исправил ошибку в типах I2r,U2r,F2r - (UniSetTypes): исправил функцию uni_atoi для корректной работы с unsigned int.. - (MBSlave): исправления по результатам тестов (работа продолжается).
parent f4f1c874
#!/bin/sh
#while true; do
uniset2-start.sh -f ./uniset2-sviewer-text --confile test.xml --ulog-add-levels warn,crit
./uniset2-start.sh -f ./uniset2-sviewer-text --confile test.xml --ulog-add-levels warn,crit
#done
../../Utilities/scripts/uniset2-functions.sh
\ No newline at end of file
../../Utilities/scripts/uniset2-start.sh
\ No newline at end of file
......@@ -1277,7 +1277,7 @@ ModbusRTU::mbErrCode MBSlave::real_read_it( IOMap::iterator& it, ModbusRTU::Modb
// считая, что при "загрузке" всё было правильно
// инициализировано
// if( p->wnum >=0 && p->wnum < f4.wsize()
val = f2.raw.v[p->wnum];
val = f2.raw_backorder.v[p->wnum];
}
else if( p->vtype == VTypes::vtF4 )
{
......@@ -1307,11 +1307,11 @@ ModbusRTU::mbErrCode MBSlave::real_read_it( IOMap::iterator& it, ModbusRTU::Modb
// считая, что при "загрузке" всё было правильно
// инициализировано
// if( p->wnum >=0 && p->wnum < i2.wsize()
val = i2.raw.v[p->wnum];
val = i2.raw_backorder.v[p->wnum];
}
else if( p->vtype == VTypes::vtU2 )
{
unsigned long v = IOBase::processingAsAO(p,shm,force);
long v = IOBase::processingAsAO(p,shm,force);
VTypes::U2 u2(v);
// оптимизируем и проверку не делаем
// считая, что при "загрузке" всё было правильно
......@@ -1321,13 +1321,13 @@ ModbusRTU::mbErrCode MBSlave::real_read_it( IOMap::iterator& it, ModbusRTU::Modb
}
else if( p->vtype == VTypes::vtU2r )
{
unsigned long v = IOBase::processingAsAO(p,shm,force);
long v = IOBase::processingAsAO(p,shm,force);
VTypes::U2r u2(v);
// оптимизируем и проверку не делаем
// считая, что при "загрузке" всё было правильно
// инициализировано
// if( p->wnum >=0 && p->wnum < u2.wsize()
val = u2.raw.v[p->wnum];
val = u2.raw_backorder.v[p->wnum];
}
else
val = IOBase::processingAsAO(p,shm,force);
......
......@@ -141,10 +141,9 @@
<item default="4294967295" id="2004" mbs="1" mbreg="106" iotype="AI" vtype="U2r" name="TestVtype4" textname="Тестовый регистр для проверки vtype"/>
<item default="200" id="2005" mbs="1" mbreg="108" iotype="AI" vtype="byte" nbyte="1" name="TestVtype5" textname="Тестовый регистр для проверки vtype"/>
<item default="200" id="2006" mbs="1" mbreg="108" iotype="AI" vtype="byte" nbyte="2" name="TestVtype6" textname="Тестовый регистр для проверки vtype"/>
<item id="2007" mbs="1" mbreg="110" iotype="AI" vtype="F2" name="TestVtype7" textname="Тестовый регистр для проверки vtype"/>
<item id="2008" mbs="1" mbreg="112" iotype="AI" vtype="F2r" name="TestVtype8" textname="Тестовый регистр для проверки vtype"/>
<item id="2009" mbs="1" mbreg="110" iotype="AI" vtype="F2" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/>
<item id="2010" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype10" textname="Тестовый регистр для проверки vtype"/>
<item id="2007" default="250" precision="2" mbs="1" mbreg="110" iotype="AI" vtype="F2" name="TestVtype7" textname="Тестовый регистр для проверки vtype"/>
<item id="2008" default="250" precision="2" mbs="1" mbreg="112" iotype="AI" vtype="F2r" name="TestVtype8" textname="Тестовый регистр для проверки vtype"/>
<item id="2009" default="250000" precision="5" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/>
<item default="-100" id="2011" mbs="1" mbreg="118" iotype="AI" vtype="signed" name="TestVtype11" textname="Тестовый регистр для проверки vtype"/>
<item default="65534" id="2012" mbs="1" mbreg="119" iotype="AI" vtype="unsigned" name="TestVtype12" textname="Тестовый регистр для проверки vtype"/>
......
......@@ -432,13 +432,13 @@ TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]")
ModbusRTU::ModbusData tREG = 100;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,2);
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,I2::wsize());
I2 i2(ret.data,ret.count);
REQUIRE( (int)i2 == -100000 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,2);
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,I2::wsize());
I2 i2(ret.data,ret.count);
REQUIRE( (int)i2 == -100000 );
}
......@@ -448,33 +448,97 @@ TEST_CASE("Read(0x03,0x04): vtypes..","[modbus][mbslave][mbtcpslave]")
ModbusRTU::ModbusData tREG = 102;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,2);
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,I2r::wsize());
I2r i2r(ret.data,ret.count);
REQUIRE( (int)i2r == -100000 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,2);
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,I2r::wsize());
I2r i2r(ret.data,ret.count);
REQUIRE( (int)i2r == -100000 );
}
}
SECTION("Test: read vtype 'U2'")
{
ModbusRTU::ModbusData tREG = 101;
ModbusRTU::ModbusData tREG = 104;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,2);
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,U2::wsize());
U2 u2(ret.data,ret.count);
REQUIRE( (unsigned int)u2 == 4294967295 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,2);
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,U2::wsize());
U2 u2(ret.data,ret.count);
REQUIRE( (unsigned int)u2 == 4294967295 );
}
}
SECTION("Test: read vtype 'U2r'")
{
ModbusRTU::ModbusData tREG = 106;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,U2r::wsize());
U2r u2r(ret.data,ret.count);
REQUIRE( (unsigned int)u2r == 4294967295 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,U2r::wsize());
U2r u2r(ret.data,ret.count);
REQUIRE( (unsigned int)u2r == 4294967295 );
}
}
SECTION("Test: read vtype 'F2'")
{
ModbusRTU::ModbusData tREG = 110;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,F2::wsize());
F2 f2(ret.data,ret.count);
REQUIRE( (float)f2 == 2.5 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,F2::wsize());
F2 f2(ret.data,ret.count);
REQUIRE( (float)f2 == 2.5 );
}
}
SECTION("Test: read vtype 'F2r'")
{
ModbusRTU::ModbusData tREG = 112;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,F2r::wsize());
F2r f2r(ret.data,ret.count);
REQUIRE( (float)f2r == 2.5 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,F2r::wsize());
F2r f2r(ret.data,ret.count);
REQUIRE( (float)f2r == 2.5 );
}
}
SECTION("Test: read vtype 'F4'")
{
ModbusRTU::ModbusData tREG = 114;
SECTION("Test: read03")
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(slaveaddr,tREG,F4::wsize());
F4 f4(ret.data,ret.count);
REQUIRE( (float)f4 == 2.5 );
}
SECTION("Test: read04")
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(slaveaddr,tREG,F4::wsize());
F4 f4(ret.data,ret.count);
REQUIRE( (float)f4 == 2.5 );
}
}
}
TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]")
......
......@@ -40,7 +40,7 @@ static bool split_addr( const string& addr, string& host, ost::tpport_t& port )
{
host = addr.substr(0,pos);
string s_port(addr.substr(pos+1,addr.size()-1));
port = UniSetTypes::uni_atoi(s_port.c_str());
port = atoi(s_port.c_str());
return true;
}
......@@ -97,23 +97,23 @@ int main(int argc, char* argv[])
break;
case 't':
tout = UniSetTypes::uni_atoi(optarg);
tout = atoi(optarg);
break;
case 'x':
usecpause = UniSetTypes::uni_atoi(optarg)*1000;
usecpause = atoi(optarg)*1000;
break;
case 'c':
count = UniSetTypes::uni_atoi(optarg);
count = atoi(optarg);
break;
case 'p':
procID = UniSetTypes::uni_atoi(optarg);
procID = atoi(optarg);
break;
case 'n':
nodeID = UniSetTypes::uni_atoi(optarg);
nodeID = atoi(optarg);
break;
case 'b':
......@@ -133,7 +133,7 @@ int main(int argc, char* argv[])
break;
case 'z':
ncycles = UniSetTypes::uni_atoi(optarg);
ncycles = atoi(optarg);
break;
case '?':
......
......@@ -80,13 +80,21 @@ namespace VTypes
// конструкторы на разные случаи...
F2r(){}
F2r( float f ):F2(f){}
F2r( float f ):F2(f)
{
raw_backorder = raw;
std::swap(raw_backorder.v[0],raw_backorder.v[1]);
}
F2r( const ModbusRTU::ModbusData* data, int size ):F2(data,size)
{
// принимаем в обратном порядке.. поэтому переворачиваем raw
raw_backorder = raw;
std::swap(raw.v[0],raw.v[1]);
}
~F2r(){}
F2mem raw_backorder;
};
// --------------------------------------------------------------------------
class F4
......@@ -267,13 +275,21 @@ namespace VTypes
public:
I2r(){}
I2r( int v ):I2(v){}
I2r( int v ):I2(v)
{
raw_backorder = raw;
std::swap(raw_backorder.v[0],raw_backorder.v[1]);
}
I2r( const ModbusRTU::ModbusData* data, int size ):I2(data,size)
{
// принимаем в обратном порядке.. поэтому переворачиваем raw
raw_backorder = raw;
std::swap(raw.v[0],raw.v[1]);
}
~I2r(){}
I2mem raw_backorder;
};
// --------------------------------------------------------------------------
class U2
......@@ -317,13 +333,21 @@ namespace VTypes
public:
U2r(){}
U2r( int v ):U2(v){}
U2r( int v ):U2(v)
{
raw_backorder = raw;
std::swap(raw_backorder.v[0],raw_backorder.v[1]);
}
U2r( const ModbusRTU::ModbusData* data, int size ):U2(data,size)
{
// принимаем в обратном порядке.. поэтому переворачиваем raw
raw_backorder = raw;
std::swap(raw.v[0],raw.v[1]);
}
~U2r(){}
U2mem raw_backorder;
};
// --------------------------------------------------------------------------
......
#!/bin/sh
# '--' - нужен для отделения аоргументов catch, от наших..
uniset2-start.sh -f ./tests_with_conf $* -- --confile tests_with_conf.xml --prop-id2 -10
./uniset2-start.sh -f ./tests_with_conf $* -- --confile tests_with_conf.xml --prop-id2 -10
......@@ -2,10 +2,10 @@
# '--' - нужен для отделения аргументов catch, от наших..
cd ../../Utilities/Admin/
uniset2-start.sh -f ./create_links.sh
uniset2-start.sh -f ./create
./uniset2-start.sh -f ./create_links.sh
./uniset2-start.sh -f ./create
uniset2-start.sh -f ./exist | grep -q UNISET_PLC/Controllers || exit 1
./uniset2-start.sh -f ./exist | grep -q UNISET_PLC/Controllers || exit 1
cd -
uniset2-start.sh -f ./tests_with_sm $* -- --confile tests_with_sm.xml --e-startup-pause 10 --ulog-levels warn,crit --dlog-levels warn,crit
./uniset2-start.sh -f ./tests_with_sm $* -- --confile tests_with_sm.xml --e-startup-pause 10 --ulog-levels warn,crit --dlog-levels warn,crit
......@@ -18,6 +18,9 @@ TEST_CASE("VTypes: I2","[vtypes][I2]")
{
I2 v(100);
REQUIRE( (int)v == 100 );
I2 v2(-1000000);
REQUIRE( (int)v2 == -1000000 );
}
SECTION("Modbus constructor")
{
......@@ -42,6 +45,9 @@ TEST_CASE("VTypes: I2r","[vtypes][I2r]")
{
I2r v(100);
REQUIRE( (int)v == 100 );
I2r v1(-1000000);
REQUIRE( (int)v1 == -1000000 );
}
SECTION("Modbus constructor")
{
......@@ -52,6 +58,14 @@ TEST_CASE("VTypes: I2r","[vtypes][I2r]")
ModbusRTU::ModbusData data3[3] = {0,0xFFFF,0xFFFF};
I2r v2(data3,3);
REQUIRE( (int)v2 == 65535 );
I2r tmp(-100000);
ModbusRTU::ModbusData d2[2];
d2[0] = tmp.raw.v[1];
d2[1] = tmp.raw.v[0];
I2r v3(d2,2);
REQUIRE( (int)v3 == -100000 );
}
}
......@@ -64,8 +78,17 @@ TEST_CASE("VTypes: U2","[vtypes][U2]")
}
SECTION("'unsigned int' constructor")
{
U2 v( numeric_limits<unsigned int>::max() );
REQUIRE( (unsigned int)v == numeric_limits<unsigned int>::max() );
{
U2 v( numeric_limits<unsigned int>::max() );
REQUIRE( (unsigned int)v == numeric_limits<unsigned int>::max() );
REQUIRE( v.raw.v[0] == 0xffff );
REQUIRE( v.raw.v[1] == 0xffff );
}
{
U2 v(-1);
REQUIRE( (unsigned int)v == 4294967295 );
}
}
SECTION("Modbus constructor")
{
......
......@@ -149,14 +149,7 @@ namespace UniSetTypes
// Различные преобразования
//! Преобразование строки в число (воспринимает префикс 0, как 8-ное, префикс 0x, как 16-ное, минус для отриц. чисел)
inline int uni_atoi( const char* str )
{
int n = 0; // if str is NULL or sscanf failed, we return 0
if ( str != NULL )
std::sscanf(str, "%i", &n);
return n;
}
int uni_atoi( const char* str );
inline int uni_atoi( const std::string& str )
{
return uni_atoi(str.c_str());
......
......@@ -372,3 +372,29 @@ string UniSetTypes::dateToString(time_t tm, const std::string& brk )
}
//--------------------------------------------------------------------------------------------
int UniSetTypes::uni_atoi( const char* str )
{
// if str is NULL or sscanf failed, we return 0
if( str == nullptr )
return 0;
// приходиться самостоятельно проверять на наличие префикса "0x"
// чтобы применить соответствующую функцию.
// причём для чисел применяется atoll,
// чтобы корректно обрабатывать большие числа типа std::numeric_limits<unsigned int>::max()
// \warning есть сомнения, что на 64bit-тах это будет корректно работать..
int n = 0;
if( strlen(str) > 2 )
{
if( str[0]=='0' && str[1]=='x' )
{
std::sscanf(str, "%x", &n);
return n;
}
}
n = std::atoll(str); // универсальнее получать unsigned..чтобы не потерять "большие числа"..
return n;
}
//--------------------------------------------------------------------------------------------
......@@ -8,7 +8,7 @@ noinst_PROGRAMS = tests tests_with_conf
#umutex threadtst dlog
tests_SOURCES = tests.cc passivetimer.cc hourglass.cc delaytimer.cc unixml.cc sscanf_hex.cc \
callbacktimer.cc trigger.cc triggerOR.cc triggerAND.cc triggerOUT.cc pulse.cc \
modbustypes.cc
modbustypes.cc utypes.cc
tests_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS)
tests_CPPFLAGS = -I$(top_builddir)/include $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
......
#include <catch.hpp>
#include <sstream>
#include <limits>
#include "UniSetTypes.h"
using namespace std;
using namespace UniSetTypes;
TEST_CASE("UniSetTypes: uni_atoi", "[utypes][uni_atoi]" )
{
SECTION("int")
{
REQUIRE( uni_atoi("100") == 100 );
REQUIRE( uni_atoi("-100") == -100 );
REQUIRE( uni_atoi("0") == 0 );
REQUIRE( uni_atoi("-0") == 0 );
ostringstream imax;
imax << std::numeric_limits<int>::max();
REQUIRE( uni_atoi(imax.str()) == std::numeric_limits<int>::max() );
ostringstream imin;
imin << std::numeric_limits<int>::min();
REQUIRE( uni_atoi(imin.str()) == std::numeric_limits<int>::min() );
}
SECTION("unsigned int")
{
ostringstream imax;
imax << std::numeric_limits<unsigned int>::max();
unsigned int uint_max_val = (unsigned int)uni_atoi(imax.str());
REQUIRE( uint_max_val == std::numeric_limits<unsigned int>::max() );
ostringstream imin;
imax << std::numeric_limits<int>::min();
unsigned int uint_min_val = (unsigned int)uni_atoi(imin.str()); // "0"?
REQUIRE( uint_min_val == std::numeric_limits<unsigned int>::min() );
}
SECTION("hex")
{
REQUIRE( uni_atoi("0xff") == 0xff );
REQUIRE( uni_atoi("0xffff") == 0xffff );
REQUIRE( uni_atoi("0x0") == 0 );
REQUIRE( (unsigned int)uni_atoi("0xffffffff") == 0xffffffff );
REQUIRE( uni_atoi("0xfffffff8") == 0xfffffff8 );
}
WARN("Tests for 'UniSetTypes' incomplete...");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment