Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

9.3 backport to fix #330 #681

Merged
merged 8 commits into from
Mar 18, 2020
12 changes: 10 additions & 2 deletions cpp_test_suite/cpp_test_ds/DevTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ void DevTest::init_device()
Short_attr_except = false;
if (tg->is_svr_starting() == true || tg->is_device_restarting(device_name) == true)
Short_attr_w_except = false;
Long_attr_except = false;
event_change_attr_except = false;
event_quality_attr_except = false;
event_throw_out_of_sync = false;
Expand Down Expand Up @@ -1281,8 +1282,15 @@ void DevTest::read_Short_attr(Tango::Attribute &att)

void DevTest::read_Long_attr(Tango::Attribute &att)
{
cout << "[DevTest::read_attr] attribute name Long_attr" << endl;
att.set_value(&attr_long);
cout << "[DevTest::read_attr] attribute name Long_attr" << std::endl;
if (Long_attr_except)
{
Tango::Except::throw_exception(
"Long_attr_except",
"Test exception is enabled for this attribute",
"DevTest::read_Long_attr");
}
att.set_value(&attr_long);
}

void DevTest::read_Long64_attr(Tango::Attribute &att)
Expand Down
1 change: 1 addition & 0 deletions cpp_test_suite/cpp_test_ds/DevTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ protected :

bool Short_attr_except;
bool Short_attr_w_except;
bool Long_attr_except;
bool event_change_attr_except;
bool event_quality_attr_except;
bool event_throw_out_of_sync;
Expand Down
52 changes: 17 additions & 35 deletions cpp_test_suite/cpp_test_ds/IOMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,41 +665,23 @@ CORBA::Any *IOAttrThrowEx::execute(Tango::DeviceImpl *device, const CORBA::Any &
const Tango::DevVarShortArray *in;
extract(in_any, in);

if ((*in)[0] == 0)
{
if ((*in)[1] == 0)
(static_cast<DevTest *>(device))->Short_attr_except = false;
else
(static_cast<DevTest *>(device))->Short_attr_except = true;
}
else if ((*in)[0] == 1)
{
if ((*in)[1] == 0)
(static_cast<DevTest *>(device))->event_change_attr_except = false;
else
(static_cast<DevTest *>(device))->event_change_attr_except = true;
}
else if ((*in)[0] == 2)
{
if ((*in)[1] == 0)
(static_cast<DevTest *>(device))->event_quality_attr_except = false;
else
(static_cast<DevTest *>(device))->event_quality_attr_except = true;
}
else if ((*in)[0] == 3)
{
if ((*in)[1] == 0)
(static_cast<DevTest *>(device))->event_throw_out_of_sync = false;
else
(static_cast<DevTest *>(device))->event_throw_out_of_sync = true;
}
else if ((*in)[0] == 4)
{
if ((*in)[1] == 0)
(static_cast<DevTest *>(device))->Short_attr_w_except = false;
else
(static_cast<DevTest *>(device))->Short_attr_w_except = true;
}
DevTest& dev = static_cast<DevTest&>(*device);

const int flag_disc = (*in)[0];
const bool flag_value = (*in)[1];
bool default_flag = false;

bool& flag =
(flag_disc == 0) ? dev.Short_attr_except :
(flag_disc == 1) ? dev.event_change_attr_except :
(flag_disc == 2) ? dev.event_quality_attr_except :
(flag_disc == 3) ? dev.event_throw_out_of_sync :
(flag_disc == 4) ? dev.Short_attr_w_except :
(flag_disc == 5) ? dev.Long_attr_except :
default_flag;

flag = flag_value;

return insert();
}

Expand Down
4 changes: 0 additions & 4 deletions cpp_test_suite/cpp_test_ds/TypeCmds.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#include "TypeCmds.h"

#define DEV_DEBUG_STREAM(dev) \
if (dev->get_logger()->is_debug_enabled())\
dev->get_logger()->debug_stream()

//+----------------------------------------------------------------------------
//
// method : IOVoid::IOVoid()
Expand Down
57 changes: 57 additions & 0 deletions cpp_test_suite/new_tests/cxx_attr_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,63 @@ cout << "status = " << status << endl;
dout >> status;
TS_ASSERT(strcmp(status,"The device is in ON state.") == 0);
}

void set_Long_attr_value(DevLong value)
{
DeviceData input;
input << value;
TS_ASSERT_THROWS_NOTHING(device1->command_inout("IOSetAttr", input));
}

void set_attribute_exception_flag(short attribute_disc, bool enabled)
{
std::vector<short> flags(2);
flags[0] = attribute_disc;
flags[1] = enabled ? 1 : 0;
DeviceData data;
data << flags;
TS_ASSERT_THROWS_NOTHING(device1->command_inout("IOAttrThrowEx", data));
}

void __assert_dev_state(DevState expected, const char* file, const char* line)
{
std::string message = std::string("Called from ") + file + ":" + line;

DevState state;
DeviceData data;
TSM_ASSERT_THROWS_NOTHING(message, data = device1->command_inout("State"));
data >> state;
TSM_ASSERT_EQUALS(message, expected, state);
}

#define __QUOTE(x) #x
#define QUOTE(x) __QUOTE(x)
#define assert_dev_state(expected) __assert_dev_state(expected, __FILE__, QUOTE(__LINE__))

// Verifies that device state is set correctly when alarm is configured for an attribute
// but no value is provided for this attribute in user callback (e.g. an exception is thrown).

void test_alarm_on_attribute_exception_during_read(void)
{
const short EXCEPTION_IN_Long_attr = 5;

set_Long_attr_value(2000);
assert_dev_state(Tango::ALARM);

set_attribute_exception_flag(EXCEPTION_IN_Long_attr, true);
assert_dev_state(Tango::ON);

set_attribute_exception_flag(EXCEPTION_IN_Long_attr, false);
assert_dev_state(Tango::ALARM);

set_Long_attr_value(1200);
assert_dev_state(Tango::ON);
}

#undef assert_dev_state
#undef QUOTE
#undef __QUOTE

};
#undef cout
#endif // AttrMiscTestSuite_h
136 changes: 52 additions & 84 deletions cppapi/server/attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2865,54 +2865,67 @@ void Attribute::delete_seq()
case Tango::DEV_SHORT:
case Tango::DEV_ENUM:
delete value.sh_seq;
value.sh_seq = Tango_nullptr;
break;

case Tango::DEV_LONG:
delete value.lg_seq;
value.lg_seq = Tango_nullptr;
break;

case Tango::DEV_LONG64:
delete value.lg64_seq;
value.lg64_seq = Tango_nullptr;
break;

case Tango::DEV_DOUBLE:
delete value.db_seq;
value.db_seq = Tango_nullptr;
break;

case Tango::DEV_STRING:
delete value.str_seq;
value.str_seq = Tango_nullptr;
break;

case Tango::DEV_FLOAT:
delete value.fl_seq;
value.fl_seq = Tango_nullptr;
break;

case Tango::DEV_USHORT:
delete value.ush_seq;
value.ush_seq = Tango_nullptr;
break;

case Tango::DEV_UCHAR:
delete value.cha_seq;
value.cha_seq = Tango_nullptr;
break;

case Tango::DEV_BOOLEAN:
delete value.boo_seq;
value.boo_seq = Tango_nullptr;
break;

case Tango::DEV_ULONG:
delete value.ulg_seq;
value.ulg_seq = Tango_nullptr;
break;

case Tango::DEV_ULONG64:
delete value.ulg64_seq;
value.ulg64_seq = Tango_nullptr;
break;

case Tango::DEV_STATE:
delete value.state_seq;
value.state_seq = Tango_nullptr;
break;

case Tango::DEV_ENCODED:
delete value.enc_seq;
value.enc_seq = Tango_nullptr;
break;
}
}
Expand Down Expand Up @@ -5362,109 +5375,64 @@ void Attribute::log_quality()
dev = tg->get_device_by_name(d_name);
}

//
// Log something if the new quality is different than the old one
//
const bool has_quality_changed = quality != old_quality;
const bool has_alarm_changed = alarm != old_alarm;
const bool is_alarm_set = alarm.any();

if (quality != old_quality)
if (has_quality_changed)
{
if (alarm.any() == false)
if (! is_alarm_set)
{

//
// No alarm detected
//

switch(quality)
switch (quality)
{
case ATTR_INVALID:
if (dev->get_logger()->is_error_enabled())
dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "INVALID quality for attribute " << name << endl;
case ATTR_INVALID:
DEV_ERROR_STREAM(dev) << "INVALID quality for attribute " << name << std::endl;
break;

case ATTR_CHANGING:
if (dev->get_logger()->is_info_enabled())
dev->get_logger()->info_stream() << log4tango::LogInitiator::_begin_log << "CHANGING quality for attribute " << name << endl;
case ATTR_CHANGING:
DEV_INFO_STREAM(dev) << "CHANGING quality for attribute " << name << std::endl;
break;

case ATTR_VALID:
if (dev->get_logger()->is_info_enabled())
dev->get_logger()->info_stream() << log4tango::LogInitiator::_begin_log << "VALID quality for attribute " << name << endl;
case ATTR_VALID:
DEV_INFO_STREAM(dev) << "INFO quality for attribute " << name << std::endl;
break;

default:
default:
break;
}
}
else
{

//
// Different log according to which alarm is set
//

if (alarm[min_level] == true)
{
if (dev->get_logger()->is_error_enabled())
dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MIN ALARM for attribute " << name << endl;
}
else if (alarm[max_level] == true)
{
if (dev->get_logger()->is_error_enabled())
dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MAX ALARM for attribute " << name << endl;
}
else if (alarm[rds] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "RDS (Read Different Set) ALARM for attribute " << name << endl;
}
else if (alarm[min_warn] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MIN WARNING for attribute " << name << endl;
}
else if (alarm[max_warn] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MAX WARNING for attribute " << name << endl;
}
log_alarm_quality();
}
}
else
else if (has_alarm_changed)
{
log_alarm_quality();
}
}

//
// The quality is the same but may be the alarm has changed
//

if (alarm != old_alarm)
{
if (alarm[min_level] == true)
{
if (dev->get_logger()->is_error_enabled())
dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MIN ALARM for attribute " << name << endl;
}
else if (alarm[max_level] == true)
{
if (dev->get_logger()->is_error_enabled())
dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MAX ALARM for attribute " << name << endl;
}
else if (alarm[rds] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "RDS (Read Different Set) ALARM for attribute " << name << endl;
}
else if (alarm[min_warn] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MIN WARNING for attribute " << name << endl;
}
else if (alarm[max_warn] == true)
{
if (dev->get_logger()->is_warn_enabled())
dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MAX WARNING for attribute " << name << endl;
}
}
void Attribute::log_alarm_quality() const
{
if (alarm[min_level])
{
DEV_ERROR_STREAM(dev) << "MIN ALARM for attribute " << name << std::endl;
}
else if (alarm[max_level])
{
DEV_ERROR_STREAM(dev) << "MAX ALARM for attribute " << name << std::endl;
}
else if (alarm[rds])
{
DEV_WARN_STREAM(dev) << "RDS (Read Different Set) ALARM for attribute " << name << std::endl;
}
else if (alarm[min_warn])
{
DEV_WARN_STREAM(dev) << "MIN WARNING for attribute " << name << std::endl;
}
else if (alarm[max_warn])
{
DEV_WARN_STREAM(dev) << "MAX WARNING for attribute " << name << std::endl;
}
}

Expand Down
1 change: 1 addition & 0 deletions cppapi/server/attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,7 @@ class Attribute
void set_data_size();
void throw_min_max_value(string &,string &,MinMaxValueCheck);
void log_quality();
void log_alarm_quality() const;

inline void init_string_prop(vector<AttrProperty> &prop_list, string& attr, const char* attr_name)
{
Expand Down
Loading