1#!/usr/bin/python 2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6 7import copy 8import mock 9import prologix_scpi_driver 10import scpi 11import unittest 12import cellular_logging 13import cellular_system_error 14 15log = cellular_logging.SetupCellularLogging('scpi_test') 16 17# TODO:(byronk): 18# a hack for now. Should look this up in labconfig_data. crbug.com/225108 19# TODO:(byronk): 20# replace SystemError with a specific exception crbug.com/225127 21 22scpi_instruments = [ 23 # Agilent 8960 call box 24 {'name_part': "8960", 'gpib_addr': '14', 'ip': '172.22.50.118'}, 25 # PXT is called 6621 26 {'name_part': "6621", 'gpib_addr': '14', 'ip': "172.22.50.244"} 27] 28 29 30class BasicPrologixTest(unittest.TestCase): 31 """ 32 Basic connection test 33 """ 34 35 def test_bad_ip_address(self): 36 """ 37 Connect to the wrong port and check for the right error message. 38 """ 39 instr = copy.copy(scpi_instruments[0]) 40 instr['ip'] = '192.168.0.0' # str(int(instr['gpib_addr'])+1) 41 log.debug(instr) 42 with self.assertRaises(Exception) as ex: 43 self._get_idns_and_verify(instruments=[instr], opc=True) 44 self.assertIsInstance(ex.exception, 45 cellular_system_error.SocketTimeout) 46 47 def test_ConnectToPortSuccess(self): 48 """ Make a socket connection """ 49 s = scpi_instruments[0] 50 prologix_scpi_driver.connect_to_port(s['ip'], 1234, 5) 51 52 def test_ConnectToPortBadIP(self): 53 """ Make a socket connection """ 54 with self.assertRaises(Exception) as ex: 55 prologix_scpi_driver.connect_to_port('192.168.255.111', 1234, 1) 56 self.assertIsInstance(ex.exception, 57 cellular_system_error.SocketTimeout) 58 59 def test_BadGpibAddress(self): 60 """ 61 How does the code behave if we can't connect. 62 """ 63 instr = copy.copy(scpi_instruments[0]) 64 instr['gpib_addr'] = 9 # str(int(instr['gpib_addr'])+1) 65 with self.assertRaises(Exception) as ex: 66 self._get_idns_and_verify(instruments=[instr], opc=True) 67 self.assertIsInstance(ex.exception, 68 cellular_system_error.InstrumentTimeout) 69 70 @mock.patch.object(prologix_scpi_driver.PrologixScpiDriver, '_DirectQuery') 71 def test_NonClearReadBufferBeforeInit(self, patched_driver): 72 """ 73 Sometimes the Prologix box will have junk in it's read buffer 74 There is code to read the junk out until setting the ++addr works. 75 Test that here. 76 """ 77 s = scpi_instruments[0] 78 patched_driver.side_effect = ['junk1', 'junk2', s['gpib_addr']] 79 driver = prologix_scpi_driver.PrologixScpiDriver( 80 hostname=s['ip'], 81 port=1234, 82 gpib_address=s['gpib_addr'], 83 read_timeout_seconds=2) 84 85 def test_Reset(self): 86 for instr in scpi_instruments: 87 scpi_connection = self._open_prologix(instr, opc_on_stanza=True, 88 read_timeout_seconds=20) 89 scpi_connection.Reset() 90 self.scpi_connection.Close() 91 92 def test_SimpleVerify(self): 93 """ 94 call SimpleVerify. 95 """ 96 # TODO(byronk): make sure this test only runs on the 8960. This 97 # command doesn't work on other boxes 98 for instr in scpi_instruments[:1]: 99 assert instr['name_part'] == '8960' 100 scpi_connection = self._open_prologix(instr, opc_on_stanza=True, 101 read_timeout_seconds=2) 102 # Check to see if the power state is off. 103 # setting most instrument to off should be ok. 104 scpi_connection.SimpleVerify('call:ms:pow:targ', '+0') 105 self.scpi_connection.Close() 106 107 def test_FetchErrors(self): 108 """ 109 call FetchErrors 110 """ 111 for instr in scpi_instruments: 112 scpi_connection = self._open_prologix(instr, opc_on_stanza=True, 113 read_timeout_seconds=2) 114 scpi_connection._WaitAndFetchErrors() 115 self.scpi_connection.Close() 116 117 def test_BadScpiCommand(self): 118 """ 119 Send a bad command. We should fail gracefully. 120 """ 121 for instr in scpi_instruments: 122 scpi_connection = self._open_prologix(instr, opc_on_stanza=True, 123 read_timeout_seconds=1) 124 try: 125 scpi_connection.Query('*IDN') 126 except cellular_system_error.InstrumentTimeout: 127 assert \ 128 "Should have raised a Instrument Timeout on a bad SCPI command" 129 130 def test_ErrorCheckerContextAndStanzaSendingOpcFalse(self): 131 """ 132 Send a stanza, which uses the context manager 133 """ 134 for instr in scpi_instruments: 135 scpi_connection = self._open_prologix(instr, opc_on_stanza=False, 136 read_timeout_seconds=5) 137 scpi_connection.SendStanza(['*WAI']) 138 scpi_connection.Close() 139 140 def test_ErrorCheckerContextAndStanzaSendingOpcTrue(self): 141 """ 142 Send a stanza, which uses the context manager 143 """ 144 for instr in scpi_instruments: 145 scpi_connection = self._open_prologix(instr, opc_on_stanza=True, 146 read_timeout_seconds=5) 147 scpi_connection.SendStanza(['*WAI']) 148 scpi_connection.Close() 149 150 def test_GetIdnOpcTrue(self): 151 """ 152 Test with opc True. OPC= operation complete. Asking this 153 question *OPC? after commands blocks until the command finishes. 154 This prevents us from sending commands faster then then the 155 instrument can handle. True is usually the right setting. 156 157 """ 158 self._get_idns_and_verify(instruments=scpi_instruments, opc=True) 159 160 def test_GetIdnOpcFalse(self): 161 """ 162 Now with OPC off. 163 """ 164 self._get_idns_and_verify(instruments=scpi_instruments, opc=False) 165 166 def _open_prologix(self, instr, opc_on_stanza, read_timeout_seconds=2): 167 """ 168 Build the prologix object. 169 """ 170 ip_addr = instr['ip'] 171 name_part = instr['name_part'] 172 gpib_addr = instr['gpib_addr'] 173 log.debug("trying %s at %s" % (name_part, ip_addr)) 174 driver = prologix_scpi_driver.PrologixScpiDriver( 175 hostname=ip_addr, 176 port=1234, 177 gpib_address=gpib_addr, 178 read_timeout_seconds=read_timeout_seconds) 179 self.scpi_connection = scpi.Scpi(driver) 180 log.debug("setting opc to %s " % opc_on_stanza) 181 self.scpi_connection.opc_on_stanza = opc_on_stanza 182 return self.scpi_connection 183 184 def _get_idns_and_verify(self, instruments, opc=False): 185 """ 186 Get the idn string from all the instruments, and check that it 187 contains the desired substring. This is a quick sanity check only. 188 """ 189 for instr in instruments: 190 scpi_connection = self._open_prologix(instr, opc_on_stanza=opc) 191 response = scpi_connection.Query('*IDN?') 192 log.debug("looking for %s in response string: %s " % 193 (instr['name_part'], response)) 194 assert instr['name_part'] in response 195 self.scpi_connection.Close() 196 197if __name__ == '__main__': 198 unittest.main() 199