# coding: utf-8
from __future__ import print_function
from __future__ import absolute_import
import unittest
import datetime
from math import isclose
from lxml import etree as etree_
import copy
import sdc11073.mdib.statecontainers as statecontainers
import sdc11073.mdib.descriptorcontainers as descriptorcontainers
import sdc11073.namespaces as namespaces
import sdc11073.pmtypes as pmtypes
import sdc11073.xmlparsing as xmlparsing
import sdc11073.mdib.containerproperties as containerproperties
from sdc11073.location import SdcLocation
from sdc11073.definitions_sdc import SDC_v1_Definitions

#pylint: disable=protected-access

class TestStateContainers(unittest.TestCase):

    def setUp(self):
        self.nsmapper = namespaces.DocNamespaceHelper()
        self.dc = descriptorcontainers.AbstractDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        self.dc.DescriptorVersion = 42


    def test_AbstractStateContainer(self):
        sc = statecontainers.AbstractStateContainer(nsmapper=self.nsmapper, 
                                                    descriptorContainer=self.dc, 
                                                    node=None)
        # constructor shall create a node
        self.assertEqual(sc.nodeName, namespaces.domTag('State'))

        #initially the state version shall be 0, and DescriptorVersion shall be set
        self.assertEqual(sc.StateVersion, 0)
        self.assertEqual(sc.DescriptorVersion, self.dc.DescriptorVersion)
        
        # verify that mkStateNode() also updates changed Descriptorversion
        self.dc.DescriptorVersion +=1
        sc.mkStateNode()
        self.assertEqual(sc.DescriptorVersion, self.dc.DescriptorVersion)

        # verify incrementState works ay expected
        sc.incrementState()
        self.assertEqual(sc.StateVersion, 1)
        node = sc.mkStateNode()
        self.assertEqual(node.get('StateVersion'), '1')
        
        # test updateFromNode
        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'2',
                                      'DescriptorHandle': self.dc.handle})
        sc.updateFromNode(node)
        self.assertEqual(sc.StateVersion, 2)
        self.assertEqual(sc.node.get('StateVersion'), '2')
        
        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'3',
                                      'DescriptorHandle':'something_completely_different'})
        self.assertRaises(RuntimeError, sc.updateFromNode, node)

        #test creation from node
        sc2 = statecontainers.AbstractStateContainer(nsmapper=self.nsmapper, 
                                                     descriptorContainer=self.dc, 
                                                     node=copy.deepcopy(sc.node)) # sc2 might change node, therfore give it a deep copy
        self._verifyAbstractStateContainerDataEqual(sc, sc2)
        
        # test update from Node
        sc.DescriptorVersion += 1 
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def _verifyAbstractStateContainerDataEqual(self, sc1, sc2):
        self.assertEqual(sc1.DescriptorVersion, sc2.DescriptorVersion)
        self.assertEqual(sc1.StateVersion, sc2.StateVersion)
        self.assertEqual(sc1.nodeName, sc2.nodeName)


    def test_AbstractOperationStateContainer(self):
        sc = statecontainers.AbstractOperationStateContainer(nsmapper=self.nsmapper, 
                                                    descriptorContainer=self.dc, 
                                                    node=None)
        self.assertIsNotNone(sc.OperatingMode) # this is a required attribute
        
        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractOperationStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=self.dc, 
                                                          node=node)
        self.assertIsNotNone(sc2.OperatingMode)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)

        #test update from node
        sc.OperatingMode = pmtypes.OperatingMode.NA
        self.assertEqual(sc.OperatingMode, pmtypes.OperatingMode.NA)
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc2.OperatingMode, pmtypes.OperatingMode.NA)



    def test_AbstractMetricStateContainer_Final(self):
        dc = descriptorcontainers.NumericMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=dc,
                                                            node=None)

        self.assertEqual(sc.ActivationState, 'On')
        for value in ('foo', 'bar'):
            sc.ActivationState = value
            self.assertEqual(sc.ActivationState, value)
            node = sc.mkStateNode()
            self.assertEqual(node.get('ActivationState'), value)

        self.assertEqual(sc.ActiveDeterminationPeriod, None)
        for value in (21, 42):
            sc.ActiveDeterminationPeriod = value
            self.assertEqual(sc.ActiveDeterminationPeriod, value)
            node = sc.mkStateNode()
            self.assertEqual(node.get('ActiveDeterminationPeriod'),
                             containerproperties.DurationConverter.toXML(value))
        sc.BodySite = [pmtypes.CodedValue('ABC')]
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('ABC')], 1)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                          descriptorContainer=dc,
                                                          node=node)
        self.assertEqual(sc.ActivationState, sc2.ActivationState)
        self.assertEqual(sc.ActiveDeterminationPeriod, sc2.ActiveDeterminationPeriod)
        self.assertEqual(sc.BodySite, sc2.BodySite)
        self.assertEqual(sc.PhysicalConnector, sc2.PhysicalConnector)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)

        # test update from Node
        sc.ActivationState = 'something else'
        sc.ActiveDeterminationPeriod += 1
        sc.BodySite = [pmtypes.CodedValue('DEF')]
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('DEF')], 2)
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc.ActivationState, sc2.ActivationState)
        self.assertEqual(sc.BodySite, sc2.BodySite)
        self.assertEqual(sc.PhysicalConnector, sc2.PhysicalConnector)
        self.assertEqual(sc.ActiveDeterminationPeriod, sc2.ActiveDeterminationPeriod)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def test_NumericMetricStateContainer(self):
        dc = descriptorcontainers.NumericMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                    descriptorContainer=dc,
                                                    node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.NumericMetricValue))
        sc.metricValue.Value = 42.21
        sc.metricValue.StartTime = 1234567.21
        sc.metricValue.StopTime = sc.metricValue.StartTime +10
        sc.metricValue.DeterminationTime = sc.metricValue.StartTime +20
        sc.metricValue.Validity = 'Vld'
        sc.ActiveAveragingPeriod = 42
        sc.PhysiologicalRange = [pmtypes.Range(1, 2, 3, 4, 5), pmtypes.Range(10, 20, 30, 40, 50)]
        node = sc.mkStateNode()
        
        #test creation from node
        sc2 = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=dc,
                                                          node=node)
        # verify also that mkStateNode on receiving sc does not change anything
        for dummy in range(1):
            self.assertTrue(isclose(sc.metricValue.Value, sc2.metricValue.Value))
            self.assertEqual(sc.metricValue.StartTime, sc2.metricValue.StartTime)
            self.assertEqual(sc.metricValue.StopTime, sc2.metricValue.StopTime)
            self.assertEqual(sc.metricValue.DeterminationTime, sc2.metricValue.DeterminationTime)
            self.assertEqual(sc.metricValue.Validity, sc2.metricValue.Validity)
            self.assertEqual(sc.ActiveAveragingPeriod, sc2.ActiveAveragingPeriod)
            self.assertEqual(sc.PhysiologicalRange, sc2.PhysiologicalRange)
            
            self._verifyAbstractStateContainerDataEqual(sc, sc2)
            sc.mkStateNode()

        #test update from node
        sc.metricValue.Value += 1
        sc.incrementState()
        sc.ActiveAveragingPeriod = 24
        sc.PhysiologicalRange[1].Lower =100
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertTrue(isclose(sc.metricValue.Value, sc2.metricValue.Value))
        self.assertEqual(sc.ActiveAveragingPeriod, sc2.ActiveAveragingPeriod)
        self.assertEqual(sc.PhysiologicalRange, sc2.PhysiologicalRange)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def test_StringMetricStateContainer(self):
        dc = descriptorcontainers.StringMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.StringMetricStateContainer(nsmapper=self.nsmapper,
                                                    descriptorContainer=dc,
                                                    node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.StringMetricValue))


    def test_EnumStringMetricStateContainer(self):
        dc = descriptorcontainers.EnumStringMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')

        sc = statecontainers.EnumStringMetricStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=dc,
                                                            node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.StringMetricValue))


    def test_RealTimeSampleArrayMetricStateContainer(self):
        dc = descriptorcontainers.RealTimeSampleArrayMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                               nodeName='MyDescriptor',
                                                                               handle='123',
                                                                               parentHandle='456')

        def verifyEqual(origin, copied):
            self.assertEqual(len(copied.metricValue.Samples), len(origin.metricValue.Samples))
            for c, o in zip(copied.metricValue.Samples, origin.metricValue.Samples):
                self.assertTrue((isclose(c, o)))
            self.assertEqual(copied.metricValue.DeterminationTime, origin.metricValue.DeterminationTime)
            self.assertEqual(copied.metricValue.Annotation, origin.metricValue.Annotation)
            self.assertEqual(copied.metricValue.ApplyAnnotations, origin.metricValue.ApplyAnnotations)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.RealTimeSampleArrayMetricStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=dc,
                                                                     node=None)
        sc.mkMetricValue()
        self.assertEqual(sc.nodeName, namespaces.domTag('State'))
        self.assertTrue(isinstance(sc.metricValue, pmtypes.SampleArrayValue))
        
        sc.metricValue.Samples = [1,2,3,4,5.5]
        sc.metricValue.DeterminationTime = 1234567
        sc.metricValue.Annotations = []
        sc.metricValue.ApplyAnnotations = []
        sc.ActivationState = 'act'

        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.RealTimeSampleArrayMetricStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=dc,
                                                                     node=node)
        verifyEqual(sc, sc2)
        
        #test update from node
        sc.metricValue.Samples = [5.5, 6.6]
        sc.metricValue.DeterminationTime = 2345678
        sc.metricValue.Annotations = [pmtypes.Annotation(pmtypes.CodedValue('a','b'))]
        sc.metricValue.ApplyAnnotations = [pmtypes.ApplyAnnotation(1,2)]

        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_AbstractDeviceComponentStateContainer_Final(self):

        def verifyEqual(origin, copied):
            self.assertEqual(copied.ActivationState, origin.ActivationState)
            self.assertEqual(copied.OperatingHours, origin.OperatingHours)
            self.assertEqual(copied.OperatingCycles, origin.OperatingCycles)
            self.assertEqual(copied.PhysicalConnector, origin.PhysicalConnector)
            self._verifyAbstractStateContainerDataEqual(copied, origin)

        sc = statecontainers.AbstractDeviceComponentStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        self.assertEqual(sc.ActivationState, None)
        self.assertEqual(sc.OperatingHours, None)
        self.assertEqual(sc.OperatingCycles, None)
        self.assertEqual(sc.PhysicalConnector, None)

        sc.ActivationState = 'On'
        sc.OperatingHours = 2.3
        sc.OperatingHours = 4
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('ABC')], 1)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractDeviceComponentStateContainer(nsmapper=self.nsmapper,
                                                                    descriptorContainer=self.dc,
                                                                    node=node)
        verifyEqual(sc, sc2)

        sc.ActivationState = 'Off'
        sc.OperatingHours += 1
        sc.OperatingHours += 1
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('DEF')], 2)
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_MdsStateContainer(self):
        pass


    def test_VmdStateContainer(self):
        pass


    def test_ChannelStateContainer(self):
        pass


    def test_ClockStateContainer(self):
        pass


    def test_AbstractAlertStateContainer(self):
        pass



    def test_AlertSystemStateContainer_final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.SystemSignalActivation, origin.SystemSignalActivation)
            self.assertEqual(copied.LastSelfCheck, origin.LastSelfCheck)
            self.assertEqual(copied.SelfCheckCount, origin.SelfCheckCount)
            self.assertEqual(copied.PresentPhysiologicalAlarmConditions, origin.PresentPhysiologicalAlarmConditions)
            self.assertEqual(copied.PresentTechnicalAlarmConditions, origin.PresentTechnicalAlarmConditions)
            self._verifyAbstractStateContainerDataEqual(copied, origin)

        sc = statecontainers.AlertSystemStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        self.assertEqual(sc.SystemSignalActivation, [])
        self.assertEqual(sc.LastSelfCheck, None)
        self.assertEqual(sc.SelfCheckCount, None)
        self.assertEqual(sc.PresentPhysiologicalAlarmConditions, [])
        self.assertEqual(sc.PresentTechnicalAlarmConditions, [])

        #test creation from node
        sc.SystemSignalActivation = [pmtypes.SystemSignalActivation(manifestation=pmtypes.AlertSignalManifestation.AUD,
                                                                    state=pmtypes.AlertActivation.ON),
                                     pmtypes.SystemSignalActivation(manifestation=pmtypes.AlertSignalManifestation.VIS,
                                                                    state=pmtypes.AlertActivation.ON)
                                     ]
        sc.LastSelfCheck = 1234567
        sc.SelfCheckCount = 3
        sc.PresentPhysiologicalAlarmConditions = ["handle1", "handle2", "handle3"]
        sc.incrementState()
        node = sc.mkStateNode()
        sc2 = statecontainers.AlertSystemStateContainer(nsmapper=self.nsmapper,
                                                                    descriptorContainer=self.dc,
                                                                    node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.LastSelfCheck = 12345678
        sc.SelfCheckCount = 4
        sc.PresentPhysiologicalAlarmConditions = ["handle2", "handle3", "handle4"]
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_AlertConditionStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.ActualPriority, origin.ActualPriority)
            self.assertEqual(copied.Rank, origin.Rank)
            self.assertEqual(copied.DeterminationTime, origin.DeterminationTime)
            self.assertEqual(copied.Presence, origin.Presence)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
            
        sc = statecontainers.AlertConditionStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=self.dc, 
                                                          node=None)
        self.assertEqual(sc.ActualPriority, None)
        self.assertEqual(sc.Rank, None)
        self.assertEqual(sc.DeterminationTime, None)
        self.assertEqual(sc.Presence, False)

        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AlertConditionStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.ActualPriority = 'lo'
        sc.Rank = 3
        sc.DeterminationTime = 1234567
        sc.Presence = True
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_LimitAlertConditionStateContainer_Final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Limits, origin.Limits)
            self.assertEqual(copied.MonitoredAlertLimits, origin.MonitoredAlertLimits)
            self.assertEqual(copied.AutoLimitActivationState, origin.AutoLimitActivationState)
            self._verifyAbstractStateContainerDataEqual(copied, origin)


        sc = statecontainers.LimitAlertConditionStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=self.dc,
                                                            node=None)
        self.assertEqual(sc.MonitoredAlertLimits, pmtypes.AlertConditionMonitoredLimits.ALL_OFF)
        self.assertEqual(sc.AutoLimitActivationState, None)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.LimitAlertConditionStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        verifyEqual(sc, sc2)

        # test update from node
        sc.Limits = pmtypes.Range(lower=5, upper=9, stepWidth=0.1, relativeAccuracy=0.01, absoluteAccuracy=0.001)
        sc.Rank = 3
        sc.DeterminationTime = 1234567
        sc.Presence = True
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)



    def test_SetStringOperationStateContainer_Final(self):
        sc = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        # verify that initial pyValue is an empty list, and that no AllowedValues node is created
        self.assertEqual(sc.AllowedValues, [])
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)

        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=copy.deepcopy(sc.node))
        self.assertEqual(sc2.AllowedValues, [])

        # verify that setting to None is identical to empty list
        sc.AllowedValues = None
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)

        # verify that non-empty list creates values in xml and that same list appears in container created from that xml
        sc.AllowedValues = ['a', 'b', 'c']
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 1)
        valuesNodes = node.xpath('//dom:Value', namespaces=namespaces.nsmap)
        self.assertEqual(len(valuesNodes), 3)
        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        self.assertEqual(sc2.AllowedValues, ['a', 'b', 'c'])

        # verify that setting it back to None clears all data
        sc.AllowedValues = None
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)
        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        self.assertEqual(sc2.AllowedValues, [])


    def test_AbstractMultiStateContainer(self):
        pass


    def test_AbstractContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.ContextAssociation, origin.ContextAssociation)
            self.assertEqual(copied.BindingMdibVersion, origin.BindingMdibVersion)
            self.assertEqual(copied.UnbindingMdibVersion, origin.UnbindingMdibVersion)
            self.assertEqual(copied.BindingStartTime, origin.BindingStartTime)
            self.assertEqual(copied.BindingEndTime, origin.BindingEndTime)
            self.assertEqual(copied.Validator, origin.Validator)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.AbstractContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        self.assertEqual(sc.ContextAssociation, 'No')
        self.assertEqual(sc.BindingMdibVersion, None)
        self.assertEqual(sc.UnbindingMdibVersion, None)
        self.assertEqual(sc.BindingStartTime, None)
        self.assertEqual(sc.BindingEndTime, None)
        self.assertEqual(sc.Validator, [])
        self.assertEqual(sc.Identification, [])

        idents = [pmtypes.InstanceIdentifier(root='abc', 
                                             type_codedValue=pmtypes.CodedValue('abc','def'), 
                                             identifierNames=[pmtypes.LocalizedText('ABC')], 
                                             extensionString='123')]
        sc.Identification = idents
        self.assertEqual(sc.Identification, idents)

        validators = [pmtypes.InstanceIdentifier(root='ABC', 
                                                 type_codedValue=pmtypes.CodedValue('123','456'), 
                                                 identifierNames=[pmtypes.LocalizedText('DEF')], 
                                                 extensionString='321')]
        sc.Validator = validators
        self.assertEqual(sc.Validator, validators)
        
        for value in ('assoc', 'disassoc'):
            sc.ContextAssociation = value
            node = sc.mkStateNode()
            self.assertEqual(node.get('ContextAssociation'), value)
            
        for value in (12345.123, 67890.987):
            sc.BindingStartTime = value
            sc.BindingEndTime = value+1
            node = sc.mkStateNode()
            self.assertEqual(node.get('BindingStartTime'), containerproperties.TimestampConverter.toXML(value))
            self.assertEqual(node.get('BindingEndTime'), containerproperties.TimestampConverter.toXML(value+1))

        for value in (0, 42, 123):
            sc.BindingMdibVersion = value
            sc.UnbindingMdibVersion = value+1
            node = sc.mkStateNode()
            self.assertEqual(node.get('BindingMdibVersion'), containerproperties.IntegerConverter.toXML(value))
            self.assertEqual(node.get('UnbindingMdibVersion'), containerproperties.IntegerConverter.toXML(value+1))

        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'2',
                                      'DescriptorHandle':'123',
                                      'BindingStartTime':'1234567',
                                      'BindingEndTime':'2345678',
                                      'Handle':sc.Handle})
        sc.updateFromNode(node)
        self.assertEqual(sc.BindingStartTime, 1234.567)
        self.assertEqual(sc.BindingEndTime, 2345.678)
        self.assertEqual(sc.node.get('BindingStartTime'), '1234567')
        self.assertEqual(sc.node.get('BindingEndTime'), '2345678')
        self.assertEqual(sc.Identification, [])
        self.assertEqual(sc.Validator, [])
        
        #test creation from node
        sc.Identification = idents
        sc.Validator = validators
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractContextStateContainer(nsmapper=self.nsmapper,
                                                                     descriptorContainer=self.dc, 
                                                                     node=node)
        verifyEqual(sc, sc2)


    def test_LocationContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.PoC, origin.PoC)
            self.assertEqual(copied.Room, origin.Room)
            self.assertEqual(copied.Bed, origin.Bed)
            self.assertEqual(copied.Facility, origin.Facility)
            self.assertEqual(copied.Building, origin.Building)
            self.assertEqual(copied.Floor, origin.Floor)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
            
        sc = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        
        self.assertTrue(sc.Handle is not None)
        self.assertEqual(sc.PoC, None)
        self.assertEqual(sc.Room, None)
        self.assertEqual(sc.Bed, None)
        self.assertEqual(sc.Facility, None)
        self.assertEqual(sc.Building, None)
        self.assertEqual(sc.Floor, None)

        #test creation from empty node
        node = sc.mkStateNode()
        self.assertEqual(node.get('Handle'), sc.Handle)
        print (etree_.tostring(node, pretty_print=True))
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)
        
        sc.Handle = 'xyz'
        sc.PoC = 'a'
        sc.Room = 'b'
        sc.Bed = 'c'
        sc.Facility = 'd'
        sc.Building = 'e'
        sc.Floor = 'f'
        
        #test creation from non-empty node
        node = sc.mkStateNode()
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=self.dc, 
                                                                     node=node)
        verifyEqual(sc, sc2)
        sc.PoC = 'aa'
        sc.Room = 'bb'
        sc.Bed = 'cc'
        sc.Facility = 'dd'
        sc.Building = 'ee'
        sc.Floor = 'ff'
        
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)

        loc = SdcLocation(fac='a', poc='b', bed='c', bld='d', flr='e', rm='f', root='g')
        bicepsSchema = xmlparsing.BicepsSchema(SDC_v1_Definitions)
        sc = statecontainers.LocationContextStateContainer.fromSdcLocation(nsmapper=self.nsmapper,
                                                                           descriptorContainer=self.dc, 
                                                                           handle='abc', 
                                                                           sdc_location=loc,
                                                                           bicepsSchema=bicepsSchema)
        self.assertEqual(sc.Handle, 'abc')
        self.assertEqual(sc.PoC, 'b')
        self.assertEqual(sc.Room, 'f')
        self.assertEqual(sc.Bed, 'c')
        self.assertEqual(sc.Facility, 'a')
        self.assertEqual(sc.Building, 'd')
        self.assertEqual(sc.Floor, 'e')

        #test creation from non-empty node
        node = sc.mkStateNode()
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)
        
        #Umlaut test
        dr = SdcLocation(fac=u'Dräger', poc=u'b', bed=u'c', bld=u'd', flr=u'e', rm=u'f', root=u'g')
        sc3 = statecontainers.LocationContextStateContainer.fromSdcLocation(nsmapper=self.nsmapper,
                                                                           descriptorContainer=self.dc, 
                                                                           handle='abc', 
                                                                           sdc_location=loc,
                                                                           bicepsSchema=bicepsSchema)
        sc2.updateFromSdcLocation(loc, bicepsSchema)
        verifyEqual(sc3, sc2)


    def test_PatientContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.Givenname, origin.Givenname)
            self.assertEqual(copied.Middlename, origin.Middlename)
            self.assertEqual(copied.Familyname, origin.Familyname)
            self.assertEqual(copied.DateOfBirth, origin.DateOfBirth)
            self.assertEqual(copied.Height, origin.Height)
            self.assertEqual(copied.Weight, origin.Weight)
            self.assertEqual(copied.Race, origin.Race)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        sc.Identification.append(pmtypes.InstanceIdentifier('abc', pmtypes.CodedValue('123'), [pmtypes.LocalizedText('Peter', 'en'),
                                                                                               pmtypes.LocalizedText('Paul'),
                                                                                               pmtypes.LocalizedText('Mary')]))
        sc.Identification.append(pmtypes.InstanceIdentifier('def', pmtypes.CodedValue('456'), [pmtypes.LocalizedText('John'),
                                                                                               pmtypes.LocalizedText('Jim'),
                                                                                               pmtypes.LocalizedText('Jane')]))
        self.assertTrue(sc.Handle is not None)
        sc.Givenname = 'Karl'
        sc.Middlename = 'M.'
        sc.Familyname = 'Klammer'
        sc.Height = pmtypes.Measurement(88.2, pmtypes.CodedValue('abc', 'def'))
        sc.Weight = pmtypes.Measurement(68.2, pmtypes.CodedValue('abc'))
        sc.Race = pmtypes.CodedValue('123', 'def')

        sc.DateOfBirth = datetime.date(2001, 3, 12)
        print (sc.DateOfBirth)
        
        #test creation from node
        node = sc.mkStateNode()
        print (etree_.tostring(node, pretty_print=True).decode('utf-8'))
        sc2 = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.Middlename = 'K.'
        sc.DateOfBirth = datetime.datetime(2001, 3, 12, 14, 30, 1)
        sc.incrementState()
        sc.Height._value =42
        sc.Weight._value =420
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_PatientContextStateContainer_final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.Givenname, origin.Givenname)
            self.assertEqual(copied.Middlename, origin.Middlename)
            self.assertEqual(copied.Familyname, origin.Familyname)
            self.assertEqual(copied.DateOfBirth, origin.DateOfBirth)
            self.assertEqual(copied.Height, origin.Height)
            self.assertEqual(copied.Weight, origin.Weight)
            self.assertEqual(copied.Race, origin.Race)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper,
                                                                        descriptorContainer=self.dc,
                                                                        node=None)

        self.assertTrue(sc.Handle is not None)

        sc.Givenname = 'Karl'
        sc.Middlename = 'M.'
        sc.Familyname = 'Klammer'
        sc.Height = pmtypes.Measurement(88.2, pmtypes.CodedValue('abc', 'def'))
        sc.Weight = pmtypes.Measurement(68.2, pmtypes.CodedValue('abc'))
        sc.Race = pmtypes.CodedValue('123', 'def')

        sc.DateOfBirth = datetime.date(2001, 3, 12)
        print (sc.DateOfBirth)

        sc.Identification.append(pmtypes.InstanceIdentifier('abc', pmtypes.CodedValue('123'), [pmtypes.LocalizedText('Peter', 'en'),
                                                                                               pmtypes.LocalizedText('Paul'),
                                                                                               pmtypes.LocalizedText('Mary')]))
        sc.Identification.append(pmtypes.InstanceIdentifier('def', pmtypes.CodedValue('456'), [pmtypes.LocalizedText('John'),
                                                                                               pmtypes.LocalizedText('Jim'),
                                                                                               pmtypes.LocalizedText('Jane')]))

        #test creation from node
        node = sc.mkStateNode()
        print (etree_.tostring(node, pretty_print=True))
        sc2 = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper,
                                                                         descriptorContainer=self.dc,
                                                                         node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.Middlename = 'K.'
        sc.DateOfBirth = datetime.datetime(2001, 3, 12, 14, 30, 1)
        sc.incrementState()
        sc.Height._value = 42
        sc.Weight._value = 420
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_SetValueOperationStateContainer(self):
        sc = statecontainers.SetValueOperationStateContainer(nsmapper=self.nsmapper, 
                                                             descriptorContainer=self.dc, 
                                                             node=None)
        
        self.assertEqual(sc.AllowedRange, [])
        sc.AllowedRange.append(pmtypes.Range(1,2,3,4,5))
        node = sc.mkStateNode()
        sc2 = statecontainers.SetValueOperationStateContainer(nsmapper=self.nsmapper, 
                                                             descriptorContainer=self.dc, 
                                                             node=node)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)

        sc.AllowedRange[0].Lower = 42
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)

        sc.AllowedRange.append(pmtypes.Range(3,4,5,6,7))
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(len(sc2.AllowedRange), 2)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)


def suite():
    return unittest.TestLoader().loadTestsFromTestCase(TestStateContainers)
#    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_SetValueOperationStateContainer'))


if __name__ == '__main__':
#    unittest.TextTestRunner(verbosity=2).run(suite())
#    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_RealTimeSampleArrayMetricStateContainer'))
    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_AbstractContextStateContainer'))

# coding: utf-8
from __future__ import print_function
from __future__ import absolute_import
import unittest
import datetime
from math import isclose
from lxml import etree as etree_
import copy
import sdc11073.mdib.statecontainers as statecontainers
import sdc11073.mdib.descriptorcontainers as descriptorcontainers
import sdc11073.namespaces as namespaces
import sdc11073.pmtypes as pmtypes
import sdc11073.xmlparsing as xmlparsing
import sdc11073.mdib.containerproperties as containerproperties
from sdc11073.location import SdcLocation
from sdc11073.definitions_sdc import SDC_v1_Definitions

#pylint: disable=protected-access

class TestStateContainers(unittest.TestCase):

    def setUp(self):
        self.nsmapper = namespaces.DocNamespaceHelper()
        self.dc = descriptorcontainers.AbstractDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        self.dc.DescriptorVersion = 42


    def test_AbstractStateContainer(self):
        sc = statecontainers.AbstractStateContainer(nsmapper=self.nsmapper, 
                                                    descriptorContainer=self.dc, 
                                                    node=None)
        # constructor shall create a node
        self.assertEqual(sc.nodeName, namespaces.domTag('State'))

        #initially the state version shall be 0, and DescriptorVersion shall be set
        self.assertEqual(sc.StateVersion, 0)
        self.assertEqual(sc.DescriptorVersion, self.dc.DescriptorVersion)
        
        # verify that mkStateNode() also updates changed Descriptorversion
        self.dc.DescriptorVersion +=1
        sc.mkStateNode()
        self.assertEqual(sc.DescriptorVersion, self.dc.DescriptorVersion)

        # verify incrementState works ay expected
        sc.incrementState()
        self.assertEqual(sc.StateVersion, 1)
        node = sc.mkStateNode()
        self.assertEqual(node.get('StateVersion'), '1')
        
        # test updateFromNode
        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'2',
                                      'DescriptorHandle': self.dc.handle})
        sc.updateFromNode(node)
        self.assertEqual(sc.StateVersion, 2)
        self.assertEqual(sc.node.get('StateVersion'), '2')
        
        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'3',
                                      'DescriptorHandle':'something_completely_different'})
        self.assertRaises(RuntimeError, sc.updateFromNode, node)

        #test creation from node
        sc2 = statecontainers.AbstractStateContainer(nsmapper=self.nsmapper, 
                                                     descriptorContainer=self.dc, 
                                                     node=copy.deepcopy(sc.node)) # sc2 might change node, therfore give it a deep copy
        self._verifyAbstractStateContainerDataEqual(sc, sc2)
        
        # test update from Node
        sc.DescriptorVersion += 1 
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def _verifyAbstractStateContainerDataEqual(self, sc1, sc2):
        self.assertEqual(sc1.DescriptorVersion, sc2.DescriptorVersion)
        self.assertEqual(sc1.StateVersion, sc2.StateVersion)
        self.assertEqual(sc1.nodeName, sc2.nodeName)


    def test_AbstractOperationStateContainer(self):
        sc = statecontainers.AbstractOperationStateContainer(nsmapper=self.nsmapper, 
                                                    descriptorContainer=self.dc, 
                                                    node=None)
        self.assertIsNotNone(sc.OperatingMode) # this is a required attribute
        
        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractOperationStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=self.dc, 
                                                          node=node)
        self.assertIsNotNone(sc2.OperatingMode)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)

        #test update from node
        sc.OperatingMode = pmtypes.OperatingMode.NA
        self.assertEqual(sc.OperatingMode, pmtypes.OperatingMode.NA)
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc2.OperatingMode, pmtypes.OperatingMode.NA)



    def test_AbstractMetricStateContainer_Final(self):
        dc = descriptorcontainers.NumericMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=dc,
                                                            node=None)

        self.assertEqual(sc.ActivationState, 'On')
        for value in ('foo', 'bar'):
            sc.ActivationState = value
            self.assertEqual(sc.ActivationState, value)
            node = sc.mkStateNode()
            self.assertEqual(node.get('ActivationState'), value)

        self.assertEqual(sc.ActiveDeterminationPeriod, None)
        for value in (21, 42):
            sc.ActiveDeterminationPeriod = value
            self.assertEqual(sc.ActiveDeterminationPeriod, value)
            node = sc.mkStateNode()
            self.assertEqual(node.get('ActiveDeterminationPeriod'),
                             containerproperties.DurationConverter.toXML(value))
        sc.BodySite = [pmtypes.CodedValue('ABC')]
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('ABC')], 1)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                          descriptorContainer=dc,
                                                          node=node)
        self.assertEqual(sc.ActivationState, sc2.ActivationState)
        self.assertEqual(sc.ActiveDeterminationPeriod, sc2.ActiveDeterminationPeriod)
        self.assertEqual(sc.BodySite, sc2.BodySite)
        self.assertEqual(sc.PhysicalConnector, sc2.PhysicalConnector)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)

        # test update from Node
        sc.ActivationState = 'something else'
        sc.ActiveDeterminationPeriod += 1
        sc.BodySite = [pmtypes.CodedValue('DEF')]
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('DEF')], 2)
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc.ActivationState, sc2.ActivationState)
        self.assertEqual(sc.BodySite, sc2.BodySite)
        self.assertEqual(sc.PhysicalConnector, sc2.PhysicalConnector)
        self.assertEqual(sc.ActiveDeterminationPeriod, sc2.ActiveDeterminationPeriod)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def test_NumericMetricStateContainer(self):
        dc = descriptorcontainers.NumericMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper,
                                                    descriptorContainer=dc,
                                                    node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.NumericMetricValue))
        sc.metricValue.Value = 42.21
        sc.metricValue.StartTime = 1234567.21
        sc.metricValue.StopTime = sc.metricValue.StartTime +10
        sc.metricValue.DeterminationTime = sc.metricValue.StartTime +20
        sc.metricValue.Validity = 'Vld'
        sc.ActiveAveragingPeriod = 42
        sc.PhysiologicalRange = [pmtypes.Range(1, 2, 3, 4, 5), pmtypes.Range(10, 20, 30, 40, 50)]
        node = sc.mkStateNode()
        
        #test creation from node
        sc2 = statecontainers.NumericMetricStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=dc,
                                                          node=node)
        # verify also that mkStateNode on receiving sc does not change anything
        for dummy in range(1):
            self.assertTrue(isclose(sc.metricValue.Value, sc2.metricValue.Value))
            self.assertEqual(sc.metricValue.StartTime, sc2.metricValue.StartTime)
            self.assertEqual(sc.metricValue.StopTime, sc2.metricValue.StopTime)
            self.assertEqual(sc.metricValue.DeterminationTime, sc2.metricValue.DeterminationTime)
            self.assertEqual(sc.metricValue.Validity, sc2.metricValue.Validity)
            self.assertEqual(sc.ActiveAveragingPeriod, sc2.ActiveAveragingPeriod)
            self.assertEqual(sc.PhysiologicalRange, sc2.PhysiologicalRange)
            
            self._verifyAbstractStateContainerDataEqual(sc, sc2)
            sc.mkStateNode()

        #test update from node
        sc.metricValue.Value += 1
        sc.incrementState()
        sc.ActiveAveragingPeriod = 24
        sc.PhysiologicalRange[1].Lower =100
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertTrue(isclose(sc.metricValue.Value, sc2.metricValue.Value))
        self.assertEqual(sc.ActiveAveragingPeriod, sc2.ActiveAveragingPeriod)
        self.assertEqual(sc.PhysiologicalRange, sc2.PhysiologicalRange)
        self._verifyAbstractStateContainerDataEqual(sc, sc2)


    def test_StringMetricStateContainer(self):
        dc = descriptorcontainers.StringMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')
        sc = statecontainers.StringMetricStateContainer(nsmapper=self.nsmapper,
                                                    descriptorContainer=dc,
                                                    node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.StringMetricValue))


    def test_EnumStringMetricStateContainer(self):
        dc = descriptorcontainers.EnumStringMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                   nodeName='MyDescriptor',
                                                                   handle='123',
                                                                   parentHandle='456')

        sc = statecontainers.EnumStringMetricStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=dc,
                                                            node=None)
        sc.mkMetricValue()
        self.assertTrue(isinstance(sc.metricValue, pmtypes.StringMetricValue))


    def test_RealTimeSampleArrayMetricStateContainer(self):
        dc = descriptorcontainers.RealTimeSampleArrayMetricDescriptorContainer(nsmapper=self.nsmapper,
                                                                               nodeName='MyDescriptor',
                                                                               handle='123',
                                                                               parentHandle='456')

        def verifyEqual(origin, copied):
            self.assertEqual(len(copied.metricValue.Samples), len(origin.metricValue.Samples))
            for c, o in zip(copied.metricValue.Samples, origin.metricValue.Samples):
                self.assertTrue((isclose(c, o)))
            self.assertEqual(copied.metricValue.DeterminationTime, origin.metricValue.DeterminationTime)
            self.assertEqual(copied.metricValue.Annotation, origin.metricValue.Annotation)
            self.assertEqual(copied.metricValue.ApplyAnnotations, origin.metricValue.ApplyAnnotations)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.RealTimeSampleArrayMetricStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=dc,
                                                                     node=None)
        sc.mkMetricValue()
        self.assertEqual(sc.nodeName, namespaces.domTag('State'))
        self.assertTrue(isinstance(sc.metricValue, pmtypes.SampleArrayValue))
        
        sc.metricValue.Samples = [1,2,3,4,5.5]
        sc.metricValue.DeterminationTime = 1234567
        sc.metricValue.Annotations = []
        sc.metricValue.ApplyAnnotations = []
        sc.ActivationState = 'act'

        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.RealTimeSampleArrayMetricStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=dc,
                                                                     node=node)
        verifyEqual(sc, sc2)
        
        #test update from node
        sc.metricValue.Samples = [5.5, 6.6]
        sc.metricValue.DeterminationTime = 2345678
        sc.metricValue.Annotations = [pmtypes.Annotation(pmtypes.CodedValue('a','b'))]
        sc.metricValue.ApplyAnnotations = [pmtypes.ApplyAnnotation(1,2)]

        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_AbstractDeviceComponentStateContainer_Final(self):

        def verifyEqual(origin, copied):
            self.assertEqual(copied.ActivationState, origin.ActivationState)
            self.assertEqual(copied.OperatingHours, origin.OperatingHours)
            self.assertEqual(copied.OperatingCycles, origin.OperatingCycles)
            self.assertEqual(copied.PhysicalConnector, origin.PhysicalConnector)
            self._verifyAbstractStateContainerDataEqual(copied, origin)

        sc = statecontainers.AbstractDeviceComponentStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        self.assertEqual(sc.ActivationState, None)
        self.assertEqual(sc.OperatingHours, None)
        self.assertEqual(sc.OperatingCycles, None)
        self.assertEqual(sc.PhysicalConnector, None)

        sc.ActivationState = 'On'
        sc.OperatingHours = 2.3
        sc.OperatingHours = 4
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('ABC')], 1)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractDeviceComponentStateContainer(nsmapper=self.nsmapper,
                                                                    descriptorContainer=self.dc,
                                                                    node=node)
        verifyEqual(sc, sc2)

        sc.ActivationState = 'Off'
        sc.OperatingHours += 1
        sc.OperatingHours += 1
        sc.PhysicalConnector = pmtypes.PhysicalConnectorInfo([pmtypes.LocalizedText('DEF')], 2)
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_MdsStateContainer(self):
        pass


    def test_VmdStateContainer(self):
        pass


    def test_ChannelStateContainer(self):
        pass


    def test_ClockStateContainer(self):
        pass


    def test_AbstractAlertStateContainer(self):
        pass



    def test_AlertSystemStateContainer_final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.SystemSignalActivation, origin.SystemSignalActivation)
            self.assertEqual(copied.LastSelfCheck, origin.LastSelfCheck)
            self.assertEqual(copied.SelfCheckCount, origin.SelfCheckCount)
            self.assertEqual(copied.PresentPhysiologicalAlarmConditions, origin.PresentPhysiologicalAlarmConditions)
            self.assertEqual(copied.PresentTechnicalAlarmConditions, origin.PresentTechnicalAlarmConditions)
            self._verifyAbstractStateContainerDataEqual(copied, origin)

        sc = statecontainers.AlertSystemStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        self.assertEqual(sc.SystemSignalActivation, [])
        self.assertEqual(sc.LastSelfCheck, None)
        self.assertEqual(sc.SelfCheckCount, None)
        self.assertEqual(sc.PresentPhysiologicalAlarmConditions, [])
        self.assertEqual(sc.PresentTechnicalAlarmConditions, [])

        #test creation from node
        sc.SystemSignalActivation = [pmtypes.SystemSignalActivation(manifestation=pmtypes.AlertSignalManifestation.AUD,
                                                                    state=pmtypes.AlertActivation.ON),
                                     pmtypes.SystemSignalActivation(manifestation=pmtypes.AlertSignalManifestation.VIS,
                                                                    state=pmtypes.AlertActivation.ON)
                                     ]
        sc.LastSelfCheck = 1234567
        sc.SelfCheckCount = 3
        sc.PresentPhysiologicalAlarmConditions = ["handle1", "handle2", "handle3"]
        sc.incrementState()
        node = sc.mkStateNode()
        sc2 = statecontainers.AlertSystemStateContainer(nsmapper=self.nsmapper,
                                                                    descriptorContainer=self.dc,
                                                                    node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.LastSelfCheck = 12345678
        sc.SelfCheckCount = 4
        sc.PresentPhysiologicalAlarmConditions = ["handle2", "handle3", "handle4"]
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_AlertConditionStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.ActualPriority, origin.ActualPriority)
            self.assertEqual(copied.Rank, origin.Rank)
            self.assertEqual(copied.DeterminationTime, origin.DeterminationTime)
            self.assertEqual(copied.Presence, origin.Presence)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
            
        sc = statecontainers.AlertConditionStateContainer(nsmapper=self.nsmapper, 
                                                          descriptorContainer=self.dc, 
                                                          node=None)
        self.assertEqual(sc.ActualPriority, None)
        self.assertEqual(sc.Rank, None)
        self.assertEqual(sc.DeterminationTime, None)
        self.assertEqual(sc.Presence, False)

        #test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.AlertConditionStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.ActualPriority = 'lo'
        sc.Rank = 3
        sc.DeterminationTime = 1234567
        sc.Presence = True
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_LimitAlertConditionStateContainer_Final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Limits, origin.Limits)
            self.assertEqual(copied.MonitoredAlertLimits, origin.MonitoredAlertLimits)
            self.assertEqual(copied.AutoLimitActivationState, origin.AutoLimitActivationState)
            self._verifyAbstractStateContainerDataEqual(copied, origin)


        sc = statecontainers.LimitAlertConditionStateContainer(nsmapper=self.nsmapper,
                                                            descriptorContainer=self.dc,
                                                            node=None)
        self.assertEqual(sc.MonitoredAlertLimits, pmtypes.AlertConditionMonitoredLimits.ALL_OFF)
        self.assertEqual(sc.AutoLimitActivationState, None)

        # test creation from node
        node = sc.mkStateNode()
        sc2 = statecontainers.LimitAlertConditionStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        verifyEqual(sc, sc2)

        # test update from node
        sc.Limits = pmtypes.Range(lower=5, upper=9, stepWidth=0.1, relativeAccuracy=0.01, absoluteAccuracy=0.001)
        sc.Rank = 3
        sc.DeterminationTime = 1234567
        sc.Presence = True
        sc.incrementState()
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)



    def test_SetStringOperationStateContainer_Final(self):
        sc = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                                   descriptorContainer=self.dc,
                                                                   node=None)
        # verify that initial pyValue is an empty list, and that no AllowedValues node is created
        self.assertEqual(sc.AllowedValues, [])
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)

        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=copy.deepcopy(sc.node))
        self.assertEqual(sc2.AllowedValues, [])

        # verify that setting to None is identical to empty list
        sc.AllowedValues = None
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)

        # verify that non-empty list creates values in xml and that same list appears in container created from that xml
        sc.AllowedValues = ['a', 'b', 'c']
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 1)
        valuesNodes = node.xpath('//dom:Value', namespaces=namespaces.nsmap)
        self.assertEqual(len(valuesNodes), 3)
        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        self.assertEqual(sc2.AllowedValues, ['a', 'b', 'c'])

        # verify that setting it back to None clears all data
        sc.AllowedValues = None
        node = sc.mkStateNode()
        allowedValuesNodes = node.xpath('//dom:AllowedValues', namespaces=namespaces.nsmap)
        self.assertEqual(len(allowedValuesNodes), 0)
        sc2 = statecontainers.SetStringOperationStateContainer(nsmapper=self.nsmapper,
                                                           descriptorContainer=self.dc,
                                                           node=node)
        self.assertEqual(sc2.AllowedValues, [])


    def test_AbstractMultiStateContainer(self):
        pass


    def test_AbstractContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.ContextAssociation, origin.ContextAssociation)
            self.assertEqual(copied.BindingMdibVersion, origin.BindingMdibVersion)
            self.assertEqual(copied.UnbindingMdibVersion, origin.UnbindingMdibVersion)
            self.assertEqual(copied.BindingStartTime, origin.BindingStartTime)
            self.assertEqual(copied.BindingEndTime, origin.BindingEndTime)
            self.assertEqual(copied.Validator, origin.Validator)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.AbstractContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        self.assertEqual(sc.ContextAssociation, 'No')
        self.assertEqual(sc.BindingMdibVersion, None)
        self.assertEqual(sc.UnbindingMdibVersion, None)
        self.assertEqual(sc.BindingStartTime, None)
        self.assertEqual(sc.BindingEndTime, None)
        self.assertEqual(sc.Validator, [])
        self.assertEqual(sc.Identification, [])

        idents = [pmtypes.InstanceIdentifier(root='abc', 
                                             type_codedValue=pmtypes.CodedValue('abc','def'), 
                                             identifierNames=[pmtypes.LocalizedText('ABC')], 
                                             extensionString='123')]
        sc.Identification = idents
        self.assertEqual(sc.Identification, idents)

        validators = [pmtypes.InstanceIdentifier(root='ABC', 
                                                 type_codedValue=pmtypes.CodedValue('123','456'), 
                                                 identifierNames=[pmtypes.LocalizedText('DEF')], 
                                                 extensionString='321')]
        sc.Validator = validators
        self.assertEqual(sc.Validator, validators)
        
        for value in ('assoc', 'disassoc'):
            sc.ContextAssociation = value
            node = sc.mkStateNode()
            self.assertEqual(node.get('ContextAssociation'), value)
            
        for value in (12345.123, 67890.987):
            sc.BindingStartTime = value
            sc.BindingEndTime = value+1
            node = sc.mkStateNode()
            self.assertEqual(node.get('BindingStartTime'), containerproperties.TimestampConverter.toXML(value))
            self.assertEqual(node.get('BindingEndTime'), containerproperties.TimestampConverter.toXML(value+1))

        for value in (0, 42, 123):
            sc.BindingMdibVersion = value
            sc.UnbindingMdibVersion = value+1
            node = sc.mkStateNode()
            self.assertEqual(node.get('BindingMdibVersion'), containerproperties.IntegerConverter.toXML(value))
            self.assertEqual(node.get('UnbindingMdibVersion'), containerproperties.IntegerConverter.toXML(value+1))

        node = etree_.Element(namespaces.domTag('State'),
                              attrib={'StateVersion':'2',
                                      'DescriptorHandle':'123',
                                      'BindingStartTime':'1234567',
                                      'BindingEndTime':'2345678',
                                      'Handle':sc.Handle})
        sc.updateFromNode(node)
        self.assertEqual(sc.BindingStartTime, 1234.567)
        self.assertEqual(sc.BindingEndTime, 2345.678)
        self.assertEqual(sc.node.get('BindingStartTime'), '1234567')
        self.assertEqual(sc.node.get('BindingEndTime'), '2345678')
        self.assertEqual(sc.Identification, [])
        self.assertEqual(sc.Validator, [])
        
        #test creation from node
        sc.Identification = idents
        sc.Validator = validators
        node = sc.mkStateNode()
        sc2 = statecontainers.AbstractContextStateContainer(nsmapper=self.nsmapper,
                                                                     descriptorContainer=self.dc, 
                                                                     node=node)
        verifyEqual(sc, sc2)


    def test_LocationContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.PoC, origin.PoC)
            self.assertEqual(copied.Room, origin.Room)
            self.assertEqual(copied.Bed, origin.Bed)
            self.assertEqual(copied.Facility, origin.Facility)
            self.assertEqual(copied.Building, origin.Building)
            self.assertEqual(copied.Floor, origin.Floor)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
            
        sc = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        
        self.assertTrue(sc.Handle is not None)
        self.assertEqual(sc.PoC, None)
        self.assertEqual(sc.Room, None)
        self.assertEqual(sc.Bed, None)
        self.assertEqual(sc.Facility, None)
        self.assertEqual(sc.Building, None)
        self.assertEqual(sc.Floor, None)

        #test creation from empty node
        node = sc.mkStateNode()
        self.assertEqual(node.get('Handle'), sc.Handle)
        print (etree_.tostring(node, pretty_print=True))
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)
        
        sc.Handle = 'xyz'
        sc.PoC = 'a'
        sc.Room = 'b'
        sc.Bed = 'c'
        sc.Facility = 'd'
        sc.Building = 'e'
        sc.Floor = 'f'
        
        #test creation from non-empty node
        node = sc.mkStateNode()
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                                     descriptorContainer=self.dc, 
                                                                     node=node)
        verifyEqual(sc, sc2)
        sc.PoC = 'aa'
        sc.Room = 'bb'
        sc.Bed = 'cc'
        sc.Facility = 'dd'
        sc.Building = 'ee'
        sc.Floor = 'ff'
        
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)

        loc = SdcLocation(fac='a', poc='b', bed='c', bld='d', flr='e', rm='f', root='g')
        bicepsSchema = xmlparsing.BicepsSchema(SDC_v1_Definitions)
        sc = statecontainers.LocationContextStateContainer.fromSdcLocation(nsmapper=self.nsmapper,
                                                                           descriptorContainer=self.dc, 
                                                                           handle='abc', 
                                                                           sdc_location=loc,
                                                                           bicepsSchema=bicepsSchema)
        self.assertEqual(sc.Handle, 'abc')
        self.assertEqual(sc.PoC, 'b')
        self.assertEqual(sc.Room, 'f')
        self.assertEqual(sc.Bed, 'c')
        self.assertEqual(sc.Facility, 'a')
        self.assertEqual(sc.Building, 'd')
        self.assertEqual(sc.Floor, 'e')

        #test creation from non-empty node
        node = sc.mkStateNode()
        sc2 = statecontainers.LocationContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)
        
        #Umlaut test
        dr = SdcLocation(fac=u'Dräger', poc=u'b', bed=u'c', bld=u'd', flr=u'e', rm=u'f', root=u'g')
        sc3 = statecontainers.LocationContextStateContainer.fromSdcLocation(nsmapper=self.nsmapper,
                                                                           descriptorContainer=self.dc, 
                                                                           handle='abc', 
                                                                           sdc_location=loc,
                                                                           bicepsSchema=bicepsSchema)
        sc2.updateFromSdcLocation(loc, bicepsSchema)
        verifyEqual(sc3, sc2)


    def test_PatientContextStateContainer(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.Givenname, origin.Givenname)
            self.assertEqual(copied.Middlename, origin.Middlename)
            self.assertEqual(copied.Familyname, origin.Familyname)
            self.assertEqual(copied.DateOfBirth, origin.DateOfBirth)
            self.assertEqual(copied.Height, origin.Height)
            self.assertEqual(copied.Weight, origin.Weight)
            self.assertEqual(copied.Race, origin.Race)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper, 
                                                           descriptorContainer=self.dc, 
                                                           node=None)
        sc.Identification.append(pmtypes.InstanceIdentifier('abc', pmtypes.CodedValue('123'), [pmtypes.LocalizedText('Peter', 'en'),
                                                                                               pmtypes.LocalizedText('Paul'),
                                                                                               pmtypes.LocalizedText('Mary')]))
        sc.Identification.append(pmtypes.InstanceIdentifier('def', pmtypes.CodedValue('456'), [pmtypes.LocalizedText('John'),
                                                                                               pmtypes.LocalizedText('Jim'),
                                                                                               pmtypes.LocalizedText('Jane')]))
        self.assertTrue(sc.Handle is not None)
        sc.Givenname = 'Karl'
        sc.Middlename = 'M.'
        sc.Familyname = 'Klammer'
        sc.Height = pmtypes.Measurement(88.2, pmtypes.CodedValue('abc', 'def'))
        sc.Weight = pmtypes.Measurement(68.2, pmtypes.CodedValue('abc'))
        sc.Race = pmtypes.CodedValue('123', 'def')

        sc.DateOfBirth = datetime.date(2001, 3, 12)
        print (sc.DateOfBirth)
        
        #test creation from node
        node = sc.mkStateNode()
        print (etree_.tostring(node, pretty_print=True).decode('utf-8'))
        sc2 = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper, 
                                                            descriptorContainer=self.dc, 
                                                            node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.Middlename = 'K.'
        sc.DateOfBirth = datetime.datetime(2001, 3, 12, 14, 30, 1)
        sc.incrementState()
        sc.Height._value =42
        sc.Weight._value =420
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_PatientContextStateContainer_final(self):
        def verifyEqual(origin, copied):
            self.assertEqual(copied.Handle, origin.Handle)
            self.assertEqual(copied.Givenname, origin.Givenname)
            self.assertEqual(copied.Middlename, origin.Middlename)
            self.assertEqual(copied.Familyname, origin.Familyname)
            self.assertEqual(copied.DateOfBirth, origin.DateOfBirth)
            self.assertEqual(copied.Height, origin.Height)
            self.assertEqual(copied.Weight, origin.Weight)
            self.assertEqual(copied.Race, origin.Race)
            self.assertEqual(copied.Identification, origin.Identification)
            self._verifyAbstractStateContainerDataEqual(copied, origin)
        
        sc = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper,
                                                                        descriptorContainer=self.dc,
                                                                        node=None)

        self.assertTrue(sc.Handle is not None)

        sc.Givenname = 'Karl'
        sc.Middlename = 'M.'
        sc.Familyname = 'Klammer'
        sc.Height = pmtypes.Measurement(88.2, pmtypes.CodedValue('abc', 'def'))
        sc.Weight = pmtypes.Measurement(68.2, pmtypes.CodedValue('abc'))
        sc.Race = pmtypes.CodedValue('123', 'def')

        sc.DateOfBirth = datetime.date(2001, 3, 12)
        print (sc.DateOfBirth)

        sc.Identification.append(pmtypes.InstanceIdentifier('abc', pmtypes.CodedValue('123'), [pmtypes.LocalizedText('Peter', 'en'),
                                                                                               pmtypes.LocalizedText('Paul'),
                                                                                               pmtypes.LocalizedText('Mary')]))
        sc.Identification.append(pmtypes.InstanceIdentifier('def', pmtypes.CodedValue('456'), [pmtypes.LocalizedText('John'),
                                                                                               pmtypes.LocalizedText('Jim'),
                                                                                               pmtypes.LocalizedText('Jane')]))

        #test creation from node
        node = sc.mkStateNode()
        print (etree_.tostring(node, pretty_print=True))
        sc2 = statecontainers.PatientContextStateContainer(nsmapper=self.nsmapper,
                                                                         descriptorContainer=self.dc,
                                                                         node=node)
        verifyEqual(sc, sc2)

        #test update from node
        sc.Middlename = 'K.'
        sc.DateOfBirth = datetime.datetime(2001, 3, 12, 14, 30, 1)
        sc.incrementState()
        sc.Height._value = 42
        sc.Weight._value = 420
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        verifyEqual(sc, sc2)


    def test_SetValueOperationStateContainer(self):
        sc = statecontainers.SetValueOperationStateContainer(nsmapper=self.nsmapper, 
                                                             descriptorContainer=self.dc, 
                                                             node=None)
        
        self.assertEqual(sc.AllowedRange, [])
        sc.AllowedRange.append(pmtypes.Range(1,2,3,4,5))
        node = sc.mkStateNode()
        sc2 = statecontainers.SetValueOperationStateContainer(nsmapper=self.nsmapper, 
                                                             descriptorContainer=self.dc, 
                                                             node=node)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)

        sc.AllowedRange[0].Lower = 42
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)

        sc.AllowedRange.append(pmtypes.Range(3,4,5,6,7))
        node = sc.mkStateNode()
        sc2.updateFromNode(node)
        self.assertEqual(len(sc2.AllowedRange), 2)
        self.assertEqual(sc.AllowedRange, sc2.AllowedRange)


def suite():
    return unittest.TestLoader().loadTestsFromTestCase(TestStateContainers)
#    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_SetValueOperationStateContainer'))


if __name__ == '__main__':
#    unittest.TextTestRunner(verbosity=2).run(suite())
#    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_RealTimeSampleArrayMetricStateContainer'))
    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_AbstractContextStateContainer'))

# coding: utf-8 #pylint: disable=protected-access # constructor shall create a node #initially the state version shall be 0, and DescriptorVersion shall be set # verify that mkStateNode() also updates changed Descriptorversion # verify incrementState works ay expected # test updateFromNode #test creation from node # sc2 might change node, therfore give it a deep copy # test update from Node # this is a required attribute #test creation from node #test update from node # test creation from node # test update from Node #test creation from node # verify also that mkStateNode on receiving sc does not change anything #test update from node #test creation from node #test update from node # test creation from node #test creation from node #test update from node #test creation from node #test update from node # test creation from node # test update from node # verify that initial pyValue is an empty list, and that no AllowedValues node is created # verify that setting to None is identical to empty list # verify that non-empty list creates values in xml and that same list appears in container created from that xml # verify that setting it back to None clears all data #test creation from node #test creation from empty node #test creation from non-empty node #test creation from non-empty node #Umlaut test #test creation from node #test update from node #test creation from node #test update from node #    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_SetValueOperationStateContainer')) #    unittest.TextTestRunner(verbosity=2).run(suite()) #    unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromName('test_statecontainers.TestStateContainers.test_RealTimeSampleArrayMetricStateContainer'))