Exemple #1
0
    def test_b3270_json_seconds(self):

        b3270 = Popen(cti.vgwrap(['b3270', '-json']), stdin=PIPE, stdout=PIPE)
        self.children.append(b3270)

        # Feed b3270 an action.
        j = {"run": {"actions": {"action": "Wait", "args": [0.1, "Seconds"]}}}
        b3270.stdin.write(json.dumps(j).encode('utf8') + b'\n')
        b3270.stdin.flush()

        # Get the result.
        pq = pipeq.pipeq(self, b3270.stdout)
        while True:
            line = pq.get(2, 'b3270 did not produce expected output')
            self.assertNotEqual(b'', line)
            if b'run-result' in line:
                break
        out = json.loads(line.decode('utf8'))

        # Wait for the processes to exit.
        b3270.stdin.close()
        b3270.stdout.close()
        self.vgwait(b3270)
        pq.close()

        # Check.
        run_result = out['run-result']
        self.assertTrue(run_result['success'])
        self.assertTrue(run_result['time'] >= 0.1)
Exemple #2
0
    def test_b3270_passthru_json(self):

        b3270 = Popen(cti.vgwrap(['b3270', '-json']), stdin=PIPE, stdout=PIPE)
        self.children.append(b3270)

        # Get the initial dump.
        b3270.stdout.readline().decode('utf8')

        # Register the Foo action and run it.
        b3270.stdin.write(b'{"register":{"name":"Foo"}}\n')
        b3270.stdin.flush()
        b3270.stdin.write(
            b'{"run":{"r-tag":"abc","actions":{"action":"Foo","args":["a","b"]}}}\n'
        )
        b3270.stdin.flush()

        # Get the result.
        pq = pipeq.pipeq(self, b3270.stdout)
        out = json.loads(
            pq.get(2, 'b3270 did not produce expected output').decode('utf8'))
        self.assertTrue('passthru' in out)
        passthru = out['passthru']
        self.assertTrue('action' in passthru)
        action = passthru['action']
        self.assertEqual('Foo', action)
        self.assertTrue('p-tag' in passthru)
        p_tag = passthru['p-tag']
        self.assertTrue('parent-r-tag' in passthru)
        self.assertEqual('abc', passthru['parent-r-tag'])
        self.assertTrue('args' in passthru)
        self.assertEqual(['a', 'b'], passthru['args'])

        # Make the action succeed.
        succeed = {"succeed": {"p-tag": p_tag, "text": ["hello", "there"]}}
        b3270.stdin.write(json.dumps(succeed).encode('utf8') + b'\n')
        b3270.stdin.flush()

        # Get the result of that.
        out = json.loads(
            pq.get(2, 'b3270 did not produce expected output').decode('utf8'))
        self.assertTrue('run-result' in out)
        run_result = out['run-result']
        self.assertTrue('r-tag' in run_result)
        self.assertEqual('abc', run_result['r-tag'])
        self.assertTrue('success' in run_result)
        self.assertTrue(run_result['success'])
        self.assertTrue('text' in run_result)
        self.assertEqual(['hello', 'there'], run_result['text'])

        # Wait for the process to exit.
        b3270.stdin.close()
        b3270.stdout.close()
        self.vgwait(b3270)
        pq.close()
Exemple #3
0
    def test_b3270_passthru_xml(self):

        b3270 = Popen(cti.vgwrap(['b3270']), stdin=PIPE, stdout=PIPE)
        self.children.append(b3270)

        # Get the initial dump.
        pq = pipeq.pipeq(self, b3270.stdout)
        while True:
            line = pq.get(2, 'b3270 did not initialize').decode('utf8')
            if '</initialize>' in line:
                break

        # Register the Foo action and run it.
        top = ET.Element('b3270-in')
        ET.SubElement(top, 'register', {'name': 'Foo'})
        ET.SubElement(top, 'run', {'r-tag': 'abc', 'actions': "Foo(a,b)"})
        *first, _, _ = cti.xml_prettify(top).split(b'\n')
        b3270.stdin.write(b'\n'.join(first) + b'\n')
        b3270.stdin.flush()

        # Get the result.
        s = pq.get(2, 'b3270 did not produce expected output').decode('utf8')
        out = ET.fromstring(s)
        self.assertEqual('passthru', out.tag)
        attr = out.attrib
        tag = attr['p-tag']
        self.assertEqual('abc', attr['parent-r-tag'])
        self.assertEqual('a', attr['arg1'])
        self.assertEqual('b', attr['arg2'])
        self.assertFalse('arg3' in attr)

        # Make the action succeed.
        succeed = ET.Element('succeed', {'p-tag': tag, 'text': 'hello\nthere'})
        b3270.stdin.write(ET.tostring(succeed) + b'\n')
        b3270.stdin.flush()

        # Get the result of that.
        s = pq.get(2, 'b3270 did not produce expected output').decode('utf8')
        out = ET.fromstring(s)
        self.assertEqual('run-result', out.tag)
        attr = out.attrib
        self.assertEqual('abc', attr['r-tag'])
        self.assertEqual('true', attr['success'])
        self.assertEqual('hello\nthere', attr['text'])

        # Wait for the process to exit.
        b3270.stdin.write(b'</b3270-in>\n')
        b3270.stdin.close()
        b3270.stdout.close()
        self.vgwait(b3270)
        pq.close()
Exemple #4
0
    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()
Exemple #5
0
    def test_b3270_xml_multiple(self):

        b3270 = Popen(cti.vgwrap(['b3270']), stdin=PIPE, stdout=PIPE)
        self.children.append(b3270)

        # Feed b3270 two actions, which it will run concurrently and complete
        # in reverse order.
        top = ET.Element('b3270-in')
        ET.SubElement(top, 'run', {
            'actions': 'Wait(0.1,seconds) Set(startTls) Quit()',
            'r-tag': 'tls'
        })
        ET.SubElement(top, 'run', {
            'actions': 'Set(insertMode)',
            'r-tag': 'ins'
        })
        *first, _, _ = cti.xml_prettify(top).split(b'\n')
        b3270.stdin.write(b'\n'.join(first) + b'\n')
        b3270.stdin.flush()

        # Get the result.
        errmsg = 'b3270 did not produce the expected output'
        pq = pipeq.pipeq(self, b3270.stdout)
        pq.get(2, errmsg)
        pq.get(2, errmsg)
        pq.get(2, errmsg)
        out = pq.get(2, errmsg).decode('utf8')
        et_ins = ET.fromstring(out)
        out = pq.get(2, errmsg).decode('utf8')
        et_tls = ET.fromstring(out)
        self.vgwait(b3270)
        pq.close()
        b3270.stdin.close()
        b3270.stdout.close()

        # Check.
        self.assertEqual('run-result', et_ins.tag)
        att_ins = et_ins.attrib
        self.assertEqual('ins', att_ins['r-tag'])
        self.assertEqual('true', att_ins['success'])
        self.assertEqual('false', att_ins['text'])

        self.assertEqual('run-result', et_tls.tag)
        att_tls = et_tls.attrib
        self.assertEqual('tls', att_tls['r-tag'])
        self.assertEqual('true', att_tls['success'])
        self.assertEqual('true', att_tls['text'])
Exemple #6
0
    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()
Exemple #7
0
    def test_b3270_json_multiple(self):

        b3270 = Popen(cti.vgwrap(['b3270', '-json']), stdin=PIPE, stdout=PIPE)
        self.children.append(b3270)

        # Feed b3270 two sets of actions, which it will run concurrently and complete
        # in reverse order.
        b3270.stdin.write(
            b'"Wait(0.1,seconds) Set(startTls) Quit()" "Set(insertMode)"\n')
        b3270.stdin.flush()

        # Get the output before waiting for b3270 to exit. Otherwise it
        # hangs trying to write to its stdout (on Windows).
        # Individual timed reads are used here because communicate() closes stdin and that will
        # cause b3270 to exit prematurely.
        errmsg = 'b3270 did not produce expected output'
        pq = pipeq.pipeq(self, b3270.stdout)
        pq.get(2, errmsg)
        insert_mode = json.loads(pq.get(2, errmsg).decode('utf8'))
        start_tls = json.loads(pq.get(2, errmsg).decode('utf8'))
        b3270.stdin.close()
        b3270.stdout.close()
        self.vgwait(b3270)
        pq.close()

        # Check.
        self.assertTrue('run-result' in insert_mode)
        result = insert_mode['run-result']
        self.assertTrue('success' in result)
        self.assertTrue(result['success'])
        self.assertTrue('text' in result)
        self.assertEqual('false', result['text'][0])

        self.assertTrue('run-result' in start_tls)
        result = start_tls['run-result']
        self.assertTrue('success' in result)
        self.assertTrue(result['success'])
        self.assertTrue('text' in result)
        self.assertEqual('true', result['text'][0])
Exemple #8
0
    def test_b3270_xml_seconds(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', {'actions': "Wait(0.2,Seconds)"})
        *first, _, _ = cti.xml_prettify(top).split(b'\n')
        b3270.stdin.write(b'\n'.join(first) + b'\n')
        b3270.stdin.flush()

        # Get the result.
        pq = pipeq.pipeq(self, b3270.stdout)
        output = b''
        while True:
            line = pq.get(2, 'b3270 did not produce expected output')
            self.assertNotEqual(b'', line)
            output += line
            if b'run-result' in line:
                break
        output += b'</b3270-out>'  # a white lie
        out = ET.fromstring(output.decode('utf8'))

        # Wait for the processes to exit.
        b3270.stdin.write(b'</b3270-in>\n')
        b3270.stdin.close()
        b3270.stdout.close()
        self.vgwait(b3270)
        pq.close()

        # Check.
        a = out.find('./run-result')
        self.assertTrue(a != None)
        att = a.attrib
        self.assertTrue(att['success'])
        self.assertTrue(float(att['time']) >= 0.1)