def main(): parser = OptionParser() parser.add_option('', "--debug", action="store_true", default=False, help="Set the debug flag") (options, args) = parser.parse_args() lock_obj = Locker(name='LockerTest', debug=options.debug) print("\nBasic locker functionality test:") results = [] messages = [] for test in [lock_take, multithreading_take]: result, msg = test(lock_obj) results.append(result) messages.append(msg) _print_footer(msg) if all(results): print("All tests PASSED") else: print("ALERT! NOT ALL THE TESTS HAS PASSED. Check the list") for msg in messages: print(msg) if all(results): sys.exit(0) else: sys.exit(-1)
def check_command_queries(scpi_obj): _print_header("Testing to command queries") try: print("Launch tests:") cmd = "*IDN?" answer = _send2input(scpi_obj, cmd) print("\tInstrument identification ({0})\n\tAnswer: {1}" "".format(cmd, answer)) for base_cmd in ['SOURce', 'BASIcloop', 'ITERative']: _print_header("Check {0} part of the tree".format(base_cmd)) _do_check_commands(scpi_obj, base_cmd) for ch in range(1, n_channels+1): base_cmd = "CHANnel{0}".format(str(ch).zfill(2)) _print_header("Check {0} part of the tree".format(base_cmd)) _do_check_commands(scpi_obj, base_cmd) fn = _random_choice(range(1, n_subchannels+1)) inner_cmd = "FUNCtion{0}".format(str(fn).zfill(2)) _print_header("Check {0} + MEAS:{1} part of the tree" "".format(base_cmd, inner_cmd)) _do_check_commands(scpi_obj, base_cmd, inner_cmd) result = True, "Command queries test PASSED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(e)) print_exc() result = False, "Command queries test FAILED" _print_footer(result[1]) return result
def check_telnet_hooks(scpi_obj): _print_header("Telnet hooks") try: ipv4 = Telnet("127.0.0.1", 5025) ipv6 = Telnet("::1", 5025) cmd = "*IDN?" def hook(who, what): _print_info("\t\thook call, received: ({0!r}, {1!r})" "".format(who, what)) scpi_obj.addConnectionHook(hook) _print_info("\tipv4 send {0}".format(cmd)) ipv4.write(cmd) _print_info("\tipv4 answer {0!r}".format(ipv4.read_until('\n'))) _print_info("\tipv6 send {0}".format(cmd)) ipv6.write(cmd) _print_info("\tipv6 answer {0!r}".format(ipv6.read_until('\n'))) scpi_obj.removeConnectionHook(hook) ipv4.close() ipv6.close() result = True, "Telnet hooks test PASSED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Telnet hooks test FAILED" _print_footer(result[1]) return result
def check_write_without_params(scpi_obj): _print_header("Attribute write without parameters") try: cmd = 'writter:without:parameters' switch = WattrTest() scpi_obj.add_command(cmd, read_cb=switch.switchTest) correct, failed = 0, 0 for i in range(3): cmd = "{0}{1}".format(cmd, " "*i) try: answer = _send2input(scpi_obj, cmd, expected_answer='ACK\r\n') except ValueError as exc: msg = "Error: {0}".format(exc) failed += 1 else: msg = "Answer: {0!r} (len ({1:d})" \ "".format(answer, len(answer)) correct += 1 print("\tRequest {0!r}\n\t{1}\n".format(cmd, msg)) if failed == 0: result = True, "Write without parameters test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Write without parameters test FAILED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Write without parameters test FAILED" _print_footer(result[1]) return result
def add_invalid_cmds(scpi_obj): _print_header("Testing to build invalid commands") try: scpi_obj.add_command(":startswithcolon", read_cb=None) except NameError as exc: print("\tNull name test PASSED") except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() return False, "Invalid commands test FAILED" try: scpi_obj.add_command("double::colons", read_cb=None) except NameError: print("\tDouble colon name test PASSED") except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() return False, "Invalid commands test FAILED" try: scpi_obj.add_command("nestedSpecial:*special", read_cb=None) except NameError: scpi_obj.command_tree.pop('nestedSpecial') print("\tNested special command test PASSED") except Exception as exp: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() return False, "Invalid commands test FAILED" result = True, "Invalid commands test PASSED" _print_footer(result[1]) return result
def check_wo_special_cmds(scpi_obj): _print_header("Test Write Only special commands") wilco = "wilco\r\n" commands = [['SHT', sht, wilco], ['RST', rst, wilco], ['RAP', rap, wilco]] correct, failed = 0, 0 for cmd_name, write_cb, expected_answer in commands: try: scpi_obj.add_special_command(cmd_name, read_cb=None, write_cb=write_cb) answer = '' start_t = _time() answer = _send2input( scpi_obj, "*{0}".format(cmd_name), expected_answer=expected_answer) correct += 1 except ValueError as exc: print("\tSpecial command {0} answer failed: {0}" "".format(cmd_name, exc)) failed += 1 except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() failed += 1 print("\tWrite Only special command *{0}\n" "\tAnswer: {1!r} ({2:g} ms)" "".format(cmd_name, answer, (_time()-start_t)*1000)) if failed == 0: result = True, "Write Only special commands test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Write Only special commands test FAILED" _print_footer(result[1]) return result
def check_locks(scpi_obj): _print_header("system [write]lock") try: LockThreadedTest(scpi_obj).launch_test() result = True, "system [write]lock test PASSED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "system [write]lock test FAILED" _print_footer(result[1]) return result
def check_nonexisting_commands(scpi_obj): _print_header("Testing to query commands that doesn't exist") base_cmd = _random_choice(['SOURce', 'BASIcloop', 'ITERative']) sub_cmd = _random_choice(['CURRent', 'VOLTage']) attr = _random_choice(['UPPEr', 'LOWEr', 'VALUe']) fake = "FAKE" ack = 'ACK\r\n' nok = 'NOK\r\n' start_t = _time() pairs = [ # * first level doesn't exist ["{0}:{1}:{2}?".format(fake, sub_cmd, attr), nok], # * intermediate level doesn't exist ["{0}:{1}:{2}?".format(base_cmd, fake, attr), nok], # * Attribute level doesn't exist ["{0}:{1}:{2}?".format(base_cmd, sub_cmd, fake), nok], # * Attribute that doesn't respond ['source:voltage:exception?', nok], # * Unexisting Channel ["CHANnel{0}".format(str(n_channels+3).zfill(2)), nok], # * Channel below the minimum reference ["CHANnel00:VOLTage:UPPEr?", nok], # * Channel above the maximum reference ["CHANnel99:VOLTage:UPPEr?", nok], ] correct, failed = 0, 0 for cmd, expected_answer in pairs: answer = '' try: start_t = _time() answer = _send2input( scpi_obj, cmd, expected_answer=expected_answer) correct += 1 except ValueError as exc: print("\tFake command answer failed: {0}".format(exc)) failed += 1 except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() failed += 1 print("\tRequest non-existing command {0}\n" "\tAnswer: {1!r} ({2:g} ms)" "".format(cmd, answer, (_time()-start_t)*1000)) if failed == 0: result = True, "Non-existing commands test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Non-existing commands test FAILED" _print_footer(result[1]) return result
def check_array_answers(scpi_obj): _print_header("Requesting an attribute the answer of which is an array") try: base_cmd = 'source' attr_cmd = 'buffer' long_test = ArrayTest(100) scpi_obj.add_command(attr_cmd, read_cb=long_test.readTest) # current current_obj = ArrayTest(5) current_cmd = "{0}:current:{1}".format(base_cmd, attr_cmd) scpi_obj.add_command(current_cmd, read_cb=current_obj.readTest) # voltage voltage_obj = ArrayTest(5) voltage_cmd = "{0}:voltage:{1}".format(base_cmd, attr_cmd) scpi_obj.add_command(voltage_cmd, read_cb=voltage_obj.readTest) # queries answers_lengths = {} correct, failed = 0, 0 for cmd in [attr_cmd, current_cmd, voltage_cmd]: for format in ['ASCII', 'QUADRUPLE', 'DOUBLE', 'SINGLE', 'HALF']: _send2input(scpi_obj, "DataFormat {0}".format(format), check_answer=False) answer = None try: answer = _send2input( scpi_obj, cmd + '?', bad_answer='NOK\r\n') except ValueError as exc: msg = "Error: {0}".format(exc) failed += 1 else: msg = "Answer: {0!r} (len ({1:d})" \ "".format(answer, len(answer)) correct += 1 print("\tRequest {0!r}\n\t{1}\n".format(cmd, msg)) if format not in answers_lengths: answers_lengths[format] = [] answers_lengths[format].append( len(answer) if answer is not None else 0) print("\tanswer lengths summary: {0}".format( "".join('\n\t\t{0}:{1}'.format(k, v) for k, v in answers_lengths.iteritems()))) if failed == 0: result = True, "Array answers test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Array answers test FAILED" except Exception as e: print("\tUnexpected kind of exception! {0}".format(e)) print_exc() result = False, "Array answers test FAILED" _print_footer(result[1]) return result
def check_multiple_commands(scpi_obj): _print_header("Requesting more than one attribute per query") try: log = {} correct, failed = 0, 0 for i in range(2, concatenated_cmds+1): lst = [] for j in range(i): bar = _build_command2test() lst.append(bar) cmds = ";".join(x for x in lst) cmds_repr = "".join("\t\t{0}\n".format(cmd) for cmd in cmds.split(';')) start_t = _time() answer = _send2input(scpi_obj, cmds) answers = _cut_multiple_answer(answer) n_answers = len(answers) if '' in answers or 'ACK' in answers or 'NOK' in answers: failed += 1 else: correct += 1 log[n_answers] = (_time() - start_t)*1000 print("\tRequest {0:d} attributes in a single query: \n" "{1}\tAnswer: {2!r} ({3:d}, {4:g} ms)\n" "".format(i, cmds_repr, answer, n_answers, log[n_answers])) if n_answers != i: raise AssertionError( "The answer doesn't have the {0:d} expected elements " "(but {1:d})" "".format(i, n_answers)) _inter_test_wait() msg = "\tSummary:" for length in log: t = log[length] msg += "\n\t\t{0}\t{1:6.3f} ms\t{2:6.3f} ms/cmd" \ "".format(length, t, t/length) print(msg) if failed == 0: result = True, "Many commands per query test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Many commands per query test FAILED" # TODO: multiple writes except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Many commands per query test FAILED" _print_footer(result[1]) return result
def check_idn(scpi_obj): _print_header("Test instrument identification") try: identity = InstrumentIdentification('ALBA', 'test', 0, _version()) scpi_obj.add_special_command('IDN', identity.idn) cmd = "*idn?" answer = _send2input(scpi_obj, cmd) print("\tRequest identification: {0}\n\tAnswer: {1!r}" "".format(cmd, answer)) if answer.strip() != identity.idn(): result = False, "Identification test FAILED" else: result = True, "Identification test PASSED" except Exception as exp: print("\tUnexpected kind of exception! {0}".format(exp)) print_exc() result = False, "Identification test FAILED" _print_footer(result[1]) return result
def check_read_with_params(scpi_obj): _print_header("Attribute read with parameters after the '?'") try: cmd = 'reader:with:parameters' long_test = ArrayTest(100) scpi_obj.add_command(cmd, read_cb=long_test.readRange) answer = _send2input(scpi_obj, "DataFormat ASCII", check_answer=False) correct, failed = 0, 0 for i in range(10): bar, foo = _randint(0, 100), _randint(0, 100) start = min(bar, foo) end = max(bar, foo) # introduce a ' ' (write separator) after the '?' (read separator) cmd_with_params = "{0}?{1:>3},{2}".format(cmd, start, end) try: answer = _send2input( scpi_obj, cmd_with_params, bad_answer='NOK\r\n') except ValueError as exc: msg = "Error: {0}".format(exc) failed += 1 else: msg = "Answer: {0!r} (len ({1:d})" \ "".format(answer, len(answer)) correct += 1 print("\tRequest {0!r}\n\t{1}\n".format(cmd_with_params, msg)) if answer is None or len(answer) == 0: raise ValueError("Empty string") cmd_with_params = "{0}?{1},{2}".format(cmd, start, end) if failed == 0: result = True, "Read with parameters test PASSED" else: print("Failed {0}/{1}".format(failed, correct+failed)) result = False, "Read with parameters test FAILED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Read with parameters test FAILED" _print_footer(result[1]) return result
def check_command_writes(scpi_obj): _print_header("Testing to command writes") try: # simple commands --- current_conf_obj = WattrTest() scpi_obj.add_command('source:current:configure', read_cb=current_conf_obj.readTest, write_cb=current_conf_obj.writeTest) voltage_conf_obj = WattrTest() scpi_obj.add_command('source:voltage:configure', read_cb=voltage_conf_obj.readTest, write_cb=voltage_conf_obj.writeTest) for inner in ['current', 'voltage']: _do_write_command(scpi_obj, "source:{0}:configure".format(inner)) _wait(1) # FIXME: remove # channel commands --- _print_header("Testing to channel command writes") base_cmd = 'writable' w_obj = scpi_obj.add_component(base_cmd, scpi_obj.command_tree) ch_cmd = 'channel' ch_obj = scpi_obj.add_channel(ch_cmd, n_channels, w_obj) ch_current_obj = WchannelTest(n_channels) ch_voltage_obj = WchannelTest(n_channels) for (subcomponent, sub_cmd_obj) in [('current', ch_current_obj), ('voltage', ch_voltage_obj)]: subcomponent_obj = scpi_obj.add_component(subcomponent, ch_obj) for (attr_name, attr_func) in [('upper', 'upperLimit'), ('lower', 'lowerLimit'), ('value', 'readTest')]: if hasattr(sub_cmd_obj, attr_func): if attr_name == 'value': attr_obj = scpi_obj.add_attribute( attr_name, subcomponent_obj, read_cb=sub_cmd_obj.readTest, write_cb=sub_cmd_obj.writeTest, default=True) else: cb_func = getattr(sub_cmd_obj, attr_func) attr_obj = scpi_obj.add_attribute( attr_name, subcomponent_obj, cb_func) print("\nChecking one write multiple reads\n") for i in range(n_channels): rnd_ch = _randint(1, n_channels) element = _random_choice(['current', 'voltage']) _do_write_channel_command( scpi_obj, "{0}:{1}".format(base_cmd, ch_cmd), rnd_ch, element, n_channels) _inter_test_wait() print("\nChecking multile writes multiple reads\n") for i in range(n_channels): test_nwrites = _randint(2, n_channels) rnd_chs = [] while len(rnd_chs) < test_nwrites: rnd_ch = _randint(1, n_channels) while rnd_ch in rnd_chs: rnd_ch = _randint(1, n_channels) rnd_chs.append(rnd_ch) element = _random_choice(['current', 'voltage']) values = [_randint(-1000, 1000)]*test_nwrites _do_write_channel_command( scpi_obj, "{0}:{1}".format(base_cmd, ch_cmd), rnd_chs, element, n_channels, values) _inter_test_wait() print("\nChecking write with allowed values limitation\n") selection_cmd = 'source:selection' selection_obj = WattrTest() selection_obj.writeTest(False) scpi_obj.add_command(selection_cmd, read_cb=selection_obj.readTest, write_cb=selection_obj.writeTest, allowed_argins=[True, False]) _do_write_command(scpi_obj, selection_cmd, True) # _do_write_command(scpi_obj, selection_cmd, 'Fals') # _do_write_command(scpi_obj, selection_cmd, 'True') try: _do_write_command(scpi_obj, selection_cmd, 0) except Exception: print("\tLimitation values succeed because it raises an exception " "as expected") else: raise AssertionError("It has been write a value that " "should not be allowed") _inter_test_wait() result = True, "Command writes test PASSED" except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Command writes test FAILED" _print_footer(result[1]) return result
def add_valid_commands(scpi_obj): _print_header("Testing to build valid commands") try: # ---- valid commands section current_obj = AttrTest() voltage_obj = AttrTest() # * commands can de added by telling their full name: scpi_obj.add_command('source:current:upper', read_cb=current_obj.upperLimit, write_cb=current_obj.upperLimit) scpi_obj.add_command('source:current:lower', read_cb=current_obj.lowerLimit, write_cb=current_obj.lowerLimit) scpi_obj.add_command('source:current:value', read_cb=current_obj.readTest, default=True) scpi_obj.add_command('source:voltage:upper', read_cb=voltage_obj.upperLimit, write_cb=voltage_obj.upperLimit) scpi_obj.add_command('source:voltage:lower', read_cb=voltage_obj.lowerLimit, write_cb=voltage_obj.lowerLimit) scpi_obj.add_command('source:voltage:value', read_cb=voltage_obj.readTest, default=True) scpi_obj.add_command('source:voltage:exception', read_cb=voltage_obj.exceptionTest) # * They can be also created in an iterative way base_cmd_name = 'basicloop' for (sub_cmd_name, sub_cmd_obj) in [('current', current_obj), ('voltage', voltage_obj)]: for (attr_name, attr_func) in [('upper', 'upperLimit'), ('lower', 'lowerLimit'), ('value', 'readTest')]: if hasattr(sub_cmd_obj, attr_func): cb_func = getattr(sub_cmd_obj, attr_func) if attr_name == 'value': default = True else: default = False scpi_obj.add_command("{0}:{1}:{2}".format( base_cmd_name, sub_cmd_name, attr_name), read_cb=cb_func, default=default) # Basically is the same than the first example, # but the add_command is constructed with variables # in nested loops # * Another alternative to create the tree in an iterative way would be it_cmd = 'iterative' it_obj = scpi_obj.add_component(it_cmd, scpi_obj.command_tree) for (subcomponent, sub_cmd_obj) in [('current', current_obj), ('voltage', voltage_obj)]: subcomponent_obj = scpi_obj.add_component(subcomponent, it_obj) for (attr_name, attr_func) in [('upper', 'upperLimit'), ('lower', 'lowerLimit'), ('value', 'readTest')]: if hasattr(sub_cmd_obj, attr_func): cb_func = getattr(sub_cmd_obj, attr_func) if attr_name == 'value': default = True else: default = False attr_obj = scpi_obj.add_attribute( attr_name, subcomponent_obj, cb_func, default=default) else: print("{0} hasn't {1}".format(subcomponent_obj, attr_func)) # In this case, the intermediate objects of the tree are # build and it is in the inner loop where they have the # attributes created. # * Use with very big care this option because the library # * don't guarantee that all the branches of the tree will # * have the appropriate leafs. # * Example of how can be added a node with channels in the scpi tree ch_cmd = 'channel' ch_obj = scpi_obj.add_channel( ch_cmd, n_channels, scpi_obj.command_tree) ch_current_obj = ChannelTest(n_channels) ch_voltage_obj = ChannelTest(n_channels) for (subcomponent, sub_cmd_obj) in [('current', ch_current_obj), ('voltage', ch_voltage_obj)]: subcomponent_obj = scpi_obj.add_component(subcomponent, ch_obj) for (attr_name, attr_func) in [('upper', 'upperLimit'), ('lower', 'lowerLimit'), ('value', 'readTest')]: if hasattr(sub_cmd_obj, attr_func): cb_func = getattr(sub_cmd_obj, attr_func) if attr_name == 'value': default = True else: default = False attr_obj = scpi_obj.add_attribute( attr_name, subcomponent_obj, cb_func, default=default) # * Example of how can be nested channel type components in a tree that # already have this channels componets defined. meas_cmd = 'measurements' meas_obj = scpi_obj.add_component(meas_cmd, ch_obj) fn_cmd = 'function' fn_obj = scpi_obj.add_channel(fn_cmd, n_subchannels, meas_obj) chfn_current_obj = SubchannelTest(n_channels, n_subchannels) chfn_voltage_obj = SubchannelTest(n_channels, n_subchannels) for (subcomponent, sub_cmd_obj) in [('current', chfn_current_obj), ('voltage', chfn_voltage_obj)]: subcomponent_obj = scpi_obj.add_component(subcomponent, fn_obj) for (attr_name, attr_func) in [('upper', 'upperLimit'), ('lower', 'lowerLimit'), ('value', 'readTest')]: if hasattr(sub_cmd_obj, attr_func): cb_func = getattr(sub_cmd_obj, attr_func) if attr_name == 'value': default = True else: default = False attr_obj = scpi_obj.add_attribute( attr_name, subcomponent_obj, cb_func, default=default) print("Command tree build: {!r}".format(scpi_obj.command_tree)) result = True, "Valid commands test PASSED" # TODO: channels with channels until the attributes except Exception as exc: print("\tUnexpected kind of exception! {0}".format(exc)) print_exc() result = False, "Valid commands test FAILED" _print_footer(result[1]) return result