def s3270_nvt_smoke(self, ipv6=False): # Start a thread to read s3270's output. nc = cti.copyserver(ipv6=ipv6) # Start s3270. s3270 = Popen(cti.vgwrap(["s3270", f"a:c:t:{nc.qloopback}:{nc.port}"]), stdin=PIPE, stdout=DEVNULL) self.children.append(s3270) # Feed s3270 some actions. s3270.stdin.write(b"String(abc)\n") s3270.stdin.write(b"Enter()\n") s3270.stdin.write(b"Disconnect()\n") s3270.stdin.write(b"Quit()\n") s3270.stdin.flush() # Make sure they are passed through. out = nc.data() self.assertEqual(b"abc\r\n", out) # Wait for the processes to exit. s3270.stdin.close() self.vgwait(s3270)
def test_nops(self): # Start 'playback' to drive s3270. pport, pts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=pport) as p: pts.close() # Start s3270 with a webserver. sport, sts = cti.unused_port() s3270 = Popen( cti.vgwrap([ "s3270", "-httpd", f"127.0.0.1:{sport}", f"127.0.0.1:{pport}" ])) self.children.append(s3270) self.check_listen(sport) sts.close() # Get to the login screen. p.send_records(4) self.nop(sport, 'Wait(CursorAt,21,13)') self.nop(sport, 'Wait(InputFieldAt,21,13)') self.nop(sport, 'Wait(StringAt,21,13,"___")') requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_s3270_cr(self): # Start 'playback' to read s3270's output. pport, socket = cti.unused_port() with playback.playback(self, 's3270/Test/contention-resolution.trc', port=pport) as p: socket.close() # Start s3270. hport, socket = cti.unused_port() s3270 = Popen(cti.vgwrap(['s3270', '-httpd', str(hport), f"127.0.0.1:{pport}"]), stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) socket.close() # Send initial negotiations and half a screen. p.send_records(6) # Make sure the keyboard remains locked. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/PrintText(string,oia)') self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertIn('X Wait', r.json()['result'][-1], 'Expected Wait') # Send 3270 data with SEND-DATA. p.send_records(1) # Make sure the keyboard is unlocked now. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/PrintText(string,oia)') self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertEqual(' ', r.json()['result'][-1][11:16], 'Expected no lock') # Wait for the processes to exit. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_tcl3270_linger2(self): # Start tcl3270. port, ts = cti.unused_port() tcl3270 = Popen(cti.vgwrap([ "tcl3270", "tcl3270/Test/linger2.tcl", "--", "-httpd", f"127.0.0.1:{port}" ]), stdin=DEVNULL, stdout=DEVNULL) self.children.append(tcl3270) self.check_listen(port) ts.close() # Find the copy of s3270 it is running. tchildren = psutil.Process(tcl3270.pid).children() self.assertEqual(1, len(tchildren)) s3270 = tchildren[0] self.assertEqual('s3270', s3270.name()) # Kill s3270. os.kill(s3270.pid, signal.SIGTERM) # Make sure tcl3270 is gone, too. self.vgwait(tcl3270, assertOnFailure=False) exit_code = tcl3270.wait() self.assertEqual(98, exit_code)
def suffix_test(ti, program, suffix, children): # Create a session file. (handle, file) = tempfile.mkstemp(suffix=suffix) bprogram = program.encode('utf8') os.write(handle, bprogram + b'.termName: foo\n') pfx2 = b'w' + bprogram if sys.platform.startswith('win') else bprogram os.write(handle, pfx2 + b'.model: 3279-3-E\n') os.close(handle) # Start the emulator. port, ts = cti.unused_port() emu = Popen(cti.vgwrap([program, '-httpd', str(port), file]), stdout=DEVNULL) children.append(emu) cti.cti.check_listen(ti, port) ts.close() # Check the output. r = requests.get( f'http://127.0.0.1:{port}/3270/rest/json/Query(TerminalName)') j = r.json() ti.assertEqual('foo', j['result'][0], 'Expecting "foo" as the terminal name') r = requests.get(f'http://127.0.0.1:{port}/3270/rest/json/Set(model)') j = r.json() ti.assertEqual('3279-3-E', j['result'][0], 'Expecting 3279-3-E as the model') # Wait for the process to exit. requests.get(f'http://127.0.0.1:{port}/3270/rest/json/Quit()') cti.cti.vgwait(ti, emu) os.unlink(file)
def test_s3270_ft_cut(self): # Start 'playback' to read s3270's output. port, socket = cti.unused_port() with playback.playback(self, 's3270/Test/ft_cut.trc', port=port) as p: socket.close() # Start s3270. s3270 = Popen(cti.vgwrap( ["s3270", "-model", "2", f"127.0.0.1:{port}"]), stdin=PIPE, stdout=DEVNULL) self.children.append(s3270) # Feed s3270 some actions. s3270.stdin.write( b'transfer direction=send host=vm "localfile=s3270/Test/fttext" "hostfile=ft text a"\n' ) s3270.stdin.write(b"String(logoff)\n") s3270.stdin.write(b"Enter()\n") s3270.stdin.flush() # Verify what s3270 does. p.match() # Wait for the process to exit. s3270.stdin.close() self.vgwait(s3270)
def test_b3270_json_syntax_error(self): b3270 = Popen(cti.vgwrap(['b3270', '-json']), stdin=PIPE, stdout=PIPE, stderr=DEVNULL) self.children.append(b3270) # Feed b3270 an action. b3270.stdin.write( b'{\n"run"\n:{"actiobs"\n:{"action":"set"\n,"args":["startTls"]\n}}?\n' ) # Get the result. out = json.loads( b3270.communicate(timeout=2)[0].split(b'\n')[-2].decode('utf8')) # Wait for the process to exit. b3270.stdin.close() self.vgwait(b3270, assertOnFailure=False) # Check. self.assertTrue('ui-error' in out) ui_error = out['ui-error'] self.assertTrue('fatal' in ui_error) self.assertTrue(ui_error['fatal'])
def test_s3270_socket_json_syntax_error(self): # Start s3270. port, ts = cti.unused_port() s3270 = Popen( cti.vgwrap(['s3270', '-scriptport', str(port), '-scriptportonce'])) self.children.append(s3270) self.check_listen(port) ts.close() # Push a JSON-formatted command at it. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) s.sendall(b'{"foo"}\n') # Decode the result. result = self.recv_to_eof(s, 2).split('\n') s.close() # Wait for the process to exit successfully. self.vgwait(s3270) # Test the output, which is in s3270 format. # This is because JSON parsing is inferred from the first # non-whitespace character on the line, and that guess might be wrong. self.assertEqual(4, len(result)) self.assertTrue(result[0].startswith('data: JSON parse error')) self.assertTrue(result[1].startswith('L U U N N 4 24 80 0 0 0x0 ')) self.assertEqual('error', result[2]) self.assertEqual('', result[3])
def test_s3270_stdin_mode_switch(self): # Start s3270. s3270 = Popen(cti.vgwrap(['s3270']), stdin=PIPE, stdout=PIPE) self.children.append(s3270) # Push s3270, then JSON, then s3270, then JSON at it. s3270.stdin.write(('Set(startTls)' + os.linesep).encode('utf8')) command = (json.dumps({ 'action': 'Set', 'args': ['startTls'] }).replace(' ', os.linesep) + os.linesep).encode('utf8') s3270.stdin.write(command) s3270.stdin.write(('Set(startTls)' + os.linesep).encode('utf8')) s3270.stdin.write(command) # Decode the result. stdout = s3270.communicate()[0].decode('utf8').split(os.linesep) # Wait for the process to exit successfully. self.vgwait(s3270) # Test the output. # First three lines are s3270, next line is JSON, next three are s3270, # last is JSON. self.check_result_s3270(stdout[0:3]) self.check_result_json(stdout[3]) self.check_result_s3270(stdout[4:7]) self.check_result_json(stdout[7])
def s3270_lp_term(self, model, term, override=None): # Start s3270. port, ts = cti.unused_port() args = ['s3270', '-model', model, '-httpd', str(port)] if override != None: args += ['-tn', override] args += ['-e', '/bin/bash', '-c', 's3270/Test/echo_term.bash'] s3270 = Popen(cti.vgwrap(args), stdin=DEVNULL, stdout=DEVNULL) self.check_listen(port) self.children.append(s3270) ts.close() # Wait for the script to exit and get the result. r = requests.get( f'http://127.0.0.1:{port}/3270/rest/json/Wait(Disconnect)', timeout=2) self.assertEqual(requests.codes.ok, r.status_code) r = requests.get( f'http://127.0.0.1:{port}/3270/rest/json/Ascii1(1,1,1,80)') self.assertEqual(requests.codes.ok, r.status_code) j = r.json() self.assertEqual(term, j['result'][0].strip()) requests.get(f'http://127.0.0.1:{port}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_s3270_socket_json_semantic_error(self): # Start s3270. port, ts = cti.unused_port() s3270 = Popen( cti.vgwrap(['s3270', '-scriptport', str(port), '-scriptportonce'])) self.children.append(s3270) self.check_listen(port) ts.close() # Push a JSON-formatted command at it. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) command = json.dumps({'foo': 'bar'}).encode('utf8') + b'\n' s.sendall(command) # Decode the result. result = self.recv_to_eof(s, 2) s.close() # Wait for the process to exit successfully. self.vgwait(s3270) # Test the output. j = json.loads(result) self.assertEqual("Missing object member 'action'", j['result'][0]) self.assertFalse(j['success']) self.assertTrue(j['status'].startswith('L U U N N 4 24 80 0 0 0x0 '))
def test_s3270_sscp_lu(self): # Start 'playback' to emulate the host. pport, socket = cti.unused_port() with playback.playback(self, 's3270/Test/wont-tn3270e.trc', port=pport) as p: socket.close() # Start s3270. hport, socket = cti.unused_port() s3270 = Popen(cti.vgwrap( ['s3270', '-httpd', str(hport), f"127.0.0.1:{pport}"]), stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) socket.close() self.check_listen(hport) # Send negotiations and make sure the responses match, but don't disconnect. p.match(disconnect=False) # Make sure the emulator is in 3270 mode now. r = requests.get( f'http://127.0.0.1:{hport}/3270/rest/json/PrintText(string,oia)' ) self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertEqual('4A ', r.json()['result'][-1][0:3], 'Expected TN3270 mode') # Wait for s3270 to exit. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_x3270if_smoke(self): # Start a copy of s3270 to talk to. port, ts = cti.unused_port() s3270 = Popen(["s3270", "-scriptport", f"127.0.0.1:{port}"], stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) self.check_listen(port) ts.close() # Run x3270if with a trivial query. x3270if = Popen(cti.vgwrap( ["x3270if", "-t", str(port), "Set(startTls)"]), stdout=PIPE) self.children.append(x3270if) # Decode the result. stdout = x3270if.communicate()[0].decode('utf8') # Wait for the processes to exit. s3270.kill() self.children.remove(s3270) s3270.wait() self.vgwait(x3270if) # Test the output. self.assertEqual('true\n', stdout)
def s3270_3270_smoke(self, ipv6=False): # Start 'playback' to read s3270's output. port, ts = cti.unused_port(ipv6=ipv6) with playback.playback(self, 's3270/Test/ibmlink.trc', port=port, ipv6=ipv6) as p: ts.close() # Start s3270. loopback = '[::1]' if ipv6 else '127.0.0.1' s3270 = Popen(cti.vgwrap([ "s3270", "-xrm", "s3270.contentionResolution: false", f'{loopback}:{port}' ]), stdin=PIPE, stdout=DEVNULL) self.children.append(s3270) # Feed s3270 some actions. s3270.stdin.write(b"PF(3)\n") s3270.stdin.write(b"Quit()\n") s3270.stdin.flush() # Make sure the emulator does what we expect. p.match() # Wait for the processes to exit. s3270.stdin.close() self.vgwait(s3270)
def test_s3270_starttls(self): # Start a server to read s3270's output. port, ts = cti.unused_port() with tls_server.tls_server('Common/Test/tls/TEST.crt', 'Common/Test/tls/TEST.key', self, 's3270/Test/ibmlink.trc', port) as server: ts.close() # Start s3270. args = ['s3270', '-xrm', 's3270.contentionResolution: false'] if sys.platform != 'darwin' and not sys.platform.startswith('win'): args += ['-cafile', 'Common/Test/tls/myCA.pem'] args.append(f'127.0.0.1:{port}=TEST') s3270 = Popen(cti.vgwrap(args), stdin=PIPE, stdout=DEVNULL) self.children.append(s3270) # Make sure it all works. server.starttls() s3270.stdin.write(b"PF(3)\n") s3270.stdin.write(b"Quit()\n") s3270.stdin.flush() server.match() # Wait for the process to exit. s3270.stdin.close() self.vgwait(s3270)
def test_s3270_socket_json(self): # Start s3270. port, ts = cti.unused_port() s3270 = Popen( cti.vgwrap(['s3270', '-scriptport', str(port), '-scriptportonce'])) self.children.append(s3270) self.check_listen(port) ts.close() # Push a JSON-formatted command at it. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) command = json.dumps({ 'action': 'Set', 'args': ['startTls'] }).encode('utf8') + b'\n' s.sendall(command) # Decode the result. result = self.recv_to_eof(s, 2) s.close() # Wait for the process to exit successfully. self.vgwait(s3270) # Test the output. self.check_result_json(result)
def test_s3270_sscp_lu(self): # Start 'playback' to read s3270's output. pport, socket = cti.unused_port() with playback.playback(self, 's3270/Test/sscp-lu.trc', port=pport) as p: socket.close() # Start s3270. hport, socket = cti.unused_port() s3270 = Popen(cti.vgwrap(['s3270', '-httpd', str(hport), f"127.0.0.1:{pport}"]), stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) socket.close() # Send initial negotiations and the first SSCP-LU message. p.send_records(21) # Make sure the emulator has switched to SSCP-LU mode. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/PrintText(string,oia)') self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertEqual('4BS', r.json()['result'][-1][0:3], 'Expected SSCP-LU mode') # Send another SSCP-LU and then a regular 3270 record. p.send_records(2) # Make sure the emulator is back to 3270 mode. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/PrintText(string,oia)') self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertEqual('4B ', r.json()['result'][-1][0:3], 'Expected 3270 mode') # Wait for the processes to exit. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_b3270_xml_semantic_error(self): b3270 = Popen(cti.vgwrap(['b3270']), stdin=PIPE, stdout=PIPE) self.children.append(b3270) # Feed b3270 an action. top = ET.Element('b3270-in') ET.SubElement(top, 'run', {'foo': 'bar'}) ET.SubElement(top, 'run', {'actions': 'Wait(0.1,seconds) Quit()'}) *first, _, _ = cti.xml_prettify(top).split(b'\n') b3270.stdin.write(b'\n'.join(first) + b'\n') out = b3270.communicate(timeout=2)[0].decode('utf8').split(os.linesep) self.vgwait(b3270) # Get the result. out_err = out[-4] et_err = ET.fromstring(out_err) # Check. self.assertEqual('ui-error', et_err.tag) attr = et_err.attrib self.assertEqual('false', attr['fatal']) self.assertEqual('missing attribute', attr['text']) self.assertEqual('run', attr['element']) self.assertEqual('actions', attr['attribute'])
def test_b3270_json_split(self): b3270 = Popen(cti.vgwrap(['b3270', '-json']), stdin=PIPE, stdout=PIPE) self.children.append(b3270) # Feed b3270 an action. b3270.stdin.write( b'{\n"run"\n:{"actions"\n:{"action":"set"\n,"args":["startTls"]\n}}}\n' ) # Get the result. out = json.loads( b3270.communicate(timeout=2)[0].split(b'\n')[-2].decode('utf8')) # Wait for the process to exit. b3270.stdin.close() self.vgwait(b3270) # Check. self.assertTrue('run-result' in out) result = out['run-result'] self.assertTrue('success' in result) self.assertTrue(result['success']) self.assertTrue('text' in result) self.assertEqual('true', result['text'][0])
def test_b3270_xml_syntax_error(self): b3270 = Popen(cti.vgwrap(['b3270']), stdin=PIPE, stdout=PIPE, stderr=DEVNULL) self.children.append(b3270) # Feed b3270 junk. top = ET.Element('b3270-in') *first, _, _ = cti.xml_prettify(top).split(b'\n') b3270.stdin.write(b'\n'.join(first) + b'<<>' b'\n') out = b3270.communicate(timeout=2)[0].decode('utf8').split(os.linesep) self.vgwait(b3270, assertOnFailure=False) self.assertTrue(b3270.wait() != 0) # Get the result. out_err = out[-3] et_err = ET.fromstring(out_err) # Wait for the process to exit. b3270.stdin.close() # Check. self.assertEqual('ui-error', et_err.tag) attr = et_err.attrib self.assertEqual('true', attr['fatal']) self.assertTrue(attr['text'].startswith('XML parsing error'))
def b3270_json_socket(self, ipv6=False): # Listen for a connection from b3270. l = cti.listenserver(self, ipv6=ipv6) # Start b3270. b3270 = Popen(cti.vgwrap( ['b3270', '-json', '-callback', f'{l.qloopback}:{l.port}']), stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) self.children.append(b3270) # Wait for it to call back. l.accept(timeout=2) # Feed it multiple commands. l.send(b'{"run":{"actions":"set monoCase"}}\n') l.send(b'{"run":{"actions":"set monoCase"}}\n') l.send(b'{"run":{"actions":"set monoCase"}}\n') # Grab its output. out = l.data(timeout=2).decode('utf8').split('\n') self.assertEqual(5, len(out)) self.assertTrue(out[1].startswith('{"run-result":{')) self.assertTrue(out[2].startswith('{"run-result":{')) self.assertTrue(out[3].startswith('{"run-result":{')) self.assertEqual('', out[4]) self.vgwait(b3270)
def test_b3270_xml_no_input_wrapper(self): # Start b3270. b3270 = Popen(cti.vgwrap(['b3270', '-xml', '-nowrapperdoc']), stdin=PIPE, stdout=PIPE, stderr=DEVNULL) self.children.append(b3270) # Feed it multiple commands. b3270.stdin.write(b'<run actions="set monoCase"/>\n') b3270.stdin.write(b'<run actions="set monoCase"/>\n') b3270.stdin.write(b'<run actions="set monoCase"/>\n') b3270.stdin.flush() # Grab its output. # The primary concern here is that b3270 isn't confused by the missing wrapper # document and embedded newlines in its input. out = b3270.communicate(timeout=2)[0].decode('utf8').split('\n') self.assertEqual(5, len(out)) self.assertTrue(out[1].startswith('<run-result ')) self.assertTrue(out[2].startswith('<run-result ')) self.assertTrue(out[3].startswith('<run-result ')) self.assertEqual('', out[4]) self.vgwait(b3270)
def test_s3270_cp937(self): expect_chinese = [ ' 辦理中止委託轉帳代繳,須提供原代繳帳號,申辦資料如有疑義或不明,經本公司聯繫補', '正資料,請配合提供補正;不願提供者不予受理。 ' ] # Start playback. pport, ts = cti.unused_port() with playback.playback(self, 's3270/Test/937.trc', port=pport) as p: ts.close() # Start s3270. sport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ 's3270', '-httpd', str(sport), '-utf8', '-codepage', 'cp937', f'127.0.0.1:{pport}' ])) self.children.append(s3270) self.check_listen(sport) ts.close() # Fill up the screen. p.send_records(1) # Check the DBCS output. r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Ascii1(2,1,2,80)') self.assertEqual(expect_chinese, r.json()['result']) # Wait for the process to exit successfully. requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_b3270_xml_no_input_wrapper_socket(self): # Listen for a connection from b3270. l = cti.listenserver(self) # Start b3270. b3270 = Popen(cti.vgwrap( ['b3270', '-xml', '-nowrapperdoc', '-callback', str(l.port)]), stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) self.children.append(b3270) # Wait for it to call back. l.accept(timeout=2) # Feed it multiple commands. l.send(b'<run actions="set monoCase"/>\n') l.send(b'<run actions="set monoCase"/>\n') l.send(b'<run actions="set monoCase"/>\n') # Grab its output. # The primary concern here is that b3270 isn't confused by the missing wrapper # document and embedded newlines in its input. out = l.data(timeout=2).decode('utf8').split('\n') self.assertEqual(5, len(out)) self.assertTrue(out[1].startswith('<run-result ')) self.assertTrue(out[2].startswith('<run-result ')) self.assertTrue(out[3].startswith('<run-result ')) self.assertEqual('', out[4]) self.vgwait(b3270)
def test_simple_negatives(self): # Start s3270. port, ts = cti.unused_port() s3270 = Popen(cti.vgwrap(["s3270", "-httpd", f"127.0.0.1:{port}"])) self.children.append(s3270) self.check_listen(port) ts.close() # Syntax tests. self.simple_negative_test(port, 'Wait(CursorAt)', 'requires') self.simple_negative_test(port, 'Wait(CursorAt,1,2,3)', 'requires') self.simple_negative_test(port, 'Wait(CursorAt,fred,joe)', 'Invalid') self.simple_negative_test(port, 'Wait(CursorAt,9999999)', 'Invalid') self.simple_negative_test(port, 'Wait(CursorAt,300,300)', 'Invalid') self.simple_negative_test(port, 'Wait(StringAt)', 'requires') self.simple_negative_test(port, 'Wait(StringAt,1,2,3,4)', 'requires') self.simple_negative_test(port, 'Wait(InputFieldAt)', 'requires') self.simple_negative_test(port, 'Wait(InputFieldAt,1,2,3)', 'requires') # Not-connected tests. self.simple_negative_test(port, 'Wait(CursorAt,0,0)', 'connected') self.simple_negative_test(port, 'Wait(StringAt,0,0,"Hello")', 'connected') self.simple_negative_test(port, 'Wait(InputFieldAt,0,0)', 'connected') # Clean up. requests.get(f'http://127.0.0.1:{port}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_b3270_nvt_xml_smoke(self): # Start 'nc' to read b3270's output. nc = cti.copyserver() # Start b3270. b3270 = Popen(cti.vgwrap(['b3270']), stdin=PIPE, stdout=DEVNULL) self.children.append(b3270) # Feed b3270 some actions. top = ET.Element('b3270-in') ET.SubElement( top, 'run', { 'actions': f'Open(a:c:t:127.0.0.1:{nc.port}) String(abc) Enter() Disconnect()' }) *first, _, _ = cti.xml_prettify(top).split(b'\n') b3270.stdin.write(b'\n'.join(first) + b'\n') b3270.stdin.flush() # Make sure they are passed through. out = nc.data() self.assertEqual(b"abc\r\n", out) # Wait for the processes to exit. b3270.stdin.close() self.vgwait(b3270)
def test_s3270_httpd_persist(self): # Start s3270. port, ts = cti.unused_port() s3270 = Popen(cti.vgwrap(['s3270', '-httpd', str(port)])) self.children.append(s3270) self.check_listen(port) ts.close() # Start a requests session and do a get. # Doing the get within a session keeps the connection alive. s = requests.Session() r = s.get(f'http://127.0.0.1:{port}/3270/rest/json/Set(monoCase)') self.assertEqual(requests.codes.ok, r.status_code) self.assertEqual('false', r.json()['result'][0]) # Do it again. r = s.get(f'http://127.0.0.1:{port}/3270/rest/json/Set(monoCase)') self.assertEqual(requests.codes.ok, r.status_code) self.assertEqual('false', r.json()['result'][0]) # Make sure the connection pool is non-empty. self.assertNotEqual(0, len(r.connection.poolmanager.pools.keys())) # Wait for the process to exit successfully. s.get(f'http://127.0.0.1:{port}/3270/rest/json/Quit()') s.close() self.vgwait(s3270)
def test_s3270_tls_smoke(self): # Start a server to read s3270's output. port, ts = cti.unused_port() with tls_server.tls_server('Common/Test/tls/TEST.crt', 'Common/Test/tls/TEST.key', self, None, port) as server: ts.close() # Start s3270. args = ['s3270'] if sys.platform != 'darwin' and not sys.platform.startswith('win'): args += ['-cafile', 'Common/Test/tls/myCA.pem'] args.append(f'l:a:c:t:127.0.0.1:{port}=TEST') s3270 = Popen(cti.vgwrap(args), stdin=PIPE, stdout=DEVNULL) self.children.append(s3270) # Do the TLS thing. server.wrap() # Feed s3270 some actions. s3270.stdin.write(b"String(abc)\n") s3270.stdin.write(b"Enter()\n") s3270.stdin.write(b"Disconnect()\n") s3270.stdin.write(b"Quit()\n") s3270.stdin.flush() # Make sure they are passed through. out = server.recv_to_end() self.assertEqual(b"abc\r\n", out) # Wait for the process to exit. s3270.stdin.close() self.vgwait(s3270)
def test_x3270_retry_cancel(self): # Find an unused port, but do not listen on it yet. playback_port, pts = cti.unused_port() # Start x3270. hport, hts = cti.unused_port() hts.close() x3270 = Popen( cti.vgwrap([ 'x3270', '-set', 'retry', '-httpd', str(hport), '127.0.0.1:{playback_port}' ])) self.children.append(x3270) # Wait for the Connection Error pop-up to appear. self.try_until(self.find_popup, 4, 'Connect error pop-up did not appear') # Make it stop. os.system( "xdotool search --onlyvisible --name 'x3270 Error' windowfocus mousemove --window %1 42 63 click 1" ) # Verify that x3270 is no longer reconnecting. r = requests.get( f'http://127.0.0.1:{hport}/3270/rest/json/printtext string oia' ).json()['result'] self.assertEqual('X Not Connected', r[-1][7:22]) requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/quit') self.vgwait(x3270) pts.close()
def s3270_httpd_smoke(self, ipv6=False): # Start s3270. port, ts = cti.unused_port(ipv6=ipv6) loopback = '[::1]' if ipv6 else '127.0.0.1' s3270 = Popen(cti.vgwrap(["s3270", "-httpd", f'{loopback}:{port}'])) self.children.append(s3270) self.check_listen(port, ipv6=ipv6) ts.close() # Send it a JSON GET. r = requests.get( f'http://{loopback}:{port}/3270/rest/json/Set(monoCase)') s = r.json() self.assertEqual(s['result'], ['false']) self.assertTrue(s['status'].startswith('L U U N N 4 24 80 0 0 0x0 ')) # Send it a JSON POST. r = requests.post(f'http://{loopback}:{port}/3270/rest/post', json={ 'action': 'set', 'args': ['monoCase'] }) s = r.json() self.assertEqual(s['result'], ['false']) self.assertTrue(s['status'].startswith('L U U N N 4 24 80 0 0 0x0 ')) # Wait for the process to exit. requests.get(f'http://{loopback}:{port}/3270/rest/json/Quit()') self.vgwait(s3270)