1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
# SPDX-FileCopyrightText: All Contributors to the PyTango project
# SPDX-License-Identifier: LGPL-3.0-or-later
import pickle
from enum import Enum
import pytest
from tango import (
ArchiveEventInfo,
AttrDataFormat,
AttributeAlarmInfo,
AttributeEventInfo,
AttributeInfo,
AttributeInfoEx,
AttrMemorizedType,
AttrWriteType,
ChangeEventInfo,
DevError,
DeviceAttributeConfig,
DevLong,
DispLevel,
ErrSeverity,
PeriodicEventInfo,
)
class StructType(Enum):
CHANGE_EVENT_INFO = 0
PERIOD_EVENT_INFO = 1
ARCHIVE_EVENT_INFO = 2
ATTRIBUTE_EVENT_INFO = 3
ATTRIBUTE_ALARM = 4
DEVICE_ATTRIBUTE_CONFIG = 5
ATTRIBUTE_INFO = 6
ATTRIBUTE_INFO_EX = 7
DEV_ERROR = 8
def get_struct(struct_type):
if struct_type == StructType.CHANGE_EVENT_INFO:
structure = ChangeEventInfo()
elif struct_type == StructType.PERIOD_EVENT_INFO:
structure = PeriodicEventInfo()
elif struct_type == StructType.ARCHIVE_EVENT_INFO:
structure = ArchiveEventInfo()
elif struct_type == StructType.ATTRIBUTE_EVENT_INFO:
structure = AttributeEventInfo()
structure.ch_event = get_struct(StructType.CHANGE_EVENT_INFO)
structure.per_event = get_struct(StructType.PERIOD_EVENT_INFO)
structure.arch_event = get_struct(StructType.ARCHIVE_EVENT_INFO)
return structure
elif struct_type == StructType.ATTRIBUTE_ALARM:
structure = AttributeAlarmInfo()
elif struct_type == StructType.DEVICE_ATTRIBUTE_CONFIG:
structure = DeviceAttributeConfig()
elif struct_type == StructType.ATTRIBUTE_INFO:
structure = AttributeInfo()
elif struct_type == StructType.ATTRIBUTE_INFO_EX:
structure = AttributeInfoEx()
structure.memorized = AttrMemorizedType.MEMORIZED_WRITE_INIT
structure.enum_labels = ["A", "BB", "CCC"]
structure.alarms = get_struct(StructType.ATTRIBUTE_ALARM)
structure.events = get_struct(StructType.ATTRIBUTE_EVENT_INFO)
structure.sys_extensions = ["ext4", "ext5", "ext6"]
elif struct_type == StructType.DEV_ERROR:
structure = DevError()
else:
raise RuntimeError("Unknown info type")
for member in dir(structure):
if not member.startswith("_") and isinstance(getattr(structure, member), str):
setattr(structure, member, member)
if struct_type in [
StructType.DEVICE_ATTRIBUTE_CONFIG,
StructType.ATTRIBUTE_INFO,
StructType.ATTRIBUTE_INFO_EX,
]:
structure.writable = AttrWriteType.READ_WRITE
structure.data_format = AttrDataFormat.SPECTRUM
structure.data_type = DevLong
structure.max_dim_x = 1
structure.max_dim_y = 2
if struct_type in [StructType.ATTRIBUTE_INFO, StructType.ATTRIBUTE_INFO_EX]:
structure.disp_level = DispLevel.EXPERT
if struct_type == StructType.DEV_ERROR:
structure.severity = ErrSeverity.WARN
else:
structure.extensions = ["ext1", "ext2", "ext3"]
return structure
def assert_struct(unpickled, struct_type=None):
if struct_type == StructType.ATTRIBUTE_EVENT_INFO:
assert_struct(unpickled.ch_event)
assert_struct(unpickled.per_event)
assert_struct(unpickled.arch_event)
return
for member in dir(unpickled):
if not member.startswith("_") and isinstance(getattr(unpickled, member), str):
assert (
getattr(unpickled, member) == member
), f"Mismatch in {member} field after unpickling."
if struct_type in [
StructType.DEVICE_ATTRIBUTE_CONFIG,
StructType.ATTRIBUTE_INFO,
StructType.ATTRIBUTE_INFO_EX,
]:
assert (
unpickled.writable == AttrWriteType.READ_WRITE
), "Mismatch in writable field after unpickling."
assert (
unpickled.data_format == AttrDataFormat.SPECTRUM
), "Mismatch in data_format field after unpickling."
assert (
unpickled.data_type == DevLong
), "Mismatch in data_type field after unpickling."
assert unpickled.max_dim_x == 1, "Mismatch in max_dim_x field after unpickling."
assert unpickled.max_dim_y == 2, "Mismatch in max_dim_y field after unpickling."
if struct_type in [StructType.ATTRIBUTE_INFO, StructType.ATTRIBUTE_INFO_EX]:
assert (
unpickled.disp_level == DispLevel.EXPERT
), "Mismatch in disp_level field after unpickling."
if struct_type == StructType.ATTRIBUTE_INFO_EX:
assert (
unpickled.memorized == AttrMemorizedType.MEMORIZED_WRITE_INIT
), "Mismatch in memorized field after unpickling."
assert unpickled.enum_labels == [
"A",
"BB",
"CCC",
], "Mismatch in enum_labels field after unpickling."
assert_struct(unpickled.alarms, StructType.ATTRIBUTE_ALARM)
assert_struct(unpickled.events, StructType.ATTRIBUTE_EVENT_INFO)
assert unpickled.sys_extensions == [
"ext4",
"ext5",
"ext6",
], "Mismatch in sys_extensions field after unpickling."
if struct_type == StructType.DEV_ERROR:
assert unpickled.severity == ErrSeverity.WARN
else:
assert unpickled.extensions == [
"ext1",
"ext2",
"ext3",
], "Mismatch in 'extensions' field after unpickling."
@pytest.mark.parametrize("structure_type", StructType)
def test_structure_pickle(structure_type):
# Step 1: Create an instance of structure
original = get_struct(structure_type)
# Step 2: Pickle the structure instance
try:
pickled_data = pickle.dumps(original)
except Exception as e:
pytest.fail(f"Pickling failed with exception: {e}")
# Step 3: Unpickle the data back to a structure instance
try:
unpickled = pickle.loads(pickled_data)
except Exception as e:
pytest.fail(f"Unpickling failed with exception: {e}")
# Step 4: Assert that all fields are equal
assert_struct(unpickled, structure_type)
|