66from enum import Enum
77from math import isnan , inf , nan
88
9- from conftest import requires_cothread
9+ from conftest import requires_cothread , WAVEFORM_LENGTH
1010
1111from softioc import asyncio_dispatcher , builder , softioc
1212from softioc .pythonSoftIoc import RecordWrapper
1818DEVICE_NAME = "RECORD-VALUE-TESTS"
1919TIMEOUT = 5 # Seconds
2020
21+ # The maximum length string for StringIn/Out records
22+ MAX_LEN_STR = "a 39 char string exactly maximum length"
23+
2124VERY_LONG_STRING = "This is a fairly long string, the kind that someone " \
2225 "might think to put into a record that can theoretically hold a huge " \
2326 "string and so lets test it and prove that shall we?"
@@ -101,6 +104,8 @@ def record_values_names(fixture_value):
101104 ("mbbOut_int" , builder .mbbOut , 1 , 1 , int ),
102105 ("strIn_abc" , builder .stringIn , "abc" , "abc" , str ),
103106 ("strOut_abc" , builder .stringOut , "abc" , "abc" , str ),
107+ ("strIn_39chars" , builder .stringIn , MAX_LEN_STR , MAX_LEN_STR , str ),
108+ ("strOut_39chars" , builder .stringOut , MAX_LEN_STR , MAX_LEN_STR , str ),
104109 ("strIn_empty" , builder .stringIn , "" , "" , str ),
105110 ("strOut_empty" , builder .stringOut , "" , "" , str ),
106111 ("strin_utf8" , builder .stringIn , "%a€b" , "%a€b" , str ), # Valid UTF-8
@@ -310,7 +315,7 @@ def run_ioc(record_configurations: list, conn, set_enum, get_enum):
310315 if set_enum == SetValueEnum .INITIAL_VALUE :
311316 kwarg .update ({"initial_value" : initial_value })
312317 elif creation_func in [builder .WaveformIn , builder .WaveformOut ]:
313- kwarg = {"length" : 50 } # Required when no value on creation
318+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
314319 # Related to this issue:
315320 # https://github.com/dls-controls/pythonSoftIOC/issues/37
316321
@@ -493,7 +498,7 @@ class TestGetValue:
493498 """Tests that use .get() to check whether values applied with .set(),
494499 initial_value, or caput return the expected value"""
495500
496- def test_value_pre_init_set (self , clear_records , record_values ):
501+ def test_value_pre_init_set (self , record_values ):
497502 """Test that records provide the expected values on get calls when using
498503 .set() and .get() before IOC initialisation occurs"""
499504
@@ -507,7 +512,7 @@ def test_value_pre_init_set(self, clear_records, record_values):
507512
508513 kwarg = {}
509514 if creation_func in [builder .WaveformIn , builder .WaveformOut ]:
510- kwarg = {"length" : 50 } # Required when no value on creation
515+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
511516
512517 out_rec = creation_func (record_name , ** kwarg )
513518 out_rec .set (initial_value )
@@ -678,15 +683,15 @@ class TestDefaultValue:
678683 ],
679684 )
680685 def test_value_default_pre_init (
681- self , creation_func , expected_value , expected_type , clear_records
686+ self , creation_func , expected_value , expected_type
682687 ):
683688 """Test that the correct default values are returned from .get() (before
684689 record initialisation) when no initial_value or .set() is done"""
685690 # Out records do not have default values until records are initialized
686691
687692 kwarg = {}
688693 if creation_func in [builder .WaveformIn , builder .WaveformOut ]:
689- kwarg = {"length" : 50 } # Required when no value on creation
694+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
690695
691696 out_rec = creation_func ("out-record" , ** kwarg )
692697 record_value_asserts (
@@ -728,7 +733,7 @@ def record_func_reject_none(self, record_func):
728733 return record_func
729734
730735 def test_value_none_rejected_initial_value (
731- self , clear_records , record_func_reject_none
736+ self , record_func_reject_none
732737 ):
733738 """Test setting \" None\" as the initial_value raises an exception"""
734739
@@ -737,7 +742,7 @@ def test_value_none_rejected_initial_value(
737742 builder .WaveformIn ,
738743 builder .WaveformOut ,
739744 ]:
740- kwarg = {"length" : 50 } # Required when no value on creation
745+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
741746
742747 with pytest .raises (self .expected_exceptions ):
743748 record_func_reject_none ("SOME-NAME" , initial_value = None , ** kwarg )
@@ -749,7 +754,7 @@ def test_value_none_rejected_set_before_init(
749754
750755 kwarg = {}
751756 if record_func_reject_none in [builder .WaveformIn , builder .WaveformOut ]:
752- kwarg = {"length" : 50 } # Required when no value on creation
757+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
753758
754759 with pytest .raises (self .expected_exceptions ):
755760 record = record_func_reject_none ("SOME-NAME" , ** kwarg )
@@ -759,7 +764,7 @@ def none_value_test_func(self, record_func, queue):
759764 """Start the IOC and catch the expected exception"""
760765 kwarg = {}
761766 if record_func in [builder .WaveformIn , builder .WaveformOut ]:
762- kwarg = {"length" : 50 } # Required when no value on creation
767+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
763768
764769 record = record_func ("SOME-NAME" , ** kwarg )
765770
@@ -793,3 +798,84 @@ def test_value_none_rejected_set_after_init(self, record_func_reject_none):
793798 finally :
794799 process .terminate ()
795800 process .join (timeout = 3 )
801+
802+
803+ class TestInvalidValues :
804+ """Tests for values that records should reject"""
805+
806+ def test_string_rejects_overlong_strings (self ):
807+ """Test that stringIn & stringOut records reject strings >=39 chars"""
808+
809+ OVERLONG_STR = MAX_LEN_STR + "A"
810+
811+ with pytest .raises (ValueError ):
812+ builder .stringIn ("STRIN1" , initial_value = OVERLONG_STR )
813+
814+ with pytest .raises (ValueError ):
815+ builder .stringOut ("STROUT1" , initial_value = OVERLONG_STR )
816+
817+ with pytest .raises (ValueError ):
818+ si = builder .stringIn ("STRIN2" )
819+ si .set (OVERLONG_STR )
820+
821+ with pytest .raises (ValueError ):
822+ so = builder .stringOut ("STROUT2" , initial_value = OVERLONG_STR )
823+ so .set (OVERLONG_STR )
824+
825+ def test_long_string_rejects_overlong_strings (self ):
826+ """Test that longStringIn & longStringOut records reject
827+ strings >=39 chars"""
828+ OVERLONG_STR = MAX_LEN_STR + "A"
829+
830+ with pytest .raises (AssertionError ):
831+ builder .longStringIn (
832+ "LSTRIN1" ,
833+ initial_value = OVERLONG_STR ,
834+ length = WAVEFORM_LENGTH )
835+
836+ with pytest .raises (AssertionError ):
837+ builder .longStringOut (
838+ "LSTROUT1" ,
839+ initial_value = OVERLONG_STR ,
840+ length = WAVEFORM_LENGTH )
841+
842+ with pytest .raises (AssertionError ):
843+ lsi = builder .longStringIn ("LSTRIN2" , length = WAVEFORM_LENGTH )
844+ lsi .set (OVERLONG_STR )
845+
846+ with pytest .raises (AssertionError ):
847+ lso = builder .longStringIn ("LSTROUT2" , length = WAVEFORM_LENGTH )
848+ lso .set (OVERLONG_STR )
849+
850+ # And a different way to initialise the records to trigger same behaviour:
851+ with pytest .raises (AssertionError ):
852+ lsi = builder .longStringIn ("LSTRIN3" , initial_value = "ABC" )
853+ lsi .set (OVERLONG_STR )
854+
855+ with pytest .raises (AssertionError ):
856+ lso = builder .longStringOut ("LSTROUT3" , initial_value = "ABC" )
857+ lso .set (OVERLONG_STR )
858+
859+
860+ def test_waveform_rejects_zero_length (self ):
861+ """Test that WaveformIn/Out and longStringIn/Out records throw an
862+ exception when being initialized with a zero length array"""
863+ with pytest .raises (AssertionError ):
864+ builder .WaveformIn ("W_IN" , [])
865+ with pytest .raises (AssertionError ):
866+ builder .WaveformOut ("W_OUT" , [])
867+ with pytest .raises (AssertionError ):
868+ builder .longStringIn ("L_IN" , length = 0 )
869+ with pytest .raises (AssertionError ):
870+ builder .longStringOut ("L_OUT" , length = 0 )
871+
872+ def test_waveform_rejects_overlonglong_values (self ):
873+ """Test that Waveform records throw an exception when an overlong
874+ value is written"""
875+ w_in = builder .WaveformIn ("W_IN" , [1 , 2 , 3 ])
876+ w_out = builder .WaveformOut ("W_OUT" , [1 , 2 , 3 ])
877+
878+ with pytest .raises (AssertionError ):
879+ w_in .set ([1 , 2 , 3 , 4 ])
880+ with pytest .raises (AssertionError ):
881+ w_out .set ([1 , 2 , 3 , 4 ])
0 commit comments