epics-extensions / WeTest

Test automation utility for EPICS modules (from YAML configuration to PDF test reports)
Other
8 stars 2 forks source link

WeTest does not support `*` or `:` in string field name #91

Open vnadot opened 4 weeks ago

vnadot commented 4 weeks ago
version: {major: 2, minor: 0, bugfix: 0}

include:
  - ['epicsComGen_WeTest_mbbo_range.yaml', PV_NAME: '${P}Set', PV_NAME_RB: '${P}Rb', delay: 0.001, skip_ZRST: false, ZRST: '*1 (no gain)', skip_ONST: false, ONST: '*1.666666667'] # sec
macros:
  # config
  - on_failure: continue
  - retry:      10 # -1 for infinite
  - MAJOR:      2
  - MINOR:      0
  - BUGFIX:     0
  # global
  - name:             "WeTest - mbbo range test (${PV_NAME})"
  - delay:            0.5 # sec
  - skip:             False
  - skip_limits:      False
  - skip_ZRST:        True
  - skip_ONST:        True
  - skip_TWST:        True
  - skip_THST:        True
  - skip_FRST:        True
  - skip_FVST:        True
  - skip_SXST:        True
  - skip_SVST:        True
  - skip_EIST:        True
  - skip_NIST:        True
  - skip_TEST:        True
  - skip_ELST:        True
  - skip_TVST:        True
  - skip_TTST:        True
  - skip_FTST:        True
  - skip_FFST:        True
  - skip_final_value: True
  # - skip_range:       False
  # default values
  - PV_NAME:          "CEA:Set"
  - PV_NAME_RB:       "CEA:Rb"
  # - RANGE_FINAL_VALUE:  0
  - ZRST: "ch0 MEBT FC1"
  - ONST: "ch1 HEBT MUX FC1"
  - TWST: "ch1 HEBT MUX FC2"
  - THST: "ch1 HEBT MUX FC3"
  - FRST: "ch1 HEBT MUX FC4"
  - FVST: ""
  - SXST: ""
  - SVST: ""
  - EIST: ""
  - NIST: ""
  - TEST: ""
  - ELST: ""
  - TVST: ""
  - TTST: ""
  - FTST: ""
  - FFST: ""
  - FINAL_VALUE: "ch0 MEBT FC1" # needs to be STRING for Rb ?

version: {major: "${MAJOR}", minor: "${MINOR}", bugfix: "${BUGFIX}"}

config:
  name:        ${name}
  type:        functional
  delay:       ${delay}
  on_failure:  ${on_failure}
  retry:       ${retry}
  skip:        ${skip}

tests:
  # enable put
  - name: "${name} - enable PV put (DISP EPICS field)"
    commands:
    - name:       "${name} - enable PV put (DISP EPICS field)"
      setter:     "${PV_NAME}.DISP" # 0: enable put, 1:disable put
      set_value:  "0"

  - name: "${name} - check mbbo limits"
    commands:
    # -1 value
    - name:       "zero value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}.RVAL"
      set_value:  "-1"
      get_value:  "0"
      skip:       "${skip_limits}"
    # 16 value
    - name:       "one value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}.RVAL"
      set_value:  "16"
      get_value:  "0"
      skip:       "${skip_limits}"
    # 0 value
    - name:       "zero value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}.RVAL"
      set_value:  "0"
      get_value:  "0"
      skip:       "${skip_limits}"
    # final value (needed if "check mbbo range" test skipped)
    - name:       "zero value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FINAL_VALUE}"
      get_value:  "${FINAL_VALUE}"
      skip:       "${skip_final_value}"

  # test values in range
  # today use VAL, but we coould support STRING value too ? todo?
  # - name:     "${name} - check mbbo range"
  #   setter:   "${PV_NAME}"
  #   getter:   "${PV_NAME_RB}.RVAL"
  #   skip:     "${skip_range}"
  #   range:
  #     start:  0
  #     stop:   15
  #     step:   1
  #   finally:
  #     value:  ${RANGE_FINAL_VALUE}

  - name: "${name} - check mbbo range"
    commands:
    # I put "0 value" at the end, so I don't have to reset to 0
    # 1 value
    - name:       "one value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${ONST}"
      get_value:  "${ONST}"
      skip:       "${skip_ONST}"
    # 2 value
    - name:       "two value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${TWST}"
      get_value:  "${TWST}"
      skip:       "${skip_TWST}"
    # 3 value
    - name:       "three value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${THST}"
      get_value:  "${THST}"
      skip:       "${skip_THST}"
    # 4 value
    - name:       "four value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FRST}"
      get_value:  "${FRST}"
      skip:       "${skip_FRST}"
    # 5 value
    - name:       "five value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FVST}"
      get_value:  "${FVST}"
      skip:       "${skip_FVST}"
    # 6 value
    - name:       "six value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${SXST}"
      get_value:  "${SXST}"
      skip:       "${skip_SXST}"
    # 7 value
    - name:       "seven value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${SVST}"
      get_value:  "${SVST}"
      skip:       "${skip_SVST}"
    # 8 value
    - name:       "height value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${EIST}"
      get_value:  "${EIST}"
      skip:       "${skip_EIST}"
    # 9 value
    - name:       "nine value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${NIST}"
      get_value:  "${NIST}"
      skip:       "${skip_NIST}"
    # 10 value
    - name:       "ten value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${TEST}"
      get_value:  "${TEST}"
      skip:       "${skip_TEST}"
    # 11 value
    - name:       "eleven value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${ELST}"
      get_value:  "${ELST}"
      skip:       "${skip_ELST}"
    # 12 value
    - name:       "twelve value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${TVST}"
      get_value:  "${TVST}"
      skip:       "${skip_TVST}"
    # 13 value
    - name:       "thirteen value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${TTST}"
      get_value:  "${TTST}"
      skip:       "${skip_TTST}"
    # 14 value
    - name:       "fourteen value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FTST}"
      get_value:  "${FTST}"
      skip:       "${skip_FTST}"
    # 15 value
    - name:       "fifteen value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FFST}"
      get_value:  "${FFST}"
      skip:       "${skip_FFST}"
    # 0 value
    - name:       "zero value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${ZRST}"
      get_value:  "${ZRST}"
      skip:       "${skip_ZRST}"

  - name: "${name} - final mbbo value"
    commands:
    - name:       "final value"
      setter:     "${PV_NAME}"
      getter:     "${PV_NAME_RB}"
      set_value:  "${FINAL_VALUE}"
      get_value:  "${FINAL_VALUE}"
      skip:       "${skip_final_value}"

  # disable PUT back if it was disable
  # todo: how to do that ?
  # - name: "${name} - enable PV put (DISP EPICS field)"
  #   commands:
  #   - name:       "${name} - disable PV put (DISP EPICS field)"
  #     setter:     "${PV_NAME}.DISP" # 0: enable put, 1:disable put
  #     set_value:  "1"
Validation of YAML scenario file: /.../test/misc/WeTest/epicsComGen/epicsComGen_WeTest_mbbo_range.yaml
Traceback (most recent call last):
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/bin/..wetest-wrapped-wrapped", line 9, in <module>
    sys.exit(main())
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/command_line.py", line 426, in main
    suite, configs = generate_tests(
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/command_line.py", line 171, in generate_tests
    tests_data = ScenarioReader(
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 343, in __init__
    self.deserialized = self._deserialize()
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 437, in _deserialize
    new_sc = ScenarioReader(
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 343, in __init__
    self.deserialized = self._deserialize()
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 368, in _deserialize
    wetest_file = self._substitute_macros(yaml.safe_load(self.file))
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 768, in _substitute_macros
    deserialized = self.macros_mgr.substitute_macros(
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 202, in substitute_macros
    output[k] = self.substitute_macros(v, trace_unknown=trace_unknown)
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 198, in substitute_macros
    return [self.substitute_macros(x, trace_unknown) for x in a_value]
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 198, in <listcomp>
    return [self.substitute_macros(x, trace_unknown) for x in a_value]
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 202, in substitute_macros
    output[k] = self.substitute_macros(v, trace_unknown=trace_unknown)
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 198, in substitute_macros
    return [self.substitute_macros(x, trace_unknown) for x in a_value]
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 198, in <listcomp>
    return [self.substitute_macros(x, trace_unknown) for x in a_value]
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 202, in substitute_macros
    output[k] = self.substitute_macros(v, trace_unknown=trace_unknown)
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/reader.py", line 234, in substitute_macros
    output = yaml.safe_load(new_str)
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/__init__.py", line 125, in safe_load
    return load(stream, SafeLoader)
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/constructor.py", line 49, in get_single_data
    node = self.get_single_node()
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/composer.py", line 55, in compose_document
    node = self.compose_node(None, None)
  File "/nix/store/xf7n7gz8azwimm008pgs0vgnr5g2gixh-python3.9-pyyaml-6.0/lib/python3.9/site-packages/yaml/composer.py", line 68, in compose_node
    raise ComposerError(None, None, "found undefined alias %r"
yaml.composer.ComposerError: found undefined alias '1'
  in "<unicode string>", line 1, column 1:
    *1

if I replace *1 by x1 in ZRST (and ONST) field it works

vnadot commented 2 weeks ago

It is the same for : char:

My EPICS database:

record(bo, "resetBehaviorCmd") {
    field(DTYP, "asynInt32")
    field( OUT, "@asyn($(PORT), 0)IresetBehavior")
    field(ZNAM, "reset: 0mA")
    field(ONAM, "reset: xn")
}
record(bi, "resetBehaviorRb") {
    field(DTYP, "asynInt32")
    field( INP, "@asyn($(PORT), 0)IresetBehavior")
    field(SCAN, "I/O Intr")
    field(ZNAM, "reset: 0mA")
    field(ONAM, "reset: xn")
}

EPICS caputs work fine:

$ caput LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd "reset: xn"
Old : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: 0mA
New : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: xn
$ caput LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: 0mA
Old : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: xn
New : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: 0mA
$ caput LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: xn
Old : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: 0mA
New : LAB-SBCT:MPS-SBCT:I0resetBehaviorCmd reset: xn
$ caget LAB-SBCT:MPS-SBCT:I0resetBehaviorRb
LAB-SBCT:MPS-SBCT:I0resetBehaviorRb reset: xn

But does not work with WeTest:

...
Running    test-584-1-0    WeTest - bo range test (resetBehaviorCmd) - check bo range: one value
Error   of test-584-1-0    (in 0.024s) [setter error] int() argument must be a string, a bytes-like object or a number, not 'dict'

...
======================================================================
ERROR: test-584-1-0 (wetest.testing.generator.SelectableTestCase)
WeTest - bo range test (resetBehaviorCmd) - check bo range: one value
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/iee/extensions/lib/python/pyepics-3.2.4-py2.7.egg/epics/ca.py", line 1305, in put
    data[0] = value
TypeError: an integer is required (got type dict)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/nix/store/pnkbr2dx35h9rz9zn3fgvcgvfr73smvs-python3.9-wetest-2.0.0rc1/lib/python3.9/site-packages/wetest/testing/generator.py", line 438, in test
    setter.put(set_value)
  File "/iee/extensions/lib/python/pyepics-3.2.4-py2.7.egg/epics/pv.py", line 336, in put
    return ca.put(self.chid, value,
  File "/iee/extensions/lib/python/pyepics-3.2.4-py2.7.egg/epics/ca.py", line 403, in wrapper
    return fcn(*args, **kwds)
  File "/iee/extensions/lib/python/pyepics-3.2.4-py2.7.egg/epics/ca.py", line 1307, in put
    data[0] = type(data[0])(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'dict'