6
6
from enum import Enum
7
7
from math import isnan , inf , nan
8
8
9
- from conftest import requires_cothread
9
+ from conftest import requires_cothread , WAVEFORM_LENGTH
10
10
11
11
from softioc import asyncio_dispatcher , builder , softioc
12
12
from softioc .pythonSoftIoc import RecordWrapper
18
18
DEVICE_NAME = "RECORD-VALUE-TESTS"
19
19
TIMEOUT = 5 # Seconds
20
20
21
+ # The maximum length string for StringIn/Out records
22
+ MAX_LEN_STR = "a 39 char string exactly maximum length"
23
+
21
24
VERY_LONG_STRING = "This is a fairly long string, the kind that someone " \
22
25
"might think to put into a record that can theoretically hold a huge " \
23
26
"string and so lets test it and prove that shall we?"
@@ -101,6 +104,8 @@ def record_values_names(fixture_value):
101
104
("mbbOut_int" , builder .mbbOut , 1 , 1 , int ),
102
105
("strIn_abc" , builder .stringIn , "abc" , "abc" , str ),
103
106
("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 ),
104
109
("strIn_empty" , builder .stringIn , "" , "" , str ),
105
110
("strOut_empty" , builder .stringOut , "" , "" , str ),
106
111
("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):
310
315
if set_enum == SetValueEnum .INITIAL_VALUE :
311
316
kwarg .update ({"initial_value" : initial_value })
312
317
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
314
319
# Related to this issue:
315
320
# https://github.com/dls-controls/pythonSoftIOC/issues/37
316
321
@@ -493,7 +498,7 @@ class TestGetValue:
493
498
"""Tests that use .get() to check whether values applied with .set(),
494
499
initial_value, or caput return the expected value"""
495
500
496
- def test_value_pre_init_set (self , clear_records , record_values ):
501
+ def test_value_pre_init_set (self , record_values ):
497
502
"""Test that records provide the expected values on get calls when using
498
503
.set() and .get() before IOC initialisation occurs"""
499
504
@@ -507,7 +512,7 @@ def test_value_pre_init_set(self, clear_records, record_values):
507
512
508
513
kwarg = {}
509
514
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
511
516
512
517
out_rec = creation_func (record_name , ** kwarg )
513
518
out_rec .set (initial_value )
@@ -678,15 +683,15 @@ class TestDefaultValue:
678
683
],
679
684
)
680
685
def test_value_default_pre_init (
681
- self , creation_func , expected_value , expected_type , clear_records
686
+ self , creation_func , expected_value , expected_type
682
687
):
683
688
"""Test that the correct default values are returned from .get() (before
684
689
record initialisation) when no initial_value or .set() is done"""
685
690
# Out records do not have default values until records are initialized
686
691
687
692
kwarg = {}
688
693
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
690
695
691
696
out_rec = creation_func ("out-record" , ** kwarg )
692
697
record_value_asserts (
@@ -728,7 +733,7 @@ def record_func_reject_none(self, record_func):
728
733
return record_func
729
734
730
735
def test_value_none_rejected_initial_value (
731
- self , clear_records , record_func_reject_none
736
+ self , record_func_reject_none
732
737
):
733
738
"""Test setting \" None\" as the initial_value raises an exception"""
734
739
@@ -737,7 +742,7 @@ def test_value_none_rejected_initial_value(
737
742
builder .WaveformIn ,
738
743
builder .WaveformOut ,
739
744
]:
740
- kwarg = {"length" : 50 } # Required when no value on creation
745
+ kwarg = {"length" : WAVEFORM_LENGTH } # Must specify when no value
741
746
742
747
with pytest .raises (self .expected_exceptions ):
743
748
record_func_reject_none ("SOME-NAME" , initial_value = None , ** kwarg )
@@ -749,7 +754,7 @@ def test_value_none_rejected_set_before_init(
749
754
750
755
kwarg = {}
751
756
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
753
758
754
759
with pytest .raises (self .expected_exceptions ):
755
760
record = record_func_reject_none ("SOME-NAME" , ** kwarg )
@@ -759,7 +764,7 @@ def none_value_test_func(self, record_func, queue):
759
764
"""Start the IOC and catch the expected exception"""
760
765
kwarg = {}
761
766
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
763
768
764
769
record = record_func ("SOME-NAME" , ** kwarg )
765
770
@@ -793,3 +798,84 @@ def test_value_none_rejected_set_after_init(self, record_func_reject_none):
793
798
finally :
794
799
process .terminate ()
795
800
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