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_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_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_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_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 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_b3270_reconnect_interference(self): # Start 'playback' to talk to b3270. playback_port, ts = cti.unused_port() with playback.playback(self, 'c3270/Test/ibmlink2.trc', port=playback_port) as p: ts.close() # Start b3270. hport, ts = cti.unused_port() b3270 = Popen(cti.vgwrap(['b3270', '-set', 'reconnect', '-json', '-httpd', str(hport)]), stdin=PIPE, stdout=PIPE) ts.close() self.children.append(b3270) # Throw away b3270's initialization output. pq = pipeq.pipeq(self, b3270.stdout) pq.get(2, 'b3270 did not start') # Tell b3270 to connect. b3270.stdin.write(f'"open 127.0.0.1:{playback_port}"\n'.encode('utf8')) b3270.stdin.flush() # Wait for b3270 to connect. p.wait_accept() # Asynchronously block for an input field. wait_thread = threading.Thread(target=self.wif, args = [hport]) wait_thread.start() # Wait for the Wait() to block. def wait_block(): r = ''.join(requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Query(Tasks)').json()['result']) return 'Wait("InputField")' in r self.try_until(wait_block, 2, 'Wait() did not block') # Close the connection. p.close() # Wait for the input field thread to complete. wait_thread.join(timeout=2) self.assertFalse(wait_thread.is_alive(), 'Wait thread did not terminate') # Check. self.assertIn('Host disconnected', ''.join(self.wait_result['result'])) # Clean up. b3270.stdin.write(b'"quit"\n') b3270.stdin.flush() b3270.stdin.close() self.vgwait(b3270) pq.close() b3270.stdout.close()
def test_numeric_pr3287_session(self): # Start playback to talk to s3270. pport, ts = cti.unused_port(ipv6=True) with playback.playback(self, 's3270/Test/ibmlink.trc', port=pport, ipv6=True) as p: ts.close() # Create an s3270 session file that starts a fake printer session. handle, sname = tempfile.mkstemp(suffix='.s3270') os.close(handle) handle, tname = tempfile.mkstemp() os.close(handle) with open(sname, 'w') as file: file.write( f's3270.hostname: {setupHosts.test_hostname}:{pport}\n') file.write('s3270.printerLu: .\n') file.write( f's3270.printer.assocCommandLine: echo "%H%" >{tname} && sleep 5\n' ) # Start s3270 with that profile. os.environ['PRINTER_DELAY_MS'] = '1' hport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap(['s3270', '-httpd', str(hport), '-6', sname])) self.children.append(s3270) self.check_listen(hport) ts.close() # Accept the connection and fill the screen. # This will cause s3270 to start up the printer session. p.send_records(4) # Make sure the printer session got started. self.try_until(lambda: os.path.getsize(tname) > 0, 4, 'Printer session not started') with open(tname, 'r') as file: contents = file.readlines() self.assertIn('[::1]', contents[0], 'Expected numeric host') # Wait for the process to exit. requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Quit())') self.vgwait(s3270) os.unlink(sname) os.unlink(tname)
def pr3287_46(self, ipv6=False): # Start 'playback' to feed data to pr3287. port, ts = cti.unused_port() with playback.playback(self, 'pr3287/Test/smoke.trc', port=port, ipv6=ipv6) as p: ts.close() # Start pr3287. (po_handle, po_name) = tempfile.mkstemp() (sy_handle, sy_name) = tempfile.mkstemp() pr3287 = Popen( cti.vgwrap([ "pr3287", '-6' if ipv6 else '-4', "-command", f"cat >'{po_name}'; date >'{sy_name}'", f'{setupHosts.test_hostname}:{port}' ])) self.children.append(pr3287) # Play the trace to pr3287. p.send_to_mark(1, send_tm=False) # Wait for the sync file to appear. self.try_until((lambda: (os.lseek(sy_handle, 0, os.SEEK_END) > 0)), 2, "pr3287 did not produce output") os.close(sy_handle) os.unlink(sy_name) # Wait for the processes to exit. pr3287.kill() self.children.remove(pr3287) self.vgwait(pr3287, assertOnFailure=False) # Read back the file. os.lseek(po_handle, 0, os.SEEK_SET) new_printout = os.read(po_handle, 65536) os.close(po_handle) os.unlink(po_name) # Compare. with open('pr3287/Test/smoke.out', 'rb') as file: ref_printout = file.read() self.assertEqual(new_printout, ref_printout)
def test_tcl3270_smoke(self): # Start 'playback' to feed data to tcl3270. playback_port, ts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=playback_port) as p: ts.close() # Create a temporary file. (handle, name) = tempfile.mkstemp() # Start tcl3270. tcl_port, ts = cti.unused_port() tcl3270 = Popen(cti.vgwrap([ "tcl3270", "tcl3270/Test/smoke.tcl", name, "--", "-xrm", "tcl3270.contentionResolution: false", "-httpd", f"127.0.0.1:{tcl_port}", f"127.0.0.1:{playback_port}" ]), stdin=DEVNULL, stdout=DEVNULL) self.children.append(tcl3270) self.check_listen(tcl_port) ts.close() # Send a screenful to tcl3270. p.send_records(4) # Wait for the file to show up. def Test(): return os.lseek(handle, 0, os.SEEK_END) > 0 self.try_until(Test, 2, "Script did not produce a file") os.close(handle) # Wait for the processes to exit. tcl3270.kill() self.children.remove(tcl3270) self.vgwait(tcl3270, assertOnFailure=False) # Compare the files self.assertTrue(filecmp.cmp(name, 'tcl3270/Test/smoke.txt')) os.unlink(name)
def test_x3270_retry_succeed_5s(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), f'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') # Start playback to accept the connection. with playback.playback(self, 'c3270/Test/ibmlink2.trc', port=playback_port) as p: pts.close() # Wait for x3270 to connect. p.wait_accept(timeout=6) # Wait for the status to update. def connected(): r = requests.get( f'http://127.0.0.1:{hport}/3270/rest/json/query host' ).json()['result'][0] return r == f'host 127.0.0.1 {playback_port}' self.try_until(connected, 2, 'x3270 did not connect') # Make sure the pop-up has popped itself down. self.assertFalse(self.find_popup()) requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/quit') self.vgwait(x3270) pts.close()
def new_wait(self, initial_eors, second_actions, wait_params, p: playback.playback = None, n: int = 0): # Start 'playback' to drive s3270. playback_port, ts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=playback_port) as p: ts.close() # Start s3270 with a webserver. s3270_port, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ "s3270", "-httpd", f"127.0.0.1:{s3270_port}", f"127.0.0.1:{playback_port}" ])) self.children.append(s3270) self.check_listen(s3270_port) ts.close() # Step until the login screen is visible. p.send_records(initial_eors) # In the background, wait for the Wait() action to block, then perform the additional actions. x = threading.Thread(target=self.to_playback, args=(s3270_port, second_actions, p, n)) x.start() # Wait for the change. r = requests.get( f'http://127.0.0.1:{s3270_port}/3270/rest/json/Wait({wait_params})', timeout=2) self.assertEqual(r.status_code, requests.codes.ok) # Wait for the processes to exit. x.join(timeout=2) requests.get(f'http://127.0.0.1:{s3270_port}/3270/rest/json/Quit()') self.vgwait(s3270)
def s3270_japanese(self, codePage): expect_japanese = { 'cp930': [ ' Jァニァトオヘオ ホオヘホ カナネ ウナエオ ニァキオ 930 ', ' 高度な音声信号処理を行う高精度ボイスピックアップテクノロジーにより、高い通話品', '質を実現。 AI による機械学習アルゴリズムで実現されたノイズリダクションシステムが' ], 'cp939': [ ' Japanese test for code page 930 ', ' 高度な音声信号処理を行う高精度ボイスピックアップテクノロジーにより、高い通話品', '質を実現。 AI による機械学習アルゴリズムで実現されたノイズリダクションシステムが' ] } # Start playback. pport, ts = cti.unused_port() with playback.playback(self, 's3270/Test/930.trc', port=pport) as p: ts.close() # Start s3270. sport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ 's3270', '-httpd', str(sport), '-utf8', '-codepage', codePage, 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(1,1,3,80)') self.assertEqual(expect_japanese[codePage], 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_retry_5s(self): # Find an unused port, but do not listen on it yet. playback_port, ts = cti.unused_port() # Start b3270. b3270 = Popen(cti.vgwrap(['b3270', '-set', 'retry', '-json']), stdin=PIPE, stdout=PIPE) self.children.append(b3270) # Throw away b3270's initialization output. pq = pipeq.pipeq(self, b3270.stdout) pq.get(2, 'b3270 did not start') # Tell b3270 to connect. b3270.stdin.write(f'"open 127.0.0.1:{playback_port}"\n'.encode('utf8')) b3270.stdin.flush() # Wait for it to try to connect and fail. out_all = [] while True: out = pq.get(2, 'b3270 did not fail the connection') out_all += [out] if b'connection-error' in out: break outj = json.loads(out.decode('utf8'))['popup'] self.assertTrue(outj['retrying']) self.assertFalse(any(b'run-result' in o for o in out_all), 'Open action should not complete') # Start 'playback' to talk to b3270. with playback.playback(self, 'c3270/Test/ibmlink2.trc', port=playback_port) as p: ts.close() # Wait for b3270 to connect. p.wait_accept(timeout=6) # Clean up. b3270.stdin.write(b'"quit"\n') b3270.stdin.flush() b3270.stdin.close() self.vgwait(b3270) pq.close() b3270.stdout.close()
def test_wc3270_smoke(self): # Start 'playback' to feed wc3270. playback_port, ts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=playback_port) as p: ts.close() # Create a session file. wc3270_port, ts = cti.unused_port() (handle, sname) = tempfile.mkstemp(suffix='.wc3270') os.write(handle, f'wc3270.title: wc3270\n'.encode('utf8')) os.write(handle, f'wc3270.httpd: 127.0.0.1:{wc3270_port}\n'.encode('utf8')) os.write(handle, f'wc3270.hostname: 127.0.0.1:{playback_port}\n'.encode('utf8')) os.close(handle) # Create a shortcut. (handle, lname) = tempfile.mkstemp(suffix='.lnk') os.close(handle) wc3270_dir, wc3270_path = self.find_in_path('wc3270.exe') cmd = f'mkshort {wc3270_dir} wc3270.exe {lname} {sname}' self.assertEqual(0, os.system(cmd)) # Start wc3270 in its own window by starting the link. self.assertEqual(0, os.system(f'start {lname}')) self.check_listen(wc3270_port) ts.close() os.unlink(sname) os.unlink(lname) # Feed wc3270 some data. p.send_records(4) # Dump the window contents. time.sleep(0.5) (handle, name) = tempfile.mkstemp(suffix='.bmp') os.close(handle) requests.get(f'http://127.0.0.1:{wc3270_port}/3270/rest/json/SnapScreen({name})') # Make sure the image is correct. self.assertTrue(filecmp.cmp(name, 'wc3270/Test/ibmlink.bmp') or filecmp.cmp(name, 'wc3270/Test/ibmlink-notfront.bmp'), f'{name} does not match wc3270/Test/ibmlink.bmp or wc3270/Test/ibmlink-notfront.tmp') os.unlink(name)
def test_c3270_prompt_open(self): # Start 'playback' to read s3270's output. playback_port, ts = cti.unused_port() with playback.playback(self, 'c3270/Test/ibmlink2.trc', port=playback_port) as p: ts.close() # Fork a child process with a PTY between this process and it. c3270_port, ts = cti.unused_port() os.environ['TERM'] = 'xterm-256color' (pid, fd) = pty.fork() if pid == 0: # Child process ts.close() os.execvp( cti.vgwrap_ecmd('c3270'), cti.vgwrap_eargs( ['c3270', '-httpd', f'127.0.0.1:{c3270_port}'])) self.assertTrue(False, 'c3270 did not start') # Parent process. # Make sure c3270 started. self.check_listen(c3270_port) ts.close() # Send an Open command to c3270. os.write(fd, f'Open(127.0.0.1:{playback_port})\r'.encode('utf8')) # Write the stream to c3270. p.send_records(7) # Break to the prompt and send a Quit command to c3270. os.write(fd, b'\x1d') time.sleep(0.1) os.write(fd, b'Quit()\r') p.close() self.vgwait_pid(pid)
def test_s3270_cmdline_host_negotiation_error(self): # Start 'playback' to read s3270's output. playback_port, ts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=playback_port) as p: ts.close() # Start s3270. s3270_port, ts = cti.unused_port() s3270 = Popen(cti.vgwrap([ 's3270', '-xrm', 's3270.contentionResolution: false', '-xrm', 's3270.scriptedAlways: true', '-httpd', f'127.0.0.1:{s3270_port}', f'127.0.0.1:{playback_port}' ]), stdin=PIPE, stdout=PIPE, stderr=PIPE) self.children.append(s3270) self.check_listen(s3270_port) ts.close() # Start negotation, but break the connection before drawing the # screen. p.send_records(1) p.disconnect() # Get the result. s3270.stdin.write(b'Quit()\n') out = s3270.communicate(timeout=2) # Wait for the processes to exit. self.vgwait(s3270) # Check. # There should be nothing on stdout, but something on stderr. self.assertTrue(out[0].startswith(b'L U U N N 4 43 80 0 0 0x0 ')) self.assertTrue(out[1].startswith(b'Wait(): Host disconnected'))
def test_s3270_string_no_margin(self): pport, socket = cti.unused_port() with playback.playback(self, 's3270/Test/wrap.trc', pport) as p: self.check_listen(pport) socket.close() # Start s3270. sport, socket = cti.unused_port() s3270 = Popen(cti.vgwrap( ['s3270', '-httpd', str(sport), f'127.0.0.1:{pport}']), stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) self.check_listen(sport) socket.close() # Fill in the screen. p.send_records(2) # Fill the first field, almost. Then fill it with one more byte. requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/String(ffffff)') requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/String(f)') # Make sure the cursor lands in the right spot. r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Query(cursor1)') self.assertEqual(requests.codes.ok, r.status_code) result = r.json()['result'][0] _, row, _, column, *_ = result.split() self.assertEqual(8, int(row), 'Cursor is on the wrong row') self.assertEqual(36, int(column), 'Cursor is on the wrong coluumn') # Wait for the processes to exit. requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_c3270_hosts_file(self): # Set up a hosts file. pport, pts = cti.unused_port() handle, name = tempfile.mkstemp() os.write(handle, f'fubar primary a:c:127.0.0.1:{pport}=gazoo\n'.encode('utf8')) os.close(handle) # Start c3270. hport, ts = cti.unused_port() (pid, fd) = pty.fork() if pid == 0: # Child process ts.close() os.execvp(cti.vgwrap_ecmd('c3270'), cti.vgwrap_eargs(['c3270', '-model', '2', "-utf8", '-httpd', str(hport), '-secure', '-set', f'hostsFile={name}', '-trace'])) self.assertTrue(False, 'c3270 did not start') self.check_listen(hport) ts.close() # Start playback to connect to. with playback.playback(self, 's3270/Test/ibmlink.trc', port=pport) as p: pts.close() # Connect to an alias. r = requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Connect(fubar)') self.assertTrue(r.ok) p.wait_accept() p.close() # Wait for the process to exit. requests.get(f'http://127.0.0.1:{hport}/3270/rest/json/Quit()') self.vgwait_pid(pid) os.close(fd) os.unlink(name)
def test_s3270_no_bid(self): # Start 'playback' to read s3270's output. port, socket = cti.unused_port() with playback.playback(self, 's3270/Test/no_bid.trc', port=port) as p: socket.close() # Start s3270. s3270 = Popen(cti.vgwrap(["s3270", "-xrm", "s3270.contentionResolution: false", f"127.0.0.1:{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() # Verify what s3270 does. p.match() # Wait for the processes to exit. s3270.stdin.close() self.vgwait(s3270)
def s3270_simplified_chinese(self, codePage): expect_chinese = [ ' 国务院总理李克强 2 月 14 日主持召开国务院常务会议,听取 2021 年全国两会建议提', '案办理情况汇报,要求汇聚众智做好今年政府工作;确定促进工业经济平稳增长和服务业特', '殊困难行业纾困发展的措施。 ' ] # Start playback. pport, ts = cti.unused_port() with playback.playback(self, 's3270/Test/935.trc', port=pport) as p: ts.close() # Start s3270. sport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ 's3270', '-httpd', str(sport), '-utf8', '-codepage', codePage, 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,3,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_s3270_apl_code_page(self): apl_chars = [ ' ABCDEFGHI ', ' QRSTUVWXY ', ' bcdefghi ', '⋄∧¨⌻⍸⍷⊢⊣∨ ', '∼ ⎸⎹│ ↑↓≤⌈⌊→', '⎕▌▐▀▄■ ⊃⊂¤○±←', '¯°─• ∩∪⊥[≥∘', '⍺∊⍳⍴⍵ ×\\÷ ∇∆⊤]≠∣', '{⁼+∎└┌├┴§ ⍲⍱⌷⌽⍂⍉', '}⁾-┼┘┐┤┬¶ ⌶!⍒⍋⍞⍝', '≡₁ʂʃ⍤⍥⍪€ ⌿⍀∵⊖⌹⍕', '⁰¹²³⁴⁵⁶⁷⁸⁹ ⍫⍙⍟⍎ ' ] # Start playback. pport, ts = cti.unused_port() with playback.playback(self, 's3270/Test/apl.trc', port=pport) as p: ts.close() # Start s3270. sport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ 's3270', '-httpd', str(sport), '-utf8', 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 SBCS code pages. r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Ascii1(2,2,12,16)') self.assertEqual(apl_chars, 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_s3270_insert_overflow(self): pport, socket = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', pport) as p: self.check_listen(pport) socket.close() # Start s3270. sport, socket = cti.unused_port() s3270 = Popen(cti.vgwrap( ['s3270', '-httpd', str(sport), f'127.0.0.1:{pport}']), stdin=DEVNULL, stdout=DEVNULL) self.children.append(s3270) self.check_listen(sport) socket.close() # Fill in the screen. p.send_records(5) # Fill the first field and go back to its beginning. Then set insert mode. requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/String(ffffffff)') requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Home()') requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Set(insertMode,true)' ) # Now try inserting into the field. This should fail, because it is coming # from a script. r = requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Key(x)') self.assertFalse(r.ok, 'Expected Key() to fail') # Make sure the field has not been modified. r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/AsciiField()') self.assertTrue(r.ok) self.assertEqual('ffffffff', r.json()['result'][0]) # Reset the keyboard and try again, with nofailonerror set, which simulates # the action coming from a keymap. The action should succeed, but they keyboard # should lock, and the field should not be modified. requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Reset()') requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Set(insertMode,true)' ) r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Key(nofailonerror,x)' ) self.assertTrue(r.ok, 'Expected Key(nofailonerror) to succeed') r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/PrintText(string,oia)' ) self.assertTrue(r.ok, 'Expected PrintText()) to succeed') self.assertIn('X Overflow', r.json()['result'][-1], 'Expected overflow') # Make sure the field has not been modified. r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/AsciiField()') self.assertTrue(r.ok) self.assertEqual('ffffffff', r.json()['result'][0]) # Wait for the processes to exit. requests.get(f'http://127.0.0.1:{sport}/3270/rest/json/Quit()') self.vgwait(s3270)
def test_x3270_bad_apl_draw(self): # Start a tightvnc server. # The password file needs to be 0600 or Vnc will prompt for it again. os.chmod('x3270/Test/vnc/.vnc/passwd', stat.S_IREAD | stat.S_IWRITE) cwd = os.getcwd() os.environ['HOME'] = cwd + '/x3270/Test/vnc' os.environ['USER'] = '******' # Set SSH_CONNECTION to keep the VirtualBox extensions from starting in the tightvncserver. os.environ['SSH_CONNECTION'] = 'foo' self.assertEqual(0, os.system('tightvncserver :2 2>/dev/null')) self.check_listen(5902) # Start 'playback' to feed x3270's. playback_port, ts = cti.unused_port() with playback.playback(self, 'x3270/Test/badapl.trc', port=playback_port) as p: self.check_listen(playback_port) ts.close() # Start x3270. os.environ['DISPLAY'] = ':2' x3270_port, ts = cti.unused_port() x3270 = Popen(cti.vgwrap([ 'x3270', '-efont', 'fixed', '-xrm', f'x3270.connectFileName: {os.getcwd()}/x3270/Test/vnc/.x3270connect', '-xrm', 'x3270.colorScheme: old-default', '-httpd', f'127.0.0.1:{x3270_port}', f'127.0.0.1:{playback_port}' ]), stdout=DEVNULL) self.children.append(x3270) self.check_listen(x3270_port) ts.close() # Feed x3270 some data. p.send_lines(4) # Wait for the data to be processed. def is_ready(): r = requests.get( f'http://127.0.0.1:{x3270_port}/3270/rest/json/Query(statsRx)' ) return r.json()['result'][0] == 'bytes 80' self.try_until(is_ready, 2, "NVT data was not processed") # Find x3270's window ID. r = requests.get( f'http://127.0.0.1:{x3270_port}/3270/rest/json/query') wid = r.json()['status'].split()[-2] # Dump the window contents. (handle, name) = tempfile.mkstemp() os.close(handle) self.assertEqual( 0, os.system(f'xwd -id {wid} -silent -nobdrs -out "{name}"')) # Wait for the processes to exit. requests.get(f'http://127.0.0.1:{x3270_port}/3270/rest/json/Quit()') self.vgwait(x3270) self.assertEqual(0, os.system('tightvncserver -kill :2 2>/dev/null')) # Make sure the image is correct. self.assertEqual( 0, os.system(f'cmp -s -i124 {name} x3270/Test/badapl.xwd')) os.unlink(name)
def test_s3270_sbcs_code_page(self): # Start playback. pport, ts = cti.unused_port() with playback.playback(self, 's3270/Test/all_chars.trc', port=pport) as p: ts.close() # Start s3270. sport, ts = cti.unused_port() s3270 = Popen( cti.vgwrap([ 's3270', '-httpd', str(sport), '-utf8', f'127.0.0.1:{pport}' ])) self.children.append(s3270) self.check_listen(sport) ts.close() cp_all_map = { 'cp037': [ ' \xa0âäàáãåçñ¢.<(+|', '&éêëèíîïìß!$*);¬', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ~stuvwxyz¡¿ÐÝÞ®', '^£¥·©§¶¼½¾[]¯¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp273': [ ' \xa0â{àáãåçñÄ.<(+!', '&éêëèíîïì~Ü$*);^', '-/Â[ÀÁÃÅÇÑö,%_>?', 'øÉÊËÈÍÎÏÌ`:#§\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µßstuvwxyz¡¿ÐÝÞ®', '¢£¥·©@¶¼½¾¬|¯¨´×', 'äABCDEFGHI\xadô¦òóõ', 'üJKLMNOPQR¹û}ùúÿ', 'Ö÷STUVWXYZ²Ô\\ÒÓÕ', '0123456789³Û]ÙÚ●' ], 'cp275': [ ' \xa0 É.<(+!', '& $Ç*);^', '-/ ç,%_>?', ' ã:ÕÃ\'="', ' abcdefghi ', ' jklmnopqr ', ' ~stuvwxyz ', ' ', 'õABCDEFGHI ', 'éJKLMNOPQR ', '\\ STUVWXYZ ', '0123456789 ●' ], 'cp277': [ ' \xa0âäàáã}çñ#.<(+!', '&éêëèíîïìߤÅ*);^', '-/ÂÄÀÁÃ$ÇÑø,%_>?', '¦ÉÊËÈÍÎÏÌ`:ÆØ\'="', '@abcdefghi«»ðýþ±', '°jklmnopqrªº{¸[]', 'µüstuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾¬|¯¨´×', 'æABCDEFGHI\xadôöòóõ', 'åJKLMNOPQR¹û~ùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp278': [ ' \xa0â{àáã}çñ§.<(+!', '&`êëèíîïìߤÅ*);^', '-/Â#ÀÁÃ$ÇÑö,%_>?', 'øÉÊËÈÍÎÏÌé:ÄÖ\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ]', 'µüstuvwxyz¡¿ÐÝÞ®', '¢£¥·©[¶¼½¾¬|¯¨´×', 'äABCDEFGHI\xadô¦òóõ', 'åJKLMNOPQR¹û~ùúÿ', '\\÷STUVWXYZ²Ô@ÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp280': [ ' \xa0âä{áãå\\ñ°.<(+!', '&]êë}íîï~ßé$*);^', '-/ÂÄÀÁÃÅÇÑò,%_>?', 'øÉÊËÈÍÎÏÌù:£§\'="', 'Øabcdefghi«»ðýþ±', '[jklmnopqrªºæ¸Æ¤', 'µìstuvwxyz¡¿ÐÝÞ®', '¢#¥·©@¶¼½¾¬|¯¨´×', 'àABCDEFGHI\xadôö¦óõ', 'èJKLMNOPQR¹ûü`úÿ', 'ç÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp284': [ ' \xa0âäàáãåç¦[.<(+|', '&éêëèíîïìß]$*);¬', '-/ÂÄÀÁÃÅÇ#ñ,%_>?', 'øÉÊËÈÍÎÏÌ`:Ñ@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ¨stuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾^!¯~´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp285': [ ' \xa0âäàáãåçñ$.<(+|', '&éêëèíîïìß!£*);¬', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ¯stuvwxyz¡¿ÐÝÞ®', '¢[¥·©§¶¼½¾^]~¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp297': [ ' \xa0âä@áãå\\ñ°.<(+!', '&{êë}íîïìߧ$*);^', '-/ÂÄÀÁÃÅÇÑù,%_>?', 'øÉÊËÈÍÎÏ̵:£à\'="', 'Øabcdefghi«»ðýþ±', '[jklmnopqrªºæ¸Æ¤', '`¨stuvwxyz¡¿ÐÝÞ®', '¢#¥·©]¶¼½¾¬|¯~´×', 'éABCDEFGHI\xadôöòóõ', 'èJKLMNOPQR¹ûü¦úÿ', 'ç÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp424': [ ' אבגדהוזחט¢.<(+|', '&יךכלםמןנס!$*);¬', '-/עףפץצקרש¦,%_>?', ' ת \xa0 ⇔`:#@\'="', ' abcdefghi«» ', '°jklmnopqr ¸ ¤', 'µ~stuvwxyz ®', '^£¥·©§¶¼½¾[]¯¨´×', '{ABCDEFGHI\xad ', '}JKLMNOPQR¹ ', '\\÷STUVWXYZ² ', '0123456789³ ●' ], 'cp500': [ ' \xa0âäàáãåçñ[.<(+!', '&éêëèíîïìß]$*);^', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ~stuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾¬|¯¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp803': [ ' $.<(+|', 'א !¢*);¬', '-/ ,%_>?', ' :#@\'="', ' בגדהוזחטי ', ' ךכלםמןנסע ', ' ףפץצקרשת ', ' ', ' ABCDEFGHI ', ' JKLMNOPQR ', ' STUVWXYZ ', '0123456789 ●' ], 'cp870': [ ' \xa0âäţáăčçć[.<(+!', '&éęëůíîľĺß]$*);^', '-/ÂÄ˝ÁĂČÇĆ|,%_>?', 'ˇÉĘËŮÍÎĽĹ`:#@\'="', '˘abcdefghiśňđýřş', '°jklmnopqrłńš¸˛¤', 'ą~stuvwxyzŚŇĐÝŘŞ', '·ĄżŢŻ§žźŽŹŁŃŠ¨´×', '{ABCDEFGHI\xadôöŕóő', '}JKLMNOPQRĚűüťúě', '\\÷STUVWXYZďÔÖŔÓŐ', '0123456789ĎŰÜŤÚ●' ], 'cp871': [ ' \xa0âäàáãåçñþ.<(+!', '&éêëèíîïìßÆ$*);Ö', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌð:#Ð\'="', 'Øabcdefghi«»`ý{±', '°jklmnopqrªº}¸]¤', 'µöstuvwxyz¡¿@Ý[®', '¢£¥·©§¶¼½¾¬|¯¨\\×', 'ÞABCDEFGHI\xadô~òóõ', 'æJKLMNOPQR¹ûüùúÿ', '´÷STUVWXYZ²Ô^ÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp875': [ ' ΑΒΓΔΕΖΗΘΙ[.<(+!', '&ΚΛΜΝΞΟΠΡΣ]$*);^', '-/ΤΥΦΧΨΩΪΫ ,%_>?', '¨ΆΈΉ∇ΊΌΎΏ`:#@\'="', '΅abcdefghiαβγδεζ', '°jklmnopqrηθικλμ', '´~stuvwxyzνξοπρσ', '£άέήΐίόύΰώςτυφχψ', '{ABCDEFGHI\xadωϊϋ‘―', '}JKLMNOPQR±½ ·’¦', '\\ STUVWXYZ²§ «¬', '0123456789³© »●' ], 'cp880': [ ' \xa0ђѓё ѕіїј[.<(+!', '&љњћќ џЪ№Ђ]$*);^', '-/ЃЁ ЅІЇЈЉ¦,%_>?', 'ЊЋЌ Џюаб :#@\'="', 'цabcdefghiдефгхи', 'йjklmnopqrклмноп', 'я stuvwxyzрстужв', 'ьызшэщчъЮАБЦДЕФГ', ' ABCDEFGHIХИЙКЛМ', ' JKLMNOPQRНОПЯРС', '\\¤STUVWXYZТУЖВЬЫ', '0123456789ЗШЭЩЧ●' ], 'cp1026': [ ' \xa0âäàáãå{ñÇ.<(+!', '&éêëèíîïìßĞİ*);^', '-/ÂÄÀÁÃÅ[Ñş,%_>?', "øÉÊËÈÍÎÏÌı:ÖŞ'=Ü", 'Øabcdefghi«»}`¦±', '°jklmnopqrªºæ˛Æ¤', 'µöstuvwxyz¡¿]$@®', '¢£¥·©§¶¼½¾¬|—¨´×', 'çABCDEFGHI\xadô~òóõ', 'ğJKLMNOPQR¹û\\ùúÿ', 'ü÷STUVWXYZ²Ô#ÒÓÕ', '0123456789³Û"ÙÚ●' ], 'cp1047': [ ' \xa0âäàáãåçñ¢.<(+|', '&éêëèíîïìß!$*);^', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ~stuvwxyz¡¿Ð[Þ®', '¬£¥·©§¶¼½¾Ý¨¯]´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1140': [ ' \xa0âäàáãåçñ¢.<(+|', '&éêëèíîïìß!$*);¬', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ€', 'µ~stuvwxyz¡¿ÐÝÞ®', '^£¥·©§¶¼½¾[]¯¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1141': [ ' \xa0â{àáãåçñÄ.<(+!', '&éêëèíîïì~Ü$*);^', '-/Â[ÀÁÃÅÇÑö,%_>?', 'øÉÊËÈÍÎÏÌ`:#§\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ€', 'µßstuvwxyz¡¿ÐÝÞ®', '¢£¥·©@¶¼½¾¬|¯¨´×', 'äABCDEFGHI\xadô¦òóõ', 'üJKLMNOPQR¹û}ùúÿ', 'Ö÷STUVWXYZ²Ô\\ÒÓÕ', '0123456789³Û]ÙÚ●' ], 'cp1142': [ ' \xa0âäàáã}çñ#.<(+!', '&éêëèíîïì߀Å*);^', '-/ÂÄÀÁÃ$ÇÑø,%_>?', '¦ÉÊËÈÍÎÏÌ`:ÆØ\'="', '@abcdefghi«»ðýþ±', '°jklmnopqrªº{¸[]', 'µüstuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾¬|¯¨´×', 'æABCDEFGHI\xadôöòóõ', 'åJKLMNOPQR¹û~ùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1143': [ ' \xa0â{àáã}çñ§.<(+!', '&`êëèíîïì߀Å*);^', '-/Â#ÀÁÃ$ÇÑö,%_>?', 'ø\\ÊËÈÍÎÏÌé:ÄÖ\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ]', 'µüstuvwxyz¡¿ÐÝÞ®', '¢£¥·©[¶¼½¾¬|¯¨´×', 'äABCDEFGHI\xadô¦òóõ', 'åJKLMNOPQR¹û~ùúÿ', 'É÷STUVWXYZ²Ô@ÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1144': [ ' \xa0âä{áãå\\ñ°.<(+!', '&]êë}íîï~ßé$*);^', '-/ÂÄÀÁÃÅÇÑò,%_>?', 'øÉÊËÈÍÎÏÌù:£§\'="', 'Øabcdefghi«»ðýþ±', '[jklmnopqrªºæ¸Æ€', 'µìstuvwxyz¡¿ÐÝÞ®', '¢#¥·©@¶¼½¾¬|¯¨´×', 'àABCDEFGHI\xadôö¦óõ', 'èJKLMNOPQR¹ûü`úÿ', 'ç÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1145': [ ' \xa0âäàáãåç¦[.<(+|', '&éêëèíîïìß]$*);¬', '-/ÂÄÀÁÃÅÇ#ñ,%_>?', 'øÉÊËÈÍÎÏÌ`:Ñ@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ€', 'µ¨stuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾^!¯~´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1146': [ ' \xa0âäàáãåçñ$.<(+|', '&éêëèíîïìß!£*);¬', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ€', 'µ¯stuvwxyz¡¿ÐÝÞ®', '¢[¥·©§¶¼½¾^]~¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1147': [ ' \xa0âä@áãå\\ñ°.<(+!', '&{êë}íîïìߧ$*);^', '-/ÂÄÀÁÃÅÇÑù,%_>?', 'øÉÊËÈÍÎÏ̵:£à\'="', 'Øabcdefghi«»ðýþ±', '[jklmnopqrªºæ¸Æ€', '`¨stuvwxyz¡¿ÐÝÞ®', '¢#¥·©]¶¼½¾¬|¯~´×', 'éABCDEFGHI\xadôöòóõ', 'èJKLMNOPQR¹ûü¦úÿ', 'ç÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1148': [ ' \xa0âäàáãåçñ[.<(+!', '&éêëèíîïìß]$*);^', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ€', 'µ~stuvwxyz¡¿ÐÝÞ®', '¢£¥·©§¶¼½¾¬|¯¨´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1149': [ ' \xa0âäàáãåçñÞ.<(+!', '&éêëèíîïìßÆ$*);Ö', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌð:#Ð\'="', 'Øabcdefghi«»`ý{±', '°jklmnopqrªº}¸]€', 'µöstuvwxyz¡¿@Ý[®', '¢£¥·©§¶¼½¾¬|¯¨\\×', 'þABCDEFGHI\xadô~òóõ', 'æJKLMNOPQR¹ûüùúÿ', '´÷STUVWXYZ²Ô^ÒÓÕ', '0123456789³ÛÜÙÚ●' ], 'cp1160': [ ' \xa0กขฃคฅฆง[¢.<(+|', '&่จฉชซฌญฎ]!$*);¬', '-/ฏฐฑฒณดต^¦,%_>?', '฿๎ถทธนบปผ`:#@\'="', '๏abcdefghiฝพฟภมย', '๚jklmnopqrรฤลฦวศ', '๛~stuvwxyzษสหฬอฮ', '๐๑๒๓๔๕๖๗๘๙ฯะัาำิ', '{ABCDEFGHI้ีึืุู', '}JKLMNOPQRฺเแโใไ', '\\๊STUVWXYZๅๆ็่้๊', '0123456789๋์ํ๋€●' ], 'bracket': [ ' \xa0âäàáãåçñ¢.<(+|', '&éêëèíîïìß!$*);¬', '-/ÂÄÀÁÃÅÇѦ,%_>?', 'øÉÊËÈÍÎÏÌ`:#@\'="', 'Øabcdefghi«»ðýþ±', '°jklmnopqrªºæ¸Æ¤', 'µ~stuvwxyz¡¿Ð[Þ®', '^£¥·©§¶¼½¾Ý¨¯]´×', '{ABCDEFGHI\xadôöòóõ', '}JKLMNOPQR¹ûüùúÿ', '\\÷STUVWXYZ²ÔÖÒÓÕ', '0123456789³ÛÜÙÚ●' ] } # Fill up the screen. p.send_records(1) # Check the SBCS code pages. for cp in cp_all_map.keys(): requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Set(codePage,{cp})' ) r = requests.get( f'http://127.0.0.1:{sport}/3270/rest/json/Ascii1(2,2,12,16)' ) self.assertEqual(cp_all_map[cp], 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_x3270_smoke(self): # Start a tightvnc server. # The password file needs to be 0600 or Vnc will prompt for it again. os.chmod('x3270/Test/vnc/.vnc/passwd', stat.S_IREAD | stat.S_IWRITE) cwd = os.getcwd() os.environ['HOME'] = cwd + '/x3270/Test/vnc' os.environ['USER'] = '******' # Set SSH_CONNECTION to keep the VirtualBox extensions from starting in the tightvncserver. os.environ['SSH_CONNECTION'] = 'foo' self.assertEqual(0, os.system('tightvncserver :2 2>/dev/null')) self.check_listen(5902) # Start 'playback' to feed x3270. playback_port, ts = cti.unused_port() with playback.playback(self, 's3270/Test/ibmlink.trc', port=playback_port) as p: self.check_listen(playback_port) ts.close() # Set up the fonts. os.environ['DISPLAY'] = ':2' obj = os.path.abspath(os.path.split(shutil.which('x3270'))[0]) self.assertEqual(0, os.system(f'mkfontdir {obj}')) self.assertEqual(0, os.system(f'xset +fp {obj}/')) self.assertEqual(0, os.system('xset fp rehash')) # Start x3270. x3270_port, ts = cti.unused_port() x3270 = Popen(cti.vgwrap([ "x3270", "-xrm", f"x3270.connectFileName: {os.getcwd()}/x3270/Test/vnc/.x3270connect", "-xrm", "x3270.colorScheme: old-default", "-httpd", f"127.0.0.1:{x3270_port}", f"127.0.0.1:{playback_port}" ]), stdout=DEVNULL) self.children.append(x3270) self.check_listen(x3270_port) ts.close() # Feed x3270 some data. p.send_records(4) # Find x3270's window ID. r = requests.get( f'http://127.0.0.1:{x3270_port}/3270/rest/json/query') wid = r.json()['status'].split()[-2] # Dump the window contents. (handle, name) = tempfile.mkstemp() os.close(handle) self.assertEqual( 0, os.system(f'xwd -id {wid} -silent -nobdrs -out "{name}"')) # Wait for the process to exit. requests.get(f'http://127.0.0.1:{x3270_port}/3270/rest/json/Quit()') self.vgwait(x3270) self.assertEqual(0, os.system('tightvncserver -kill :2 2>/dev/null')) # Make sure the image is correct. self.assertEqual( 0, os.system(f'cmp -s -i124 {name} x3270/Test/ibmlink.xwd')) os.unlink(name)