def push(self, username=None, password=None): if not self.repo_is_defined: error("No Git repository found for the current directory.") self.repo.git.push() return try: pexpect.spawnu('git push') except: try: self.repo.git.push() print("Push was successful") except Exception as e: error("Git push failed!") print(type(e)) return try: g.logfile_read = sys.stdout if not username: username = '' if not password: password = '' while True: i = g.expect([u'Username for .*', u'Password for .*', pexpect.EOF]) if(i == 0): g.send(username+'\n') elif(i == 1): # Python 2 # g.send(codecs.decode(password, 'base64')+'\n') # End Python 2 # Python 3 g.send(str(codecs.decode(password.encode(), 'base64'), 'utf-8')+'\n') # End Python 3 else: break except: print("Notice: Auto-credentials currently not operational") '''
def test_default_eclipse_adt_install(self): """Install eclipse adt from scratch test case""" self.child = pexpect.spawnu(self.command('{} android eclipse-adt'.format(UDTC))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[I Accept.*\]") # ensure we have a license question self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher and an icon file self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.path_exists(get_icon_path(self.icon_filename))) self.assertTrue(self.is_in_path("adb")) self.assertTrue(self.is_in_path("ddms")) # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # on 64 bits, there is a java subprocess, we kill that one with SIGKILL (eclipse isn't reliable on SIGTERM) if self.arch_option == "x86_64": self.check_and_kill_process(["java", self.arch_option, self.installed_path], wait_before=self.TIMEOUT_START, send_sigkill=True) else: self.check_and_kill_process([self.exec_path], wait_before=self.TIMEOUT_START, send_sigkill=True) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} android eclipse-adt'.format(UDTC))) self.expect_and_no_warn("Eclipse ADT is already installed.*\[.*\] ") self.child.sendline() self.wait_and_no_warn()
def test_tcpv6_send(board_group, application, env=None): env_client = os.environ.copy() if env != None: env_client.update(env) env_client.update(board_group.boards[0].to_env()) env_server = os.environ.copy() if env != None: env_server.update(env) env_server.update(board_group.boards[1].to_env()) with pexpect.spawnu("make", ["-C", application, "term"], env=env_client, timeout=DEFAULT_TIMEOUT) as client, \ pexpect.spawnu("make", ["-C", application, "term"], env=env_server, timeout=DEFAULT_TIMEOUT) as server: port = random.randint(0x0000, 0xffff) server_ip = get_ipv6_address(server) client_ip = get_ipv6_address(client) server.sendline(u"tcp server start %d" % port) # wait for neighbor discovery to be done time.sleep(5) client.sendline(u"tcp connect %s %d" % (server_ip, port)) server.expect(u"TCP client \\[%s\\]:[0-9]+ connected" % client_ip) client.sendline(u"tcp send affe:abe") client.expect_exact(u"Success: send 4 byte over TCP to server") server.expect(u"00000000 AF FE AB E0") client.sendline(u"tcp disconnect") client.sendline(u"tcp send affe:abe") client.expect_exact(u"could not send")
def test_adt_reinstall_other_non_empty_path(self): """Reinstall eclipse adt on another path (non empty) once installed should remove the first version""" original_install_path = self.installed_path if not self.in_container: self.reinstalled_path = tempfile.mkdtemp() else: # we still give a path for the container self.reinstalled_path = os.path.join(tempfile.gettempdir(), "tmptests") self.create_file(os.path.join(self.reinstalled_path, "bar"), "foo") for loop in ("install", "reinstall"): if loop == "reinstall": self.installed_path = self.reinstalled_path self.child = pexpect.spawnu(self.command('{} android eclipse-adt {}'.format(UDTC, self.installed_path))) self.expect_and_no_warn("Eclipse ADT is already installed.*\[.*\] ") self.child.sendline("y") self.expect_and_no_warn("{} isn't an empty directory.*there\? \[.*\] ".format(self.installed_path)) self.child.sendline("y") else: self.child = pexpect.spawnu(self.command('{} android eclipse-adt'.format(UDTC))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[.*\] ") self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.path_exists(get_icon_path(self.icon_filename))) # ensure that version first isn't installed anymore self.assertFalse(self.path_exists(original_install_path))
def test_adt_reinstall_other_path(self): """Reinstall eclipse adt on another path once installed should remove the first version""" original_install_path = self.installed_path for loop in ("install", "reinstall"): if loop == "reinstall": self.installed_path = "/tmp/foo" self.child = pexpect.spawnu(self.command('{} android eclipse-adt {}'.format(UDTC, self.installed_path))) self.expect_and_no_warn("Eclipse ADT is already installed.*\[.*\] ") self.child.sendline("y") else: self.child = pexpect.spawnu(self.command('{} android eclipse-adt'.format(UDTC))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[.*\] ") self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.path_exists(get_icon_path(self.icon_filename))) # ensure that version first isn't installed anymore self.assertFalse(self.path_exists(original_install_path))
def test_default_install(self): """Install visual studio from scratch test case""" self.child = pexpect.spawnu(self.command('{} web visual-studio-code'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[I Accept.*\]") # ensure we have a license question self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher and an icon file self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assert_exec_exists() self.assert_icon_exists() # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.check_and_kill_process(["Code", self.installed_path], wait_before=self.TIMEOUT_START, send_sigkill=True) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} web visual-studio-code'.format(UMAKE))) self.expect_and_no_warn("Visual Studio Code is already installed.*\[.*\] ") self.child.sendline() self.wait_and_no_warn()
def test_default_stencyl_install(self): """Install stencyl from scratch test case""" self.child = pexpect.spawnu(self.command('{} games stencyl'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assert_exec_exists() self.assert_icon_exists() # launch it, send SIGTERM and check that it exits fine use_cwd = self.installed_path if self.in_container: use_cwd = None proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=use_cwd) self.check_and_kill_process(["./runtimes/jre-linux/bin/java"], wait_before=self.TIMEOUT_START) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} games stencyl'.format(UMAKE))) self.expect_and_no_warn("Stencyl is already installed.*\[.*\] ") self.child.sendline() self.wait_and_no_warn()
def test_default_install(self): """Install the distribution from scratch test case""" self.child = pexpect.spawnu(self.command('{} ide arduino'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_close() # we have an installed launcher, added to the launcher and an icon file self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assert_exec_exists() self.assert_icon_exists() self.assertTrue(self.is_in_group("dialout")) # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.check_and_kill_process(["java", "processing.app.Base"], wait_before=self.TIMEOUT_START) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} ide arduino'.format(UMAKE))) self.expect_and_no_warn("Arduino is already installed.*\[.*\] ") self.child.sendline() self.wait_and_close()
def test_default_android_studio_install(self): """Install android studio from scratch test case""" self.child = pexpect.spawnu(self.command('{} android android-studio'.format(UDTC))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[I Accept.*\]") # ensure we have a license question self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.is_in_path("adb")) self.assertTrue(self.is_in_path("ddms")) # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.check_and_kill_process(["java", self.installed_path], wait_before=self.TIMEOUT_START) self.assertEquals(proc.wait(self.TIMEOUT_STOP), 0) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} android android-studio'.format(UDTC))) self.expect_and_no_warn("Android Studio is already installed.*\[.*\] ") self.child.sendline() self.wait_and_no_warn()
def test_default_android_sdk_install(self): """Install android sdk from scratch test case""" self.child = pexpect.spawnu(self.command('{} android android-sdk'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[I Accept.*\]") # ensure we have a license question self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_close() # we have an installed sdk exec self.assert_exec_exists() self.assertTrue(self.is_in_path(self.exec_path)) # launch it, send SIGTERM and check that it exits fine self.assertEqual(subprocess.check_call(self.command_as_list([self.exec_path, "list"]), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL), 0) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} android android-sdk'.format(UMAKE))) self.expect_and_no_warn("Android SDK is already installed.*\[.*\] ") self.child.sendline() self.wait_and_close()
def test_default_install(self): """Install from scratch test case""" self.child = pexpect.spawnu(self.command('{} ide pycharm'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() logger.info("Installed, running...") # we have an installed launcher, added to the launcher and an icon file self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.path_exists(self.full_icon_path)) # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.check_and_kill_process(["java", self.installed_path], wait_before=self.TIMEOUT_START) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} ide pycharm'.format(UMAKE))) self.expect_and_no_warn("PyCharm is already installed.*\[.*\] ") self.child.sendline() self.wait_and_no_warn()
def test_default_unity3D_install(self): """Install unity3D editor from scratch test case""" # only an amd64 test if platform.machine() != "x86_64": return self.child = pexpect.spawnu(self.command('{} games unity3d'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_close() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assert_exec_exists() self.assert_icon_exists() # ensure setuid self.assertEqual(self.get_file_perms(os.path.join(self.installed_path, "Editor", "chrome-sandbox")), '-rwsr-xr-x') # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.check_and_kill_process([self.exec_path], wait_before=self.TIMEOUT_START) proc.wait(self.TIMEOUT_STOP) # ensure that it's detected as installed: self.child = pexpect.spawnu(self.command('{} games unity3d'.format(UMAKE))) self.expect_and_no_warn("Unity3d is already installed.*\[.*\] ") self.child.sendline() self.wait_and_close()
def get_kerberos_ticket(username, password): """Attempts to create a Kerberos ticket for a user. Args: username The username. password The password. Returns: Boolean indicating success or failure of ticket creation """ cache = "/tmp/ion-%s" % uuid.uuid4() logger.debug("Setting KRB5CCNAME to 'FILE:{}'".format(cache)) os.environ["KRB5CCNAME"] = "FILE:" + cache try: realm = settings.CSL_REALM kinit = pexpect.spawnu("/usr/bin/kinit {}@{}".format(username, realm), timeout=settings.KINIT_TIMEOUT) kinit.expect(":") kinit.sendline(password) returned = kinit.expect([pexpect.EOF, "password:"******"Password for {}@{} expired, needs reset".format(username, realm)) return "reset" kinit.close() exitstatus = kinit.exitstatus except pexpect.TIMEOUT: KerberosAuthenticationBackend.kinit_timeout_handle(username, realm) exitstatus = 1 if exitstatus != 0: try: realm = settings.AD_REALM kinit = pexpect.spawnu("/usr/bin/kinit {}@{}".format(username, realm), timeout=settings.KINIT_TIMEOUT) kinit.expect(":") kinit.sendline(password) kinit.expect([pexpect.EOF, "password:"******"KRB5CCNAME" in os.environ: subprocess.check_call(['kdestroy', '-c', os.environ["KRB5CCNAME"]]) del os.environ["KRB5CCNAME"] if exitstatus == 0: logger.debug("Kerberos authorized {}@{}".format(username, realm)) return True else: logger.debug("Kerberos failed to authorize {}".format(username)) return False
def run(install_dir,admin_email, admin_password): child = pexpect.spawnu("{}".format(os.path.join(install_dir,"seafile-server-latest","seahub.sh")),["start-fastcgi"],timeout=180) child.logfile = sys.stdout child.expect_exact("[ admin email ]") child.sendline(admin_email) child.expect_exact("[ admin password ]") child.sendline(admin_password) child.expect_exact("[ admin password again ]") child.sendline(admin_password) child = pexpect.spawnu("{}".format(os.path.join(install_dir,"seafile-server-latest","seahub.sh")),["stop"],timeout=180) child.expect(pexpect.EOF) child = pexpect.spawnu("{}".format(os.path.join(install_dir,"seafile-server-latest","seafile.sh")),["stop"],timeout=180) child.expect(pexpect.EOF)
def connectToSeed(): """ Create a Pexpect connecton to the seedhost """ # Use spawnu for Python3 compatibility ssh_passwd_opts='' if CONFIG['seed_password'] == '': command = '/usr/bin/ssh ' + ssh_passwd_opts + ' ' + CONFIG['seed_login'] DEBUG(1, "Logging in to seed using ssh-keys <" + command + ">") client = pexpect.spawnu(command) seen = client.expect('^.+') if seen == 0: DEBUG(1, client.before) #FAIL("SSH-KEYS: failed to log in to seedhost <" + CONFIG['seed_login'] + "> using ssh-keys") STEP("SEEDHOST") return client #ssh_passwd_opts='-o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no' ssh_passwd_opts='-o PubkeyAuthentication=no' command = '/usr/bin/ssh ' + ssh_passwd_opts + ' ' + CONFIG['seed_login'] DEBUG(1, "Logging in to seed using password <" + command + ">") client = pexpect.spawnu(command) # [email protected]'s password: #seen = client.expect('.+s password:'******'password:'******'s input and out to a file or the screen. # The following will turn on logging and send output to stdout (the screen). #client = pexpect.spawn (foo) #client.logfile = sys.stdout sys.exit(1) #if VERBOSE: DEBUG(1, "SEEN=" + str(seen)) if seen == 0: DEBUG(1, client.before) #FAIL("PASSWORD: failed to log in to seedhost <" + CONFIG['seed_login'] + "> using password") DEBUG(1, "Sending password (contains " + str(len(CONFIG['seed_password'])) + " chars)") client.sendline(CONFIG['seed_password']) #FAIL("PASSWORD") STEP("SEEDHOST") return client
def check_swport_usage(sw_pair,SW1,SW2,username,password): # uses pexpect to obtain switchport status outputs from SW1 and SW2 print() input('Hit Enter to check the switchport statuses on '+sw_pair+':') print() for switch in [SW1,SW2]: try: child = pexpect.spawnu('telnet '+switch+'.dn.net') child.expect('Username: '******'Password: '******'6513-'+switch+'-(sec-)*c\d{1,2}#',timeout=3) print('====================================') print(switch+':\n') child.sendline('term len 55') child.expect('6513-'+switch+'-(sec-)*c\d{1,2}#',timeout=3) child.sendline('sh int status mod 4') child.expect('Gi4/25',timeout=3) print(child.before) child.sendline('exit') except (EOF,TIMEOUT,ExceptionPexpect): print('ERROR: Unable to display mod 4 interface statuses from '+switch) print('Try checking statuses manually instead:') print() print(' '+switch+':') print(' sh int status mod 4') print() try: child = pexpect.spawnu('telnet '+switch+'.dn.net') child.expect('Username: '******'Password: '******'6513-'+switch+'-(sec-)*c\d{1,2}#',timeout=3) child.sendline('term len 55') child.expect('6513-'+switch+'-(sec-)*c\d{1,2}#',timeout=3) child.sendline('sh int status mod 4 | beg Gi4/25') child.expect('6513-'+switch+'-(sec-)*c\d{1,2}#',timeout=3) print(child.before) child.sendline('exit') except (EOF,TIMEOUT,ExceptionPexpect): print('ERROR: Unable to display mod 4 interface statuses from '+switch) print('Try checking statuses manually instead:') print() print(' '+switch+':') print(' sh int status mod 4') print()
def __init__(self, id): # change directory if needed if not self.SAVE_DIR in os.getcwd(): os.chdir(self.SAVE_DIR) # local variables self.id = id self.active = True # if a saved game exists restore it if os.path.isfile(str(id)): self.proc = pexpect.spawnu('python3 -madventure ' + str(id)) self.getOutput() # avoid 'GAME RESTORED' message else: self.proc = pexpect.spawnu('python3 -madventure')
def spawn(request, tag, dockerfile, cmd): if bare: proc = pexpect.spawnu(cmd) else: tag = 'thefuck/{}'.format(tag) build_container(tag, dockerfile) proc = pexpect.spawnu('docker run --volume {}:/src --tty=true ' '--interactive=true {} {}'.format(root, tag, cmd)) proc.sendline('pip install /src') proc.sendline('cd /') proc.logfile = sys.stdout request.addfinalizer(proc.terminate) return proc
def test_default_go_install(self): """Install eclipse from scratch test case""" if not self.in_container: self.example_prog_dir = tempfile.mkdtemp() self.additional_dirs.append(self.example_prog_dir) example_file = os.path.join(self.example_prog_dir, "hello.go") open(example_file, "w").write(self.EXAMPLE_PROJECT) compile_command = ["bash", "-l", "-c", "go run {}".format(example_file)] else: # our mock expects getting that path compile_command = ["bash", "-l", "go run /tmp/hello.go"] self.child = pexpect.spawnu(self.command('{} go'.format(UMAKE))) self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() self.assert_exec_exists() self.assertTrue(self.is_in_path(self.exec_path)) # compile a small project output = subprocess.check_output(self.command_as_list(compile_command)).decode() if self.in_container: self.assertEqual(output, "hello, world\r\n") else: self.assertEqual(output, "hello, world")
def test_onionbalance_config_automatic_key_with_password(tmpdir, mocker): """ Run onionbalance-config with an existing key, export as password protected key. """ # Create input private_key private_key = Crypto.PublicKey.RSA.generate(1024) key_path = tmpdir.join('private_key') key_path.write(private_key.exportKey()) # Start onionbalance-config in automatic mode cli = pexpect.spawnu("onionbalance-config", logfile=sys.stdout, args=[ '--output', str(tmpdir.join(u"configdir")), '--key', str(key_path), '--password', 'testpassword', ]) cli.expect(u"Done! Successfully generated") # Check master config was generated with password protected key. master_dir = tmpdir.join('configdir', 'master') output_key_path = [fpath for fpath in master_dir.listdir() if fpath.ext == '.key'][0] assert output_key_path.check() # Check key decrypts and is valid mocker.patch('getpass.getpass', lambda *_: 'testpassword') output_key = onionbalance.util.key_decrypt_prompt(str(output_key_path)) assert isinstance(output_key, Crypto.PublicKey.RSA._RSAobj)
def __init__(self): # FIXME: Need configuration of this: self._exp = pexpect.spawnu('netcat 192.168.145.253 23') if _debug_cmds: self._exp.logfile = sys.stdout self._do_command('s' + str(_MICROSTEP)) self._heading_angle = 0 self._heading_steps = 0
def test_normal_output(self): self.sut = pexpect.spawnu( "python -m colorize -f 'b%(message)sb' -- echo foo", timeout=3 ) self.sut.expect_exact("bfoob") self.assertEquals(0, self.sut.wait())
def test_just_stdout(self): self.sut = pexpect.spawnu( "python -m colorize -f 'b%(message)sb' -- echo FAILURE", timeout=3 ) self.sut.expect_exact("b\x1b[1;37;41mFAILURE\x1b[mb") self.assertEquals(0, self.sut.wait())
def test_basic_format(self): self.sut = pexpect.spawnu( "python -m colorize -f 'a%(message)sa' -- echo FAILURE", timeout=3 ) self.sut.expect_exact("a\x1b[1;37;41mFAILURE\x1b[ma") self.assertEquals(0, self.sut.wait())
def test_is_default_framework(self): """Android Studio is chosen as the default framework""" self.child = pexpect.spawnu(self.command('{} android'.format(UDTC))) # we ensure it thanks to installed_path being the android-studio one self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendcontrol('C') self.wait_and_no_warn()
def test_eclipse_adt_reinstall(self): """Reinstall eclipse adt once installed""" for loop in ("install", "reinstall"): self.child = pexpect.spawnu(self.command('{} android eclipse-adt'.format(UDTC))) if loop == "reinstall": self.expect_and_no_warn("Eclipse ADT is already installed.*\[.*\] ") self.child.sendline("y") self.expect_and_no_warn("Choose installation path: {}".format(self.installed_path)) self.child.sendline("") self.expect_and_no_warn("\[.*\] ") self.child.sendline("a") self.expect_and_no_warn("Installation done", timeout=self.TIMEOUT_INSTALL_PROGRESS) self.wait_and_no_warn() # we have an installed launcher, added to the launcher self.assertTrue(self.launcher_exists_and_is_pinned(self.desktop_filename)) self.assertTrue(self.path_exists(self.exec_path)) self.assertTrue(self.path_exists(get_icon_path(self.icon_filename))) # launch it, send SIGTERM and check that it exits fine proc = subprocess.Popen(self.command_as_list(self.exec_path), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # on 64 bits, there is a java subprocess, we kill that one with SIGKILL (eclipse isn't reliable on SIGTERM) if self.arch_option == "x86_64": self.check_and_kill_process(["java", self.arch_option, self.installed_path], wait_before=self.TIMEOUT_START, send_sigkill=True) else: self.check_and_kill_process([self.exec_path], wait_before=self.TIMEOUT_START, send_sigkill=True) proc.wait(self.TIMEOUT_STOP)
def collectBackups(devices): for device in devices: # use pexpect to pull out config dump from device print('\nCollecting backup from '+device+'...') username = '******' password = '******' outfile = open(time.strftime("%Y-%m-%d")+'--'+device+'.txt', 'w') header = device + '('+ time.strftime("%Y-%m-%d") + '):\n' print(header, file=outfile) try: child = pexpect.spawnu('ssh '+username+'@'+device) i = child.expect(['Are you sure you want to continue connecting (yes/no)?','.*(P|p)assword:'],timeout=10) if i == 0: child.sendline('yes') child.expect('.*(P|p)assword:',timeout=3) child.sendline(password) child.expect(device+'#',timeout=3) else: child.sendline(password) child.expect(device+'#',timeout=3) print('Login successful') child.sendline('term len 0') child.expect(device+'#',timeout=3) child.sendline('sh run') child.logfile = outfile child.expect(device+'#',timeout=15) # after collecting the output, reset terminal child.sendline('term len 60') child.expect(device+'#',timeout=3) child.sendline('exit') print('Configs have been backed up for '+device) except (EOF,TIMEOUT,ExceptionPexpect): print('ERROR: Failed to backup configs of '+device)
def change_password(form_data): if form_data: form_data["username"] = re.sub('\W', '', form_data["username"]) if (form_data and form_data["username"] is "unknown" or form_data["old_password"] is None or form_data["new_password"] is None or form_data["new_password_confirm"] is None): return {"unable_to_set": True} if form_data["new_password"] != form_data["new_password_confirm"]: return {"unable_to_set": True, "password_match": False} realm = settings.CSL_REALM errors = [] try: kinit = pexpect.spawnu("/usr/bin/kpasswd {}@{}".format(form_data["username"], realm), timeout=settings.KINIT_TIMEOUT) match = kinit.expect([":", pexpect.EOF]) if match == 1: return {"unable_to_set": True, "error": "User {} does not exist.".format(form_data["username"])} kinit.sendline(form_data["old_password"]) kinit.expect([":", pexpect.EOF]) if match == 1: return {"unable_to_set": True, "error": "Old password was incorrect."} kinit.sendline(form_data["new_password"]) kinit.expect([":", pexpect.EOF]) if match == 1: return {"unable_to_set": True} kinit.sendline(form_data["new_password_confirm"]) kinit.expect(pexpect.EOF) kinit.close() exitstatus = kinit.exitstatus except pexpect.TIMEOUT: return {"unable_to_set": True, "errors": errors} exitstatus = 1 if exitstatus == 0: return True return {"unable_to_set": True}
def cmd_expect(self, command, **kwargs): from pexpect import spawnu # prepare the environ, based on the system + our own env env = copy(environ) env.update(self.environ) # prepare the process kwargs.setdefault('env', env) kwargs.setdefault('show_output', self.log_level > 1) sensible = kwargs.pop('sensible', False) show_output = kwargs.pop('show_output') if show_output: if IS_PY3: kwargs['logfile'] = codecs.getwriter('utf8')(stdout.buffer) else: kwargs['logfile'] = codecs.getwriter('utf8')(stdout) if not sensible: self.debug('Run (expect) {0!r}'.format(command)) else: self.debug('Run (expect) {0!r} ...'.format(command.split()[0])) self.debug('Cwd {}'.format(kwargs.get('cwd'))) return spawnu(command, **kwargs)
def main(cnc_ip, cnc_login, cnc_pass, cmd): res = 0 print("rcmd:" + cnc_ip, cnc_login, cnc_pass, cmd) child = pexpect.spawnu('telnet ' + cnc_ip) child.logfile=sys.stdout # child.logfile_read = sys.stdout # child.logfile_send = sys.stdout try: child.expect([u'login: '******'Password:'******'\$']) child.sendline(cmd) while True: index = child.expect(['\$', '/']) if index == 0: break; except pexpect.TIMEOUT as e: print("rcmd: time out of operation") res = -1 except pexpect.EOF: print("rcmd: end of operation") res = -2 child.sendline(u'exit;exit;') # Try to ask ftp child to exit. child.close() return res
# 2:11PM up 3 days, 13:50, 3 users, load averages: 0.01, 0.00, 0.00 # [powerpc] Darwin v1-58.corefa.com 8.2.0 Darwin Kernel Version 8.2.0 # 10:35 up 18:06, 4 users, load averages: 0.52 0.47 0.36 # [Sparc - R220] Sun Solaris (8) # 2:13pm up 22 min(s), 1 user, load average: 0.02, 0.01, 0.01 # [x86] Linux 2.4.18-14 (Redhat 8) # 11:36pm up 4 days, 17:58, 1 user, load average: 0.03, 0.01, 0.00 # AIX jwdir 2 5 0001DBFA4C00 # 09:43AM up 23:27, 1 user, load average: 0.49, 0.32, 0.23 # OpenBSD box3 2.9 GENERIC#653 i386 # 6:08PM up 4 days, 22:26, 1 user, load averages: 0.13, 0.09, 0.08 # Note that, for Python 3 compatibility reasons, we are using spawnu and # importing unicode_literals (above). spawnu accepts Unicode input and # unicode_literals makes all string literals in this script Unicode by default. p = pexpect.spawnu('uptime') # This parses uptime output into the major groups using regex group matching. p.expect( 'up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])' ) duration, users, av1, av5, av15 = p.match.groups() # The duration is a little harder to parse because of all the different # styles of uptime. I'm sure there is a way to do this all at once with # one single regex, but I bet it would be hard to read and maintain. # If anyone wants to send me a version using a single regex I'd be happy to see it. days = '0' hours = '0' mins = '0' if 'day' in duration:
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ''' from __future__ import absolute_import from __future__ import print_function from __future__ import unicode_literals import pexpect # Don't do this unless you like being John Malkovich # c = pexpect.spawnu('/usr/bin/env python ./python.py') # Note that, for Python 3 compatibility reasons, we are using spawnu and # importing unicode_literals (above). spawnu accepts Unicode input and # unicode_literals makes all string literals in this script Unicode by default. c = pexpect.spawnu('/usr/bin/env python') c.expect('>>>') print('And now for something completely different...') print(''.join(reversed((c.before)))) print('Yes, it\'s python, but it\'s backwards.') print() print('Escape character is \'^]\'.') print(c.after, end=' ') c.interact() c.kill(1) print('is alive:', c.isalive())
def autodoc(args): author = getpass.getuser() project = Path().resolve().name if "y" not in input( 'Do you want to generate the documentation for "{}"? [y/n] :'. format(project)): return child = pexpect.spawnu("sphinx-quickstart", ["./"], encoding="utf-8") res = child.expect([ "> Separate source and build directories*", "> Please enter a new root path*" ]) if res == 1: print( "\n{}Error{}".format(utils.colors.FAIL, utils.colors.ENDC), "an existing conf.py has been found in the selected root path.", ) print( "sphinx-quickstart will not overwrite existing Sphinx projects by itself." ) child.close() if "y" in input("\n{}Force overwriting?{} (you will lose the current". format(utils.colors.WARNING, utils.colors.ENDC) + " ./build/ and ./source/ folders) [y/n] : "): _ = subprocess.check_output("mkinx clean", shell=True) child = pexpect.spawnu("sphinx-quickstart", ["./"], encoding="utf-8") child.expect("> Separate source and build directories*") else: return print("\n Setting up the project...") windows = "y" if sys.platform in {"win32", "cygwin"} else "n" child.sendline("y") child.expect("> Name prefix*") child.sendline() child.expect("> Project name:*") child.sendline(project) child.expect("> Author name*") child.sendline(author) child.expect("> Project release*") child.sendline() child.expect("> Project language*") child.sendline("") child.expect("> Source file suffix*") child.sendline("") child.expect("> Name of your master document*") child.sendline("") child.expect("> Do you want to use the epub builder*") child.sendline("") child.expect("> autodoc: automatically insert docstrings*") child.sendline("y") child.expect("> doctest: automatically test code snippets*") child.sendline("") child.expect("> intersphinx: link between Sphinx documentation*") child.sendline("") child.expect('> todo: write "todo" entries*') child.sendline("") child.expect("> coverage: checks for documentation coverage") child.sendline("") child.expect("> imgmath: include math, rendered as PNG or SVG images*") child.sendline("") child.expect("> mathjax: include math*") child.sendline("") child.expect("> ifconfig: conditional inclusion of content*") child.sendline("") child.expect("> viewcode: include links to the source code*") child.sendline("y") child.expect( "> githubpages: create .nojekyll file to publish the document*") child.sendline("") child.expect("> Create Makefile*") child.sendline("") child.expect("> Create Windows command*") child.sendline(windows) child.expect("Creating file*") child.wait() child.close() print(" Building documentation...") print( ' If you see warnings such as "WARNING: autodoc: failed to import module', '[...] No module named [...]"', "\n consider mocking the imports with:", "\n mkinx autodoc -m module1 module2 etc.", "\n see http://www.sphinx-doc.org/en/stable/ext/autodoc.html#confval-autodoc_mock_imports", ) utils.set_sphinx_config(Path() / "source" / "conf.py", project, args.mock_imports) try: _ = subprocess.check_output( "sphinx-apidoc -f -o source {} -e -M > /dev/null".format(project), shell=True, ) except subprocess.CalledProcessError as e: # print(e) print( "{}Error{} ".format(utils.colors.FAIL, utils.colors.ENDC), "you should run `autodoc` from a project folder,", "with an importable project package", ) print("Cleaning...", end="") _ = subprocess.check_output("mkinx clean", shell=True) print(u"\u2713") return utils.add_project_to_rst_index(Path() / "source" / "index.rst", project) utils.remove_project_name_from_titles(Path() / "source") os.remove(Path() / "source" / "modules.rst") index = Path().resolve().parent / "docs" / "index.md" if not index.exists(): print( "Error: the project could not be added to your home documentation") print("`mkinx autodoc` should be run from: ") print(" path/to/documentation/new_python_project") else: utils.add_project_to_doc_index(index, project) _ = subprocess.check_output( "cd .. && mkinx build -F -p {} > /dev/null".format(project), shell=True) print(u"""\n Added configuration file source/conf.py Added documentation files /source/*.rst Added utility file ./Makefile {} {}Finished \u2713{} An initial directory structure has been created. You can now enhance your master file source/index.rst and other documentation source files.\n""".format( "Added utility file make.bat" if windows == "y" else "", utils.colors.OKGREEN, utils.colors.ENDC, ))
def __enter__(self): self.proc = pexpect.spawnu(self.cmd_line) self.proc.expect(Spike.PROMPT) self.proc.setecho(False) self.until(0) return self
class AgdaKernel(Kernel): implementation = 'agda' implementation_version = '0.5' language = 'agda' language_version = '2.6' language_info = { 'name': 'agda', 'mimetype': 'text/agda', 'file_extension': '.agda', } banner = "Agda kernel" cells = {} last_code = "" agda_version = "" notebookName = "" cellId = "" preamble = "" unicodeComplete = True ''' _banner = None @property def banner(self): if self._banner is None: self._banner = check_output(['bash', '--version']).decode('utf-8') return self._banner ''' #lock = threading.Lock() #process = Popen(['agda', '--interaction'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) process = pexpect.spawnu('agda --interaction') firstTime = True def startAgda(self): if self.firstTime: self.process.expect('Agda2> ') self.print(f'Agda has started.') self.firstTime = False return def __init__(self, **kwargs): Kernel.__init__(self, **kwargs) self.agda_version = self.readAgdaVersion() # self.kernel_lock = threading.Lock() def sendResponse(self, text): try: self.send_response(self.iopub_socket, 'stream', {'name': 'stdout', 'text': text}) except AttributeError: # during testing there is no such method, just ignore self.print("Ignoring call to self.send_response") def sendInfoResponse(self, text): # ignore otherwise if self.sendInfoMessages: try: self.send_response(self.iopub_socket, 'stream', {'name': 'stdinfo', 'text': text}) except AttributeError: # during testing there is no such method, just ignore self.print("Ignoring call to self.send_response") # return line and column of an position in a string def line_of(self, s, n): lines = s.split('\n') i = 0 # current line j = 0 # cumulative length found = False for line in lines: if n >= j and n <= j + len(line): found = True break # self.print(f'line {i} has length {len(line)}, cumulative {j}') i += 1 j += len(line) + 1 # need to additionally record the '\n' if found: return i, n - j else: return -1, -1 def readAgdaVersion(self): p = pexpect.spawn('agda --version') p.expect(pexpect.EOF) result = str(p.before) tokens = result.split(" ") version = tokens[2] # remove initial "Agda version " version = version[:-5] # remove trailing "\r\n" self.print(f'Detected Agda version: {version}') return version def interact(self, cmd): self.print("Interacting with Agda: %s" % cmd) #cmd = cmd.encode() # create a byte representation #result = self.process.communicate(input=cmd)[0] #cmd = cmd + "\n" self.process.sendline(cmd) result = "" while True: #this more robust version will survive an unexpected end of output from Agda prompt = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, 'Agda2> ', '\(agda2-info-action "\*Type-checking\*"'], timeout=240) response = self.process.before result += response if prompt == 0 or prompt == 1: break elif prompt == 2: self.sendInfoResponse("DONE") break elif prompt == 3: # keep jupyter informed about agda's partial responses self.sendInfoResponse(response) continue #skip the first line (it's a copy of cmd) result = result[result.index('\n')+1:] #result = result.decode() self.print(f'Agda replied: {result}') lines = result.split('\n') result = {} # parse the response for line in lines: start = line.find("agda2") # parse only lines containing "agda2", and from that position on if start != -1: tokens = line[start:].split(' ') key = tokens[0] rest = line[start + len(key):] #rest = rest.replace("\\n", "\n") # extract all the strings in quotation marks "..." rest = rest.replace("\\\"", "§") # replace \" with § values = re.findall('"([^"]*)"', rest) # find all strings in quotation marks "..." values = [val.replace("§", "\"") for val in values] # replace § with " (no escape) if not key in result: result[key] = [] # in this case the format is "(agda2-give-action 0 'no-paren)" # return the goal index 0 if key == AGDA_GIVE_ACTION: result[key] = [tokens[1]] # add the new values to the dictionary result[key].append(values) self.print("result: %s" % result) return result def getModuleName(self, code): code = self.removeComments(code) lines = code.split('\n') #look for the first line matching "module name where" for line in lines: if bool(re.match(r'module *[a-zA-Z0-9.\-]* *where', line)): # fileName = "tmp/" + re.sub(r"-- *", "", firstLine) moduleName = re.sub(r'module *', "", line) # delete prefix moduleName = re.sub(r' *where.*', "", moduleName) # delete suffix return moduleName return "" def getFileName(self, code): moduleName = self.getModuleName(code) return moduleName.replace(".", "/") + ".agda" if moduleName != "" else "" def getDirName(self, code): moduleName = self.getModuleName(code) last = moduleName.rfind(".") prefixName = moduleName[:last] return prefixName.replace(".", "/") if last != -1 else "" def do_shutdown(self, restart): return def do_execute(self, in_code, silent, store_history=True, user_expressions=None, allow_stdin=False): self.startAgda() fileName = self.getFileName(in_code) dirName = self.getDirName(in_code) moduleName = self.getModuleName(in_code) absoluteFileName = os.path.abspath(fileName) preambleLength = 0 self.sendInfoMessages = False if user_expressions and "sendInfoMessages" in user_expressions and user_expressions["sendInfoMessages"] == "yes": self.sendInfoMessages = True if user_expressions and "agdaCMD" in user_expressions: self.agdaCMD = user_expressions["agdaCMD"] self.print(f'agdaCMD = {self.agdaCMD}') else: self.print(f'agdaCMD NOT given') self.agdaCMD = "" # reset if not given # printing this may expose the user's github password # self.print(f'user_expressions: {user_expressions}') if user_expressions and "persistent" in user_expressions: persistent = user_expressions["persistent"] == "yes" else: persistent = False # set unicodeComplete only if passed in user_expressions; # otherwise, remember the previous value if user_expressions and "unicodeComplete" in user_expressions: self.unicodeComplete = user_expressions["unicodeComplete"] == "yes" if user_expressions and "loadFromStore" in user_expressions and user_expressions["loadFromStore"] == "yes": self.print(f'loadFromStore = yes') try: fileHandle = open(fileName, "r+") code = fileHandle.read() fileHandle.close() self.print(f'executing code from file: {code}') except: self.print(f"file {fileName} not found, executing from given code") code = in_code else: code = in_code self.print(f'loadFromStore = no') self.print(f'executing code: {code}') if user_expressions: # get notebook name (if any) if "notebookName" in user_expressions: self.notebookName = user_expressions["notebookName"] # get cell id if "cellId" in user_expressions: self.cellId = user_expressions["cellId"] if "preamble" in user_expressions: self.preamble = user_expressions["preamble"] notebookName = self.notebookName cellId = self.cellId preamble = self.preamble #if notebookName == "": # error = True # self.print(f'empty notebook name!') # result = "the cell should be evaluated first..." #else: error = False self.print(f'detected fileName: {fileName}, dirName: {dirName}, moduleName: {moduleName}, notebookName: {notebookName}, cellId: {cellId}, preamble: {preamble}') # use the provided preamble only if the module name is missing if fileName == "" and not error: # if no line \"module [modulename] where\" is provided, # we create a standard one ourselves preambleLength = len(preamble.split("\n")) - 1 if preamble == "": error = True self.print(f'a preamble of the form "module xxx where" should be provided') result = 'a preamble of the form "module xxx where" should be provided' else: new_code = preamble + code fileName = self.getFileName(new_code) dirName = self.getDirName(new_code) moduleName = self.getModuleName(new_code) absoluteFileName = os.path.abspath(fileName) self.print(f'redetected fileName: {fileName}, dirName: {dirName}, moduleName: {moduleName}, notebookName: {notebookName}, cellId: {cellId}, new code: {new_code}') code = new_code if not error: self.fileName = fileName lines = code.split('\n') numLines = len(lines) self.print(f"writing to file: {fileName}") if dirName != "" and not os.path.exists(dirName): os.makedirs(dirName) fileHandle = open(fileName, "w+") for i in range(numLines): if i < numLines - 1: fileHandle.write("%s\n" % lines[i]) else: fileHandle.write("%s" % lines[i]) fileHandle.close() # if the persistent option is turned on, do a git commit if persistent: def git_push(): # push the changes #branch = "main" if user_expressions and "username" in user_expressions: username = user_expressions["username"] else: self.print(f'No username provided') username = "" self.print(f'Pushing, username: {username}') #to branch {branch}') self.sendInfoResponse(f'Pushing, username: {username}\n') if user_expressions and "password" in user_expressions: self.print("Storing password") password = user_expressions["password"] self.sendInfoResponse(f'Storing password\n') else: self.print("No password provided") password = "" self.sendInfoResponse('No password provided\n') child = pexpect.spawn(f'git push origin') while True: prompt = child.expect([ "Username for 'https://github.com':", f"Password for 'https://{username}@github.com':", pexpect.EOF] ) self.print(f'Prompt = {prompt}') self.sendInfoResponse(f'Prompt = {prompt}\n') if prompt == 0: child.sendline(username) elif prompt == 1: child.sendline(password) elif prompt == 2: child.close() break if child.exitstatus != 0: text = child.before.decode() self.print(text) self.sendInfoResponse(text) self.print(f'Pushed!') self.sendInfoResponse("Pushed!") def persist(): #(self, fileName): #with lock: self.print(f'Git commit & push: {fileName}') os.system('git pull') os.system(f'git add {fileName}') os.system(f'git commit -m "do_execute: updated {fileName}"') self.print(f'Time to push...') git_push() self.print(f'Persist is on, asynchronously committing to github') thr = threading.Thread(target=persist, args=(), kwargs={}) thr.start() # load the code in Agda result, error = self.runCmd(code, -1, -1, "", AGDA_CMD_LOAD) result = deescapify(result) # try: # #remove the .agdai file # agdai = fileName + "i" # os.remove(agdai) # except: # self.print("*.agdai file '%s' not found" % agdai) # self.print("output: %s" % result) if result == "": result = "OK" #save the result of the last evaluation self.cells[fileName] = result # save the code that was executed self.code = code if not silent or error != "": self.sendResponse(result) # return all holes holes_as_pairs_of_positions = self.findAllHoles(code) # pairs are just lists of length 2 (join the lists) holes_as_positions = sum(map(lambda x: [x[0], x[1]], holes_as_pairs_of_positions), []) #self.print(f'holes_as_positions = {holes_as_positions}') # replace each absolute position with the pair (line number, relative position) holes_as_lines_rel_pos = list(map(lambda x: self.line_of(code, x), holes_as_positions)) # the first component is the line, the second the relative position within the line; # project to the line number; # additinally remove the shift possibly caused by the defaul preamble holes_as_lines = list(map(lambda x: x[0] - preambleLength, holes_as_lines_rel_pos)) #self.print(f'holes_as_lines = {holes_as_lines}') # remove trailing newlines code = code.rstrip('\n') user_expressions_return = { "fileName": absoluteFileName, "moduleName": moduleName, "holes": holes_as_lines, "preambleLength" : preambleLength, "isError": error, "code": code, "result": result # return the agda response here too for further processing } self.print(f"Returning user_expressions_return: {user_expressions_return}") return {'status': 'ok' if not error else 'error', # The base class increments the execution count 'execution_count': self.execution_count, 'payload': [], 'user_expressions': user_expressions_return, } # def do_execute(self, in_code, silent, store_history=True, user_expressions=None, allow_stdin=False): # with self.kernel_lock: # return self._do_execute(in_code, silent, store_history, user_expressions, allow_stdin) def inComment(self, code, pos): # check whether there is a "--" on the left of pos, but not going to the previous line while pos >= 0 and code[pos:pos+1] != "\n": if code[pos:pos+2] == "--": return True pos -= 1 return False def find_expression(self, code, cursor_pos): forbidden = [" ", "\n", "(", ")", "{", "}", ":", ";"] length = len(code) hole_left = cursor_pos # go left until you find the beginning of a hole while code[hole_left : hole_left + 2] != "{!" and hole_left > 0: hole_left -= 1 hole_left_found = code[hole_left : hole_left + 2] == "{!" and not self.inComment(code, hole_left) self.print(f'found hole left? {hole_left_found}') hole_right = cursor_pos - 2 # go right until you find the beginning of a hole while code[hole_right : hole_right + 2] != "!}" and hole_right < length: hole_right += 1 hole_right_found = code[hole_right : hole_right + 2] == "!}" and not self.inComment(code, hole_right) self.print(f'found hole right? {hole_right_found}') # check if the cursor is inside a hole if hole_left_found and hole_right_found: start = hole_left end = hole_right + 2 expression = code[start : end] self.print(f'found hole left {start} and right {end}: token = {expression}') else: self.print(f'going for spaces') start = cursor_pos while start >= 1 and code[start - 1:start] not in forbidden: start -= 1 end = cursor_pos while end < length and code[end] not in forbidden: end += 1 expression = code[start : end] expression = escapify(expression) self.print(f'considering expression: \"{expression}\"') return start, end, expression def isHole(self, exp): result = exp == "?" or re.search("\\{!.*!\\}", exp) != None self.print(f'the expression "{exp}" is a hole? {result}') return result def runCmd(self, code, cursor_start, cursor_end, exp, cmd): fileName = self.fileName if hasattr(self, 'fileName') else self.getFileName(code) absoluteFileName = os.path.abspath(fileName) self.print(f"running command: {cmd}, cursor_start: {cursor_start}, cursor_end: {cursor_end}") if fileName == "": return "empty filename", True if (fileName not in self.cells or self.cells[fileName] == "") and cmd != AGDA_CMD_LOAD: return "the cell should be evaluated first", True if cmd != AGDA_CMD_LOAD: # find out line and column of the cursors row1, col1 = self.line_of(code, cursor_start) row2, col2 = self.line_of(code, cursor_end) if self.agda_version <= "2.5.1": intervalsToRange = f'(Range [Interval (Pn (Just (mkAbsolute "{absoluteFileName}")) {cursor_start+1} {row1+1} {col1+1}) (Pn (Just (mkAbsolute "{absoluteFileName}")) {cursor_end+1} {row2+1} {col2+1})])' else: intervalsToRange = f'(intervalsToRange (Just (mkAbsolute "{absoluteFileName}")) [Interval (Pn () {cursor_start+1} {row1+1} {col1+1}) (Pn () {cursor_end+1} {row2+1} {col2+1})])' interactionId = self.findCurrentHole(code, cursor_start) if row1 == -1 or row2 == -1: # should not happen return "Internal error", True inside_exp = exp[2:-2] result = "" if cmd == AGDA_CMD_LOAD: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect (Cmd_load "{absoluteFileName}" [])' elif cmd == AGDA_CMD_INFER: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_INFER} Simplified {interactionId} {intervalsToRange} "{exp}")' elif cmd == AGDA_CMD_INFER_TOPLEVEL: query = f'IOTCM "{absoluteFileName}" None Indirect ({AGDA_CMD_INFER_TOPLEVEL} Simplified "{exp}")' elif cmd == AGDA_CMD_GOAL_TYPE_CONTEXT_INFER: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_GOAL_TYPE_CONTEXT_INFER} Simplified {interactionId} {intervalsToRange} "{exp}")' elif cmd in [AGDA_CMD_AUTO, AGDA_CMD_AUTOONE]: hints = exp #"" if exp == "?" else inside_exp query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({cmd} {interactionId} {intervalsToRange} "{hints}")' elif cmd == AGDA_CMD_COMPUTE: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_COMPUTE} DefaultCompute {interactionId} {intervalsToRange} "{exp}")' elif cmd == AGDA_CMD_COMPUTE_TOPLEVEL: query = f'IOTCM "{absoluteFileName}" None Indirect ({AGDA_CMD_COMPUTE_TOPLEVEL} DefaultCompute "{exp}")' elif cmd == AGDA_CMD_REFINE_OR_INTRO: flag = "False" # "True" if the goal has functional type query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_REFINE_OR_INTRO} {flag} {interactionId} {intervalsToRange} "{inside_exp}")' elif cmd == AGDA_CMD_MAKE_CASE: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_MAKE_CASE} {interactionId} {intervalsToRange} "{inside_exp}")' elif cmd == AGDA_CMD_GIVE: query = f'IOTCM "{absoluteFileName}" NonInteractive Indirect ({AGDA_CMD_GIVE} WithoutForce {interactionId} {intervalsToRange} "{inside_exp}")' else: return f"Unrecognised command: {cmd}", True # send the type query to agda response = self.interact(query) if AGDA_INFO_ACTION in response: info_action_type, info_action_message = response[AGDA_INFO_ACTION][0][0], deescapify(response[AGDA_INFO_ACTION][0][1]) info_action_types = [item[0] for item in response[AGDA_INFO_ACTION]] else: info_action_type, info_action_message = "", "" if AGDA_INFO_ACTION in response: self.print(f"there is AGDA_INFO_ACTION") if AGDA_GIVE_ACTION in response: # if there is a give action, it has priority result = response[AGDA_GIVE_ACTION] self.print(f"there is AGDA_GIVE_ACTION, with content {result}, and interactionId = {interactionId}") if cmd in [AGDA_CMD_GIVE, AGDA_CMD_REFINE_OR_INTRO] and len(result) > 0 and int(result[0]) == interactionId: self.print(f"got matching hole!") if cmd == AGDA_CMD_GIVE: return "OK", False elif cmd == AGDA_CMD_REFINE_OR_INTRO and len(result) > 1 and result[1] != "": self.print(f"returning: {result[1][0]}") return deescapify(result[1][0]), False else: return "OK", False elif AGDA_ALL_GOALS in info_action_types: self.print(f"there is AGDA_ALL_GOALS") goals = "".join([deescapify(item[1]) if item[0] == AGDA_ALL_GOALS else "" for item in response[AGDA_INFO_ACTION]]) self.print(f"deescapified goals: {goals}") return goals, False elif AGDA_ALL_DONE in info_action_types: return "OK", False elif any(x in AGDA_ERROR_LIKE for x in info_action_types): info_action_message = "".join([f"{item[0]}: {deescapify(item[1])}" if item[0] in AGDA_ERROR_LIKE else "" for item in response[AGDA_INFO_ACTION]]) if cmd != AGDA_CMD_LOAD: # error recovery: if there is a string "did you mean 'new_exp'?", # then call again with new_exp (except if we are loading) matches = re.findall(r'did you mean \'([^\']*)\'\?', info_action_message) if len(matches) > 0: new_exp = matches[0] if new_exp != exp: # avoid a potential infinite loop self.print(f'trying error recovery with new expression: {new_exp}') return self.runCmd(code, cursor_start, cursor_end, new_exp, cmd) return info_action_message, True elif AGDA_INFERRED_TYPE in info_action_types: inferred_type = info_action_message return f'{inferred_type}', False # if inferred_type != "" else str(response) elif AGDA_GOAL_TYPE_ETC in info_action_types: result = info_action_message blocks = result.split('————————————————————————————————————————————————————————————') result = blocks[0] + blocks[1] # find the maximal line length lines = result.split('\n') max_len = max(list(map(len, lines))) result = blocks[0] + ("-" * max_len) + blocks[1] self.print(f'AGDA_GOAL_TYPE_ETC case, max_len: {max_len}, result: {result}') return result, False elif AGDA_AUTO in info_action_types: return info_action_message, False elif AGDA_NORMAL_FORM in info_action_types: return info_action_message, False else: return info_action_message, True elif AGDA_MAKE_CASE_ACTION in response: # in this case we need to parse Agda's response again case_list = response[AGDA_MAKE_CASE_ACTION][0] result = "\n".join(case_list) self.print(f"Case list: {result}") return result, False elif cmd == AGDA_CMD_LOAD: if AGDA_INFO_ACTION in response: result = "\n".join(list(map(lambda info: " ".join(info), response[AGDA_INFO_ACTION]))) return result, False return str(response), True def get_expression(self, code, cursor_pos): if len(code) < len(self.code): # we are in a selection and the cursor is at the beginning of the selection if cursor_pos + len(code) <= len(self.code) and self.code[cursor_pos:cursor_pos+len(code)] == code: #self.print(f'we are in a selected text, cursor at the beginning') cursor_start, cursor_end, exp = cursor_pos, cursor_pos + len(code), code # we are in a selection and the cursor is at the end of the selection elif cursor_pos - len(code) >= 0 and cursor_pos <= len(self.code) and self.code[cursor_pos-len(code):cursor_pos] == code: #self.print(f'we are in a selected text, cursor at the end') cursor_start, cursor_end, exp = cursor_pos - len(code), cursor_pos, code else: error = True self.print(f'no other case possible: the cursor is either at the beginning or at the end of a selection') #return {'status': 'ok', 'found': True, 'data': {'text/plain': 'load the cell first'}, 'metadata': {}} # we are not in a selection, or an error above occurred else: # if exp == "": cursor_start, cursor_end, exp = self.find_expression(code, cursor_pos) #cursor_start += 1 return cursor_start, cursor_end, exp def infer_top_level(self, cursor_start, cursor_end, exp): inferred_type, error2 = self.runCmd(self.code, cursor_start, cursor_end, exp, AGDA_CMD_INFER_TOPLEVEL) normal_form, error3 = self.runCmd(self.code, cursor_start, cursor_end, exp, AGDA_CMD_COMPUTE_TOPLEVEL) error = error2 and error3 if not error: result = f"{exp.strip()} EVALUATES TO \n{normal_form.strip()} OF TYPE\n {inferred_type.strip()}" elif not error2: result = f"{exp.strip()} : {inferred_type.strip()}" elif not error3: result = f"{exp.strip()} = {normal_form.strip()}" else: # this is an error message result = normal_form.strip() return error, f"{result}" def infer_local(self, cursor_start, cursor_end, exp): goal, error1 = self.runCmd(self.code, cursor_start, cursor_end, exp, AGDA_CMD_GOAL_TYPE_CONTEXT_INFER) inferred_type, error2 = self.runCmd(self.code, cursor_start, cursor_end, exp, AGDA_CMD_INFER) normal_form, error3 = self.runCmd(self.code, cursor_start, cursor_end, exp, AGDA_CMD_COMPUTE) result = "" #self.print(f'gathered: error1 = {error1}, error2 = {error2}, error3 = {error3}') if not error2 and not error3: normalisation = f"Eval: {exp.strip()} --> {normal_form.strip()} : {inferred_type.strip()}" elif not error2: normalisation = f"{exp.strip()} : {inferred_type.strip()}" elif not error3: normalisation = f"Eval: {exp.strip()} --> {normal_form.strip()}" else: normalisation = "" padding = "=" * len(normalisation) if not error1 and goal and goal != "": result = f"{goal.strip()} \n{padding}\n" else: return True, f"{normal_form.strip()}" # this contains the error message return False, result # get the type of the current expression # triggered by SHIFT+TAB # code is either the current selection, or the whole cell otherwise # cursor_pos is always at the beginning or at the end of the selection; def do_inspect(self, code, cursor_pos, detail_level=0): #if self.code == "" or not code in self.code: # return {'status': 'error', 'found': True, 'data': {'text/plain': "must load the cell first"}} self.print(f'do_inspect cursor_pos: {cursor_pos}, selection: "{code}" of length {len(code)}, code: "{self.code}" of length {len(self.code)}') # load the code to check that there are no errors #response = self.do_execute(self.code, False) response = self.do_execute(code, False) if response['status'] == 'error': return {'status': 'error', 'found': False, 'data': {'text/plain': "unable to inspect, the code contain errors"}} cursor_start, cursor_end, exp = self.get_expression(code, cursor_pos) # self.print(f'current exp: "{exp}", pos: {cursor_pos}, start: {cursor_start}, end: {cursor_end}') old_code = self.code # if we are not in a hole, try the top level inspection first if not self.isHole(exp): error, result = self.infer_top_level(cursor_start, cursor_end, exp) if not error: return {'status': 'ok', 'found': True, 'data': {'text/plain': result}} else: # if we are not in a hole, # create an artificial hole around the current selection and reload self.code = self.code[:cursor_start-1] + "{! " + exp + " !}" + self.code[cursor_end:] #self.print(f'new_code: {self.code}') response = self.do_execute(self.code, False) # adding the hole creates an error if response['status'] == 'error': self.print(f'unexpected error when adding temporary hole: {response}') cursor_start, cursor_end, exp = self.find_expression(self.code, cursor_start) # at this point we are in a hole, # either the original one, or the one we created if exp != "?": exp = exp[2:-2] # strip the initial "{!" and final "!}" #self.print(f'considering inside exp: {exp}') #self.print(f'considering exp: {exp}, pos: {cursor_pos}, start: {cursor_start}, end: {cursor_end}') error, result = self.infer_local(cursor_start, cursor_end, exp) # undo file modifications if we created a new hole if self.code != old_code: self.code = old_code self.do_execute(self.code, False) return {'status': 'error' if error else 'ok', 'found': True, 'data': {'text/plain': result}} # handle unicode completion here def do_complete(self, code, cursor_pos): #self.print(f'considering code: {code}, pos: {cursor_pos}') half_subst = { 'Nat' : 'ℕ', '<=<>' : '≤⟨⟩', '<==<>' : '≤≡⟨⟩', '=<>' : '≡⟨⟩', '-><>' : '↝<>', '->*<>' : '↝*<>', 'top' : '⊤', 'bot' : '⊥', 'neg' : '¬', '/\\' : '∧', '\\/' : '∨', '\\' : 'λ', # it is important that this comes after /\ 'Pi' : 'Π', 'Sigma' : 'Σ', '->' : '→', '→' : '↦', '↦' : '↝', '↝' : '->', 'iff' : '⟺', '<=>' : '⟺', '=>' : '⇒', '<' : '⟨', '>' : '⟩', # it is important that this comes after -> '⟩' : '≻', '≻' : '>', 'forall' : '∀', 'exists' : '∃', 'A' : '𝔸', 'B' : '𝔹', 'C' : 'ℂ', 'N' : 'ℕ', 'Q' : 'ℚ', 'R' : 'ℝ', 'Z' : 'ℤ', ':=' : '≔', '/=' : '≢', 'leq' : '≤', '<=' : '≤', 'geq' : '≥', '>=' : '≥', '[=' : '⊑', '=' : '≡', 'alpha' : 'α', 'beta' : 'β', 'gamma' : 'γ', 'rho' : 'ρ', 'e' : 'ε', 'mu' : 'μ', 'kappa': 'κ', 'xor' : '⊗', 'emptyset' : '∅', 'qed' : '∎', '.' : '·', 'd' : '∇', 'Delta' : 'Δ', 'delta' : 'δ', 'notin' : '∉', 'in' : '∈', '[' : '⟦', ']' : '⟧', '::' : '∷', '0' : '𝟬', # '𝟢', '𝟬' : '₀', '₀' : '0', '1' : '𝟭', # '𝟣' '𝟭' : '₁', '₁' : '1', '2' : '₂', '3' : '₃', '4' : '₄', '5' : '₅', '6' : '₆', '7' : '₇', '8' : '₈', '9' : '₉', '+' : '⨁', '~' : '≈', 'x' : '×', 'o' : '∘', 'phi' : 'φ', 'psi' : 'ψ', 'xi' : 'ξ', #'??' : "{! !}", 'w' : 'ω ', 'omega' : 'ω', 'Gamma' : 'Γ', 'tau' : 'τ', 'sigma' : 'σ', #';' : ';', very bad idea: the second semicolon lloks the same but it is a different unicode symbol... ';' : '⨟', '(' : '⟬', '⟬' : '⦅', ')' : '⟭', '⟭' : '⦆', 'b' : 'ᵇ', 'empty' : '∅', '|-' : '⊢', 'models' : '⊨', '|=' : '⊨', 'cup' : '⊔', 'l' : 'ℓ', 'op' : 'ᵒᵖ', '{{' : '⦃', '}}' : '⦄', '--' : '−−', # they are not the same! '−−' : '--', # they are the other way around! ':' : '꞉', # they are not the same! '꞉' : ':', # they are the other way around! 'subseteq' : '⊆', '⊆' : 'subseteq' } other_half = {val : key for (key, val) in half_subst.items() if val not in list(half_subst.keys())} subst = {**half_subst, **other_half} # merge the two dictionaries keys = [key for (key, val) in subst.items()] length = len(code) matches = [] error = False for key in keys: n = len(key) cursor_start = cursor_pos - n cursor_end = cursor_pos s = code[cursor_start:cursor_pos] if s == key: # we have a match matches = [subst[key]] break def cmdAuto(): # call Agsy, options: -c (case splitting) -m (hints) -r (refine) -l (list) -s k (select result k) """options = lambda k: f' -m -s {k} ' k = 0 while True: result, error = self.runCmd(code, cursor_start, cursor_end, options(k), AGDA_CMD_AUTOONE) self.print(f'result is: {result}, error is: {error}') if error or result in ["No solution found", "No candidate found", "Only 1 solution found", f'Only {k} solutions found']: if matches == []: matches = ["{! !}"] # transform "?" into "{! !}" when Agsy fails break else: matches += [result] if result != "" else [] k += 1 """ options = "-m -l" # list solutions self.print(f'Agsy options are: {options}') result, error = self.runCmd(code, cursor_start, cursor_end, options, AGDA_CMD_AUTOONE if self.agda_version >= "2.5.4" else AGDA_CMD_AUTO) self.print(f'result is: {result}, error is: {error}') if result.find("Listing solution(s)") != -1: matches = self.listing_solution_parser(result) elif error or result in ["No solution found", "No candidate found", "No solution found after timeout (1000ms)"]: matches = ["{! !}"] # transform "?" into "{! !}" when Agsy fails else: self.print(f'Unexpected answer: {result}, error is: {error}') return result, error, matches # didn't apply a textual substitution, # or such substitutions are disabled if not self.unicodeComplete or matches == []: # reset the list of matches in any case matches = [] cursor_start_orig, cursor_end_orig, exp_orig = self.find_expression(code, cursor_pos) cursor_start, cursor_end = cursor_start_orig, cursor_end_orig exp = escapify(exp_orig) #cursor_start += 1 agdaCMD = self.agdaCMD # if we have a specific command to pass to Agda, just do it if agdaCMD != "": self.print(f'Passing command directly to Agda: {agdaCMD}') if agdaCMD == AGDA_CMD_AUTO or agdaCMD == AGDA_CMD_AUTOONE: result, error, matches = cmdAuto() else: result, error = self.runCmd(code, cursor_start, cursor_end, exp, agdaCMD) self.print(f'result is: {result}, error is: {error}') if error: cursor_start, cursor_end = cursor_pos, cursor_pos elif agdaCMD == AGDA_CMD_GIVE and result == "OK": result = "(" + re.search(r'\{! *(.*) *!\}', exp).group(1).strip() + ")" self.print(f'gave hole: {result}') elif agdaCMD == AGDA_CMD_MAKE_CASE: # need to replace the current row with result while cursor_start > 0 and code[cursor_start - 1] != "\n": cursor_start -= 1 while cursor_end < length and code[cursor_end] != "\n": cursor_end += 1 # elif agdaCMD == AGDA_CMD_REFINE_OR_INTRO: # else: # cursor_start, cursor_end = cursor_pos, cursor_pos # result = "" matches = [result] if result != "" else [] else: # load the current contents self.do_execute(code, False) if exp == "?": result, error, matches = cmdAuto() # continue the chain if Agsy fails if self.isHole(exp) and (exp != "?" or matches == ["{! !}"]): # first, try to replace the hole with its current contents result, error = self.runCmd(code, cursor_start, cursor_end, exp, AGDA_CMD_GIVE) self.print(f'AGDA_CMD_GIVE, result: {result}, error: {error}') if error: # second, try to automatically refine the current contents result, error = self.runCmd(code, cursor_start, cursor_end, exp, AGDA_CMD_REFINE_OR_INTRO) if error: # try case # need to reload to make it work (??) _, _ = self.runCmd(code, -1, -1, "", AGDA_CMD_LOAD) # third, try to introduce a case analysis result, error = self.runCmd(code, cursor_start, cursor_end, exp, AGDA_CMD_MAKE_CASE) if error or result == "OK": cursor_start, cursor_end = cursor_pos, cursor_pos result = "" else: # need to replace the current row with result while cursor_start > 0 and code[cursor_start - 1] != "\n": cursor_start -= 1 while cursor_end < length and code[cursor_end] != "\n": cursor_end += 1 elif result == "OK": # cannot close the hole result1 = re.search(r'\{! *(.*) *!\}', exp).group(1).strip() self.print(f'not closing hole: {result1}') else: # in this case result is a refined goal and we can refine the hole result = result elif result == "OK": # close the hole result = "(" + re.search(r'\{! *(.*) *!\}', exp).group(1).strip() + ")" self.print(f'gave hole: {result}') matches = [result] if result != "" else [] self.print(f'exp: {exp}, matches: {matches}') # always replace "?" with a hole in case there is no match if exp == "?" and matches == []: matches = ["{! !}"] cursor_start, cursor_end = cursor_start_orig, cursor_end_orig self.print(f'cursor_start: {cursor_start}, cursor_end: {cursor_end}') error = False return {'matches': matches, 'cursor_start': cursor_start, 'cursor_end': cursor_end, 'metadata': {}, 'status': 'ok' if not error else 'error'} def listing_solution_parser(self, str): # example: Listing solution(s) 0-9\n0 cong suc (+-assoc m n p)\n1 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m p p)) ⟩\nsuc (m + (n + p)) ∎\n2 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m p n)) ⟩\nsuc (m + (n + p)) ∎\n3 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m p m)) ⟩\nsuc (m + (n + p)) ∎\n4 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m n p)) ⟩\nsuc (m + (n + p)) ∎\n5 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m n n)) ⟩\nsuc (m + (n + p)) ∎\n6 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m n m)) ⟩\nsuc (m + (n + p)) ∎\n7 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m m p)) ⟩\nsuc (m + (n + p)) ∎\n8 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m m n)) ⟩\nsuc (m + (n + p)) ∎\n9 begin\nsuc (m + n + p) ≡⟨ cong suc (+-assoc m n p) ⟩\nsuc (m + (n + p)) ≡⟨\nsym (cong (λ _ → suc (m + (n + p))) (+-assoc m m m)) ⟩\nsuc (m + (n + p)) ∎\n solutions = re.split('\n[0-9]+ +', str)[1:] # skip the first line # need to insert two extra spaces for multiline solutions in order to preserve indentation solutions = [ '\n '.join(re.split('\n', solution)) for solution in solutions] # strip trailing newlines and spaces solutions = [ solution.rstrip() for solution in solutions] self.print(f"solutions is: {solutions}") # solution = " ".join(tokens[2:]) # skip the first "20 " (plus the extra space!) and put the tokens back return solutions def findAllHoles(self, code): i = 0 length = len(code) holes = [] while i < length: if code[i:i+2] == "--": # we are in a line comment while i < length and code[i] != "\n": i += 1 # skip to the end of the line elif code[i:i+2] == "{-": # we are in a block comment i += 2 k = 1 while i < length and k > 0: if code[i:i+2] == "{-": k += 1 i += 2 elif code[i:i+2] == "-}": k -= 1 i += 2 else: i += 1 elif code[i:i+1] == "?" and i+1 == length: holes.append((i, i+1)) i += 1 elif code[i:i+2] in ["(?"]: holes.append((i+1, i+2)) i += 2 elif code[i:i+2] in ["?)", "?;"]: holes.append((i, i+1)) i += 1 elif code[i:i+3] in [" ?\n", " ? ", "(?)"] or (code[i:i+2] == " ?" and i+2 == length): holes.append((i+1, i+2)) i += 2 elif code[i:i+2] == "{!": # beginning of a hole start = i i += 2 while i < length: # find the end of the hole (no nested holes) if code[i:i+2] == "!}": holes.append((start, i+2)) i += 2 break i += 1 else: i += 1 self.print(f'found holes: {holes}') return holes def findCurrentHole(self, code, pos): holes = self.findAllHoles(code) self.print(f'looking for hole at position: {pos}') k = 0 for (i, j) in holes: if i <= pos and pos <= j: # allow the cursor to be one position to the right of the hole return k k += 1 return -1 # no hole found def removeComments(self, code): level = 0 i = 0 length = len(code) result = "" while i < length: if level == 0 and code[i:i+2] == "--": # skip till the end of the line while i < length and code[i] != "\n": i += 1 result += "\n" if code[i:i+1] == "\n" else "" elif code[i:i+2] == "{-": level += 1 i += 1 elif code[i:i+2] == "-}" and level > 0: level -= 1 i += 1 elif level == 0: result += code[i] i += 1 return result def print(self, msg): try: self.log.error(msg) except AttributeError: print(msg)
def initializePigpiod(): child = pexpect.spawnu('bash') child.logfile = sys.stdout child.sendline("sudo pigpiod") time.sleep(1)
def step_start_cycli(context): context.cli = pexpect.spawnu("cycli -u neo4j -p password")
def main(): parser = argparse.ArgumentParser() parser.add_argument("--flash", help="flash bootrom & fullimage", action="store_true") parser.add_argument("--init", help="run init rdv4 script", action="store_true") parser.add_argument("-y", help="automatic yes to prompts", action="store_true") args = parser.parse_args() print("-----------", color('Proxmark3 online test script v1.0.3', fg='cyan'), "------------") print( "This script will run some series of test against a connected Proxmark3 device" ) print("Steps:") print(" 1. flash bootrom, fullimage") print(" 2. init_rdv4 / flash smartcard") print(" 3. check device mismatch message") print(" 4. check smart card fw, flash memory") print(" if needed, flash flash smartcard reader firmware") print(" 5. check antenna tuning") print(" 6. check LF T55x7 functionality") print(" 7. check HF search") print(" 8. check SPIFFS") print(" 9. check HF iCLASS functionality") print("\n") # result res = 0 total_tests = 12 must_update_fw = 0 msg = '' if args.flash: print("-----------------------", color('Flashing phase', fg='cyan'), "---------------------") print("flashing bootrom - don't touch the device or cables") pm3_flashbootrom() print("flashing fullimage - don't touch the device or cables") pm3_flashfullimage() print("\n") # start pm3 child = pexpect.spawnu('./pm3') i = child.expect('pm3 --> ') print("[+] Proxmark3 client open") if args.init: print("------------------------", color('Init phase', fg='cyan'), "------------------------") print("Running init rdv4 script - don't touch the device or cables") pm3_initrdv4(child) print("flashing smartcard - don't touch the device or cables") pm3_flash_sm(child) print("\n") print("------------------------", color('Test phase', fg='cyan'), "------------------------") # check device mismatch signature_msg = "device.................... RDV4".lower() # check flashmemory flash_mem = "baudrate................24 mhz".lower() # check smartcard fw version sm_version = "version.................v3.11".lower() # check LF lf_search = "valid hid prox id found!".lower() # check HF hf_search = "Valid iCLASS tag / PicoPass tag found".lower() # mem spiffs info mem_spiffs = "max path length............32 chars".lower() # lf antenna tuning lf_tune = "LF antenna is OK".lower() # hf antenna tuning hf_tune = "HF antenna is OK".lower() try: # HW VERSION checks child.sendline('hw version') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) if signature_msg in msg: print("[+] RDV4 signature ", color('[OK]', fg='green')) res += 1 else: print("[-] RDV4 signature ", color('[FAIL]', fg='red')) # HW STATUS checks child.sendline('hw status') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) if sm_version in msg: print("[+] Smart card firmware version ", color('[OK]', fg='green')) res += 1 else: print("[-] Smart card firmware version ", color('[FAIL]', fg='red'), " will upgrade fw in the next step") must_update_fw = 1 if flash_mem in msg: print("[+] Flash memory accessable ", color('[OK]', fg='green')) res += 1 else: print("[-] Flash memory accessable ", color('[FAIL]', fg='red')) # extract slow clock and verify its OK... # slow clock check: # Slow clock..............30057 Hz for line in msg.splitlines(): match_slow = line.find('slow clock..............') if match_slow > -1: match = re.search(r'\d+', line) if match: clock = int(match[0]) if clock < 29000: print( "[-] Warning, Slow clock too slow (%d Hz)" % (clock), color('[FAIL]', fg='red')) elif clock > 33000: print( "[-] Warning, Slow clock too fast (%d Hz)" % (clock), color('[FAIL]', fg='red')) else: print( "[+] Slow clock within acceptable range (%d Hz)" % (clock), color('[OK]', fg='green')) res += 1 except: print(color("[!] exception for HW STATUS", fg='red')) msg = escape_ansi(str(child.before)) print(msg) child.sendline('quit') child.expect(pexpect.EOF) return if must_update_fw == 1: if pm3_flash_sm(child): res += 1 try: print( "[=] starting antenna tune tests, this takes some time and plot window will flash up..." ) # HW TUNE checks child.sendline('hw tune') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) if lf_tune in msg: print("[+] LF antenna tuning ", color('[OK]', fg='green')) res += 1 else: print("[-] LF antenna tuning ", color('[FAIL]', fg='red')) if hf_tune in msg: print("[+] HF antenna tuning ", color('[OK]', fg='green')) res += 1 else: print("[-] HF antenna tuning ", color('[FAIL]', fg='red')) except: print(color("[!] exception for hw tune", fg='red')) msg = escape_ansi(str(child.before)) print(msg) child.sendline('quit') child.expect(pexpect.EOF) return # hide plot window again child.sendline('data hide') i = child.expect('pm3 --> ') ans = '' while ans != 'y' and args.y == False: ans = (input( color('>>> Put LF card and HF card on Proxmark3 antenna', fg='yellow') + ' [Y/n/q] ') or "y") if ans == 'q': child.sendline('quit') child.expect(pexpect.EOF) print('[!] Aborted all tests ', color('[USER ABORTED]', fg='red')) return # LF T55X7 WIPE/CLONE/READ TESTS if pm3_lf_t55xx(child): res += 1 # HF SEARCH TESTS try: print("[=] starting HF SEARCH tests...") # HF SEARCH Test child.sendline('hf search') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) if hf_search in msg: print("[+] HF SEARCH ", color('[OK]', fg='green')) res += 1 else: print("[-] HF SEARCH ", color('[FAIL]', fg='red')) except: print(color("[!] exception for HF SEARCH", fg='red')) msg = escape_ansi(str(child.before)) print(msg) child.sendline('quit') child.expect(pexpect.EOF) return # MEM Tree test child.sendline('mem spiffs info') i = child.expect('/', timeout=10) msg = escape_ansi(str(child.before)) if mem_spiffs in msg: print("[+] MEM SPIFFS INFO ", color('[OK]', fg='green')) res += 1 else: print("[-] MEM SPIFFS INFO ", color('[FAIL]', fg='red')) ans = '' while ans != 'y' and args.y == False: ans = (input( color('>>> Put iCLASS legacy card on Proxmark3 antenna', fg='yellow') + ' [Y/n/q] ') or "y") if ans == 'q': child.sendline('quit') child.expect(pexpect.EOF) print('[!] Aborted all tests ', color('[USER ABORTED]', fg='red')) return # iCLASS read/write test try: print("[=] starting iCLASS info/read/write tests...") child.sendline('hf iclass info') i = child.expect('pm3 --> ') # iclass info / read / write checks iclass_info = 'Credential... iCLASS legacy'.lower() iclass_ok = False msg = escape_ansi(str(child.before)) if iclass_info in msg: print("[+] HF ICLASS INFO ", color('[OK]', fg='green')) res += 1 iclass_ok = True else: print("[-] HF ICLASS INFO ", color('[FAIL]', fg='red')) if iclass_ok: child.sendline('hf iclass rdbl -b 10 --ki 0') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) for line in msg.splitlines(): iclass_read = 'block 10'.lower() if iclass_read in line: res += 1 print("[+] HF ICLASS RDBL ", color('[OK]', fg='green')) old_b10 = line[16:].replace(" ", "") child.sendline( 'hf iclass wrbl -b 10 --ki 0 -d 0102030405060708') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) iclass_write = 'wrote block 10 successful'.lower() if iclass_write in msg: res += 1 print("[+] HF ICLASS WRBL ", color('[OK]', fg='green')) child.sendline('hf iclass wrbl -b 10 --ki 0 -d %s' % (old_b10)) i = child.expect('pm3 --> ') else: print("[-] HF ICLASS WRBL ", color('[FAIL]', fg='red')) break else: print("[-] skipping iclass read/write") except: print(color("[!] exception iCLASS read/write", fg='red')) msg = escape_ansi(str(child.before)) print(msg) child.sendline('quit') child.expect(pexpect.EOF) return # exit Proxmark3 client child.sendline('quit') i = child.expect(pexpect.EOF) print("[+] PM3 client closed\n") # validate test results print("-------------------------", color('Results', fg='cyan'), "-------------------------") if res == total_tests: print('[+] Passed ', color('[OK]', fg='green')) else: print('[-] failed test ', color('[FAIL]', fg='red'), '(%d / %d tests)' % (res, total_tests)) print("")
if mount == True and motherboard == 'Lenovo': print("### LENOVO ###") unmount_Lenovo() cmd = lenovo_rdmount_path + ' -s ' + ipmiIpAddress + ' -d ' + iso_file_path + ' -l ' + ipmiUsername + ' -p ' + ipmiPassword print('### MOUNTING ###') m = subprocess.call(cmd, shell=True) print(m) elif mount == True and motherboard == 'SuperMicro': print("### SUPERMICRO ###") cmd = supermicro_smcipmitool_path + ' ' + ipmiIpAddress + ' ' + ipmiUsername + ' ' + ipmiPassword + ' shell' print(cmd) ############################ proc = pexpect.spawnu(cmd) #time.sleep(3) proc.expect('.*ASPD.*') #print (proc.before) print(proc.after) proc.sendline('vmwa status') proc.expect('.*ASPD.*') print(proc.after) iso_cmd = 'vmwa dev2iso ' + iso_file_path proc.sendline(iso_cmd) proc.expect('.*ASPD.*') print(proc.after) proc.sendline('ipmi power cycle') proc.expect('.*ASPD.*')
def test_user_aud_check_open(ald_init, app): admpass = ald_init[0] passfile = ald_init[1] aud_list = app.user.user_aud_list(passfile) user_list = app.user.user_list() user, u_passwd = valid_name_generator(), 'Testpass123' if user not in user_list: app.user.user_create(user, admpass, u_passwd) if user in str(aud_list): app.user.user_aud_del(user, admpass) app.user.user_aud_add(user, hex(aud_flags['open']), hex(aud_flags['open']), admpass) else: app.user.user_aud_add(user, hex(aud_flags['open']), hex(aud_flags['open']), admpass) app.user.user_ald_cap(user, getfqdn(), passfile) aud_dir = '/tmp/dir_for_test' aud_file = aud_dir + '/file_for_test' aud_flag = 'open' app.base.clean_kernel_mlog() try: os.mkdir(aud_dir, 0o700) except OSError as mkdir_err: if mkdir_err.errno == errno.EEXIST: os.chmod(aud_dir, 0o700) if os.access(aud_file, os.F_OK): os.remove(aud_file) else: raise with open(aud_file, 'w', encoding='utf-8') as audfile: audfile.write('test') os.chmod(aud_file, 0o700) user_uid = app.base.get_user_uid(user) os.chown(aud_file, user_uid, os.getuid()) os.chown(aud_dir, user_uid, os.getuid()) usession = pexpect.spawnu('login %s' % user, timeout=3) usession.expect('Пароль:') usession.sendline(u_passwd) usession.sendline('cat %s' % aud_file) time.sleep(2) kern_list = app.base.kernlog_list(user_uid) result = app.user.user_aud_check(kern_list, obj=aud_file, call=aud_flag) # in case of the 1st fail if not result: usession.sendline('exit') usession.expect(pexpect.EOF) usession.close() assert usession.exitstatus == 0 assert not usession.isalive() assert result app.base.clean_kernel_mlog() os.chmod(aud_file, 0o070) usession.sendline('cat %s' % aud_file) usession.sendline('exit') usession.expect(pexpect.EOF) usession.close() assert usession.exitstatus == 0 assert not usession.isalive() kern_list = app.base.kernlog_list(user_uid) result = app.user.user_aud_check(kern_list, obj=aud_file, call=aud_flag, flag='[f]') assert result
def step_run_cli(context): """ Run the process using pexpect. """ context.cli = pexpect.spawnu('pgcli')
# 2:11PM up 3 days, 13:50, 3 users, load averages: 0.01, 0.00, 0.00 # [powerpc] Darwin v1-58.corefa.com 8.2.0 Darwin Kernel Version 8.2.0 # 10:35 up 18:06, 4 users, load averages: 0.52 0.47 0.36 # [Sparc - R220] Sun Solaris (8) # 2:13pm up 22 min(s), 1 user, load average: 0.02, 0.01, 0.01 # [x86] Linux 2.4.18-14 (Redhat 8) # 11:36pm up 4 days, 17:58, 1 user, load average: 0.03, 0.01, 0.00 # AIX jwdir 2 5 0001DBFA4C00 # 09:43AM up 23:27, 1 user, load average: 0.49, 0.32, 0.23 # OpenBSD box3 2.9 GENERIC#653 i386 # 6:08PM up 4 days, 22:26, 1 user, load averages: 0.13, 0.09, 0.08 # Note that, for Python 3 compatibility reasons, we are using spawnu and # importing unicode_literals (above). spawnu accepts Unicode input and # unicode_literals makes all string literals in this script Unicode by default. p = pexpect.spawnu("uptime") # This parses uptime output into the major groups using regex group matching. p.expect( r"up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])" ) duration, users, av1, av5, av15 = p.match.groups() # The duration is a little harder to parse because of all the different # styles of uptime. I'm sure there is a way to do this all at once with # one single regex, but I bet it would be hard to read and maintain. # If anyone wants to send me a version using a single regex I'd be happy to see it. days = "0" hours = "0" mins = "0" if "day" in duration:
def spawn_process(command): """return a handle to a new controllable child process""" return pexpect.spawnu(command, dimensions=(24, 250))
#!/usr/bin/env python #coding:utf-8 from __future__ import unicode_literals # 使用unicode编码 import pexpect import sys child = pexpect.spawnu('ftp ftp.openbsd.org') # 运行ftp命令 info = file('ftp.txt', 'w') # 记录连接日志信息 child.logfile = info # 匹配账号输入提示,(?i)表示后面的字符串正则匹配忽略大小写 child.expect('(?i)name .*: ') child.sendline('anonymous') # 输入ftp账号信息 child.expect('(?i)password') # 匹配密码输入提示 child.sendline('*****@*****.**') # 输入ftp密码 # 调用interact()让出控制权,用户可以继续当前的会话手工控制子程序 child.interact() child.sendline('bye') child.close()
def __init__(self): subprocess.check_output("rfkill unblock bluetooth", shell=True) self.process = pexpect.spawnu("bluetoothctl", echo=False)
def test_user_aud_check_mac(ald_init, app): admpass = ald_init[0] passfile = ald_init[1] aud_list = app.user.user_aud_list(passfile) user_list = app.user.user_list() user, u_passwd = valid_name_generator(), 'Testpass123' if user not in user_list: app.user.user_create(user, admpass, u_passwd) if user in str(aud_list): app.user.user_aud_del(user, admpass) app.user.user_aud_add(user, hex(aud_flags['mac']), hex(aud_flags['mac']), admpass) else: app.user.user_aud_add(user, hex(aud_flags['mac']), hex(aud_flags['mac']), admpass) cap = 'parsec_cap_chmac' app.user.user_ald_cap(user, getfqdn(), passfile) aud_dir = '/dir_for_test' aud_flag = 'parsec_chmac' try: os.mkdir(aud_dir, 0o700) except OSError as mkdir_err: if mkdir_err.errno == errno.EEXIST: shutil.rmtree(aud_dir) os.mkdir(aud_dir, 0o700) else: raise app.base.clean_kernel_mlog() user_uid = app.base.get_user_uid(user) app.user.user_parsec_cap_mod(user, cap, admpass) usession = pexpect.spawnu('login %s' % user, timeout=3) usession.expect('Пароль:') usession.sendline(u_passwd) usession.expect(user + '@' + gethostname()) usession.sendline('/usr/sbin/pdpl-file 1:0:0 %s' % '/') usession.expect(user + '@' + gethostname()) usession.sendline('exit') usession.expect(pexpect.EOF) usession.close() assert usession.exitstatus == 0 assert not usession.isalive() kern_list = app.base.kernlog_list(user_uid) result = app.user.user_aud_check(kern_list, call=aud_flag, obj='/', flag='[f]') assert result app.base.clean_kernel_mlog() usession = pexpect.spawnu('login %s' % user, timeout=3) usession.expect('Пароль:') usession.sendline(u_passwd) usession.expect(user + '@' + gethostname()) usession.sendline('/usr/sbin/pdpl-file 1:0:0 %s' % aud_dir) usession.expect(user + '@' + gethostname()) usession.sendline('exit') usession.expect(pexpect.EOF) usession.close() assert usession.exitstatus == 0 assert not usession.isalive() kern_list = app.base.kernlog_list(user_uid) result = app.user.user_aud_check(kern_list, call=aud_flag, obj=aud_dir, flag='[s]') assert result shutil.rmtree(aud_dir)
def test_stty_dash_a_before_and_afetr_invoking_lldb_command(self): """Test that 'stty -a' displays the same output before and after running the lldb command.""" import pexpect if not which('expect'): self.skipTest( "The 'expect' program cannot be located, skip the test") # The expect prompt. expect_prompt = "expect[0-9.]+> " # The default lldb prompt. lldb_prompt = "(lldb) " # So that the child gets torn down after the test. self.child = pexpect.spawnu('expect') child = self.child child.expect(expect_prompt) child.setecho(True) if self.TraceOn(): child.logfile = sys.stdout if self.platformIsDarwin(): child.sendline('set env(TERM) xterm') else: child.sendline('set env(TERM) vt100') child.expect(expect_prompt) child.sendline('puts $env(TERM)') child.expect(expect_prompt) # Turn on loggings for input/output to/from the child. child.logfile_send = child_send1 = six.StringIO() child.logfile_read = child_read1 = six.StringIO() child.sendline('stty -a') child.expect(expect_prompt) # Now that the stage1 logging is done, restore logfile to None to # stop further logging. child.logfile_send = None child.logfile_read = None # Invoke the lldb command. child.sendline(lldbtest_config.lldbExec) child.expect_exact(lldb_prompt) # Immediately quit. child.sendline('quit') child.expect(expect_prompt) child.logfile_send = child_send2 = six.StringIO() child.logfile_read = child_read2 = six.StringIO() child.sendline('stty -a') child.expect(expect_prompt) child.sendline('exit') # Now that the stage2 logging is done, restore logfile to None to # stop further logging. child.logfile_send = None child.logfile_read = None if self.TraceOn(): print("\n\nContents of child_send1:") print(child_send1.getvalue()) print("\n\nContents of child_read1:") print(child_read1.getvalue()) print("\n\nContents of child_send2:") print(child_send2.getvalue()) print("\n\nContents of child_read2:") print(child_read2.getvalue()) stty_output1_lines = child_read1.getvalue().splitlines() stty_output2_lines = child_read2.getvalue().splitlines() zipped = list(zip(stty_output1_lines, stty_output2_lines)) for tuple in zipped: if self.TraceOn(): print("tuple->%s" % str(tuple)) # Every line should compare equal until the first blank line. if len(tuple[0]) == 0: break self.assertEqual(tuple[0], tuple[1])
def test_master_descriptor_publication(tmpdir): """ Functional test to run OnionBalance, publish a master descriptor and check that it can be retrieved from the DHT. """ chutney_config = parse_chutney_enviroment() private_key = Crypto.PublicKey.RSA.generate(1024) master_onion_address = onionbalance.util.calc_onion_address(private_key) config_file_path = create_test_config_file( tmppath=tmpdir, private_key=private_key, instances=chutney_config.get('instances', []), ) assert config_file_path # Start an OnionBalance server and monitor for correct output with pexpect server = pexpect.spawnu("onionbalance", args=[ '-i', chutney_config.get('client_ip'), '-p', str(chutney_config.get('control_port')), '-c', config_file_path, '-v', 'debug', ], logfile=sys.stdout, timeout=15) # Check for expected output from OnionBalance server.expect(u"Loaded the config file") server.expect(u"introduction point set has changed") server.expect(u"Published a descriptor", timeout=120) # Check Tor control port gave an uploaded event. server.expect(u"HS_DESC UPLOADED") # Eek, sleep to wait for descriptor upload to all replicas to finish time.sleep(10) # .. todo:: Also need to check and raise for any warnings or errors # that are emitted # Try fetch and validate the descriptor with stem with stem.control.Controller.from_port( address=chutney_config.get('client_ip'), port=chutney_config.get('control_port') ) as controller: controller.authenticate() # get_hidden_service_descriptor() will raise exceptions if it # cannot find the descriptors master_descriptor = controller.get_hidden_service_descriptor( master_onion_address) master_ips = master_descriptor.introduction_points() # Try retrieve a descriptor for each instance for instance_address in chutney_config.get('instances'): instance_descriptor = controller.get_hidden_service_descriptor( instance_address) instance_ips = instance_descriptor.introduction_points() # Check if all instance IPs were included in the master descriptor assert (set(ip.identifier for ip in instance_ips) == set(ip.identifier for ip in master_ips))
re_ip_exception = re.compile(r'(\d{1,3}\.){4,}') if re_ip_exception.search(wlc_ip): ip_warning(wlc_ip) verify_ip = re_ip.search(wlc_ip) if verify_ip: ip_group = verify_ip.groups() for ip in ip_group: if int(ip) >= 255: ip_warning(wlc_ip) else: ip_warning(wlc_ip) wlc_connect = pexpect.spawnu('ssh ' + wlc_ip) #wlc_connect.logfile = sys.stdout wlc_connect.expect('User:'******'Password:'******'(Cisco Controller)', 'User']) if login_check == 1: print("Login Error, Check your account status") sys.exit(0) else: print("Login Successfully") wlc_connect.sendline('show ap summary')
def test_master_descriptor_publication(tmpdir): """ Functional test to run OnionBalance, publish a master descriptor and check that it can be retrieved from the DHT. """ chutney_config = parse_chutney_enviroment() private_key = Crypto.PublicKey.RSA.generate(1024) master_onion_address = onionbalance.hs_v2.util.calc_onion_address( private_key) config_file_path = create_test_config_file( tmppath=tmpdir, private_key=private_key, instances=chutney_config.get('instances', []), ) assert config_file_path # Start an OnionBalance server and monitor for correct output with pexpect server = pexpect.spawnu("onionbalance", args=[ '--hs-version', 'v2', '-i', chutney_config.get('client_ip'), '-p', str(chutney_config.get('control_port')), '-c', config_file_path, '-v', 'debug', ], logfile=sys.stdout, timeout=15) # Check for expected output from OnionBalance server.expect(u"Loaded the config file") server.expect(u"introduction point set has changed") server.expect(u"Published a descriptor", timeout=120) # Check Tor control port gave an uploaded event. server.expect(u"HS_DESC UPLOADED") # Eek, sleep to wait for descriptor upload to all replicas to finish time.sleep(10) # .. todo:: Also need to check and raise for any warnings or errors # that are emitted # Try fetch and validate the descriptor with stem with stem.control.Controller.from_port( address=chutney_config.get('client_ip'), port=chutney_config.get('control_port')) as controller: controller.authenticate() # get_hidden_service_descriptor() will raise exceptions if it # cannot find the descriptors master_descriptor = controller.get_hidden_service_descriptor( master_onion_address) master_ips = master_descriptor.introduction_points() # Try retrieve a descriptor for each instance for instance_address in chutney_config.get('instances'): instance_descriptor = controller.get_hidden_service_descriptor( instance_address) instance_ips = instance_descriptor.introduction_points() # Check if all instance IPs were included in the master descriptor assert (set(ip.identifier for ip in instance_ips) == set(ip.identifier for ip in master_ips)) # Check that the control socket was created socket_path = tmpdir.join('control') assert socket_path.check() # Connect to the control socket and check the output sock_client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock_client.connect(str(socket_path)) # Read the data from the status socket result = [] while True: data = sock_client.recv(1024) if not data: break result.append(data.decode('utf-8')) result_data = ''.join(result) # Check each instance is in the output for instance_address in chutney_config.get('instances'): assert instance_address in result_data # Check all instances were online and all master descriptors uploaded assert master_onion_address in result_data assert '[offline]' not in result_data assert '[not uploaded]' not in result_data
# output that line. The 'child.sendline' lines tell `pexpect` to send # that information to the program. # # With these two combined, we can simulate typing really quickly! It # makes it **much** easier that trying to type in input values # again... and again... and again... # # You aren't required to use this file. It's just here to make testing # a little easier, if you want to give it a try. # ## import pexpect import sys # Start the XY77 program child = pexpect.spawnu('python3.4 main.py') # Keep track of output from the attached program. child.logfile_read = sys.stdout ## # Setup # # Serial number child.expect(">> ") # Wait for a >> child.sendline("KRXX7e3652") # When we see a >>, send the serial number # Check Engine light child.expect(">> ") child.sendline("0")
#!/usr/bin/env python import pexpect import subprocess import sys image_name = sys.argv[1] pex = pexpect.spawnu("whoami") pex.expect(u'(\S+)') username = pex.match.groups()[0] pex = pexpect.spawnu("shifterimg lookup %s" % image_name) pex.expect(u'([0-9a-f]+)') image_id = pex.match.groups()[0] expected_config = u'{"identifier":"%s","user":"******","volMap":""}' \ % (image_id, username) pex = pexpect.spawnu("shifter --image=%s cat /var/shifterConfig.json" % image_name) pex.expect(expected_config)
def test_expect_echo(self): '''This tests that echo can be turned on and off. ''' p = pexpect.spawnu('cat', timeout=10) self._expect_echo(p)
# Transfer the Database print('OK, I am going to try to migrate the database now...') db_proc = """mysqldump -u{0} -p{1} -h{2} {3} | sed "s/TIME_ZONE='+00:00'/TIME_ZONE='+06:00'/" | pv | xz -c -4 | ssh {4}@{5} "xz -d -c | mysql -u{6} -p{7} -h{8} {9}" """.format( args.source_db_user, shlex.quote(args.source_db_pass), args.source_db_host, args.source_db_name, args.dest_sftp_user, args.destination, args.dest_db_user, shlex.quote(args.dest_db_pass), args.dest_db_host, args.dest_db_name) if args.verbose: print(db_proc) try: # This is the "wrong" way to do it, but I can't get the nested Popen's to work if args.dest_sftp_pass is None: exitcode = subprocess.call(db_proc, shell=True) else: child = pexpect.spawnu('/bin/bash', ['-c', db_proc], timeout=None) child.expect(['password: '******'DB copy failed. Abort!') exit(1) # Update the DB refs in local.xmls or wp-config.php
def test_expect_echo_exact(self): '''Like test_expect_echo(), but using expect_exact(). ''' p = pexpect.spawnu('cat', timeout=10) p.expect = p.expect_exact self._expect_echo(p)
async def analyze_callback(mythic, callback): try: task = Task(callback=callback, command="nmap", params="a") print("[+] got new callback, retrieving ip address") submit = await mythic.create_task(task, return_on="completed") print("[*] waiting for ls results...") results = await mythic.gather_task_responses(submit.response.id, timeout=20) for res in results: print(res) if res.task.command.cmd == 'nmap asd': ip = res.response print("Scanning " + ip) output = pexpect.run("sshuttle -r [email protected] 0/0", events={'.*assword': 'bubiman10\n'}) print("\nThe output of sshuttle command: \n%s" % output.decode("utf-8")) ip = requests.get('https://api.ipify.org').text print('My public IP address is: {}'.format(ip)) output = pexpect.run("nmap 192.168.0.0/24") print("\nThe output of nmap command: \n%s" % output.decode("utf-8")) child = pexpect.spawnu("bash") child.logfile = open("./log.log", "w") child.expect(".*@") child.sendline("sshuttle -r [email protected] 0/0") child.expect(".*assword") child.sendline("bubiman10") child.expect(".*assword") child.sendline("bubiman10") child.expect(".*onnected") p = pexpect.spawnu("bash") p.logfile_read = open("./log2.log", "w") p.sendline("curl ipv4.icanhazip.com") time.sleep(1) p.expect(".*\.") address_file = open("./log2.log", "r") text = str(address_file.readlines()) pattern = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') ip = pattern.findall(text)[0] os.remove("./log.log") os.remove("./log2.log") nmap = pexpect.spawnu("bash") nmap.logfile = open("./nmap_" + ip + ".log", "w") nmap.sendline("nmap -iR 1") nmap.expect("Nmap done") # task = Task( # callback=callback, command="ls", params="." # ) # print("[+] got new callback, issuing ls") # submit = await mythic.create_task(task, return_on="completed") # print("[*] waiting for ls results...") # results = await mythic.gather_task_responses(submit.response.id, timeout=20) # folder = json.loads(results[0].response) # print("[*] going through results looking for interesting files...") # for f in folder["files"]: # if f["name"] == "provaserver": # task = Task( # callback=callback, command="download", params="provaserver" # ) # print("[+] found an interesting file, tasking it for download") # await mythic.create_task(task, return_on="submitted") # task = Task( # callback=callback, command="list_apps" # ) # print("[+] tasking callback to list running applications") # list_apps_submit = await mythic.create_task(task, return_on="submitted") # print("[*] waiting for list_apps results...") # results = await mythic.gather_task_responses(list_apps_submit.response.id) # apps = json.loads(results[0].response) # print("[*] going through results looking for dangerous processes...") # for a in apps: # if "Little Snitch Agent" in a["name"]: # list_apps_submit.response.comment = "Auto processed, created alert on Little Snitch Agent, updating block lists" # await mythic.set_comment_on_task(list_apps_submit.response) # print("[+] found a dangerous process! Little Snitch Agent - sending alert to operators") # await mythic.create_event_message(message=EventMessage(message="LITTLE SNITCH DETECTED on {}".format(callback.host), level='warning')) # resp = await mythic.get_all_disabled_commands_profiles() # print("[+] Getting/creating disabled command profile to prevent bad-opsec commands based on dangerous processes") # snitchy_block_list_exists = False # for cur_dcp in resp.response: # if cur_dcp.name == "snitchy block list": # snitchy_block_list_exists = True # dcp = cur_dcp # if not snitchy_block_list_exists: # dcp = DisabledCommandsProfile(name="snitchy block list", payload_types=[ # PayloadType(ptype="prova", commands=["shell", "shell_elevated"]), # PayloadType(ptype="poseidon", commands=["shell"]) # ]) # resp = await mythic.create_disabled_commands_profile(dcp) # current_operation = (await mythic.get_current_operation_info()).response # for member in current_operation.members: # print("[*] updating block list for {}".format(member.username)) # resp = await mythic.update_disabled_commands_profile_for_operator(profile=dcp, operator=member, operation=current_operation) except Exception as e: print(str(e))
def qqq(action, fiename, port): try: # Connect to the device tmp = conntimeout handler = pexpect.spawnu('telnet %s %i' % (ip, port), maxread=20000) handler.logfile = sys.stdout handler.crlf = '\r\n' while (tmp > 0): #handler.sendline('') time.sleep(0.1) tmp = tmp - 0.1 if handler.isalive() == True: break if action == 'get': if (handler.isalive() != True): print('ERROR: cannot connect to port "%i".' % (port)) node_quit(handler) sys.exit(1) rc = node_login(handler) if rc != True: print('ERROR: failed to login.') node_quit(handler) sys.exit(1) config = config_get(handler) if config in [False, None]: print('ERROR: failed to retrieve config.') node_quit(handler) sys.exit(1) try: fd = open(filename, 'a') fd.write(config) fd.close() except: print('ERROR: cannot write config to file.') node_quit(handler) sys.exit(1) elif action == 'put': rc = config_put(handler) if rc != True: print('ERROR: failed to push config.') node_quit(handler) sys.exit(1) # Remove lock file lock = '%s/.lock' % (os.path.dirname(filename)) if os.path.exists(lock): os.remove(lock) # Mark as configured configured = '%s/.configured' % (os.path.dirname(filename)) if not os.path.exists(configured): open(configured, 'a').close() node_quit(handler) sys.exit(0) except Exception as e: print('ERROR: got an exception') print(type(e)) # the exception instance print(e.args) # arguments stored in .args print(e) # __str__ allows args to be printed directly, node_quit(handler) return False
def step_start_cycli_read_only(context): context.cli = pexpect.spawnu("cycli -u neo4j -p password -r")
def run_interactive_command(prompt_answers, command, *args): """ Helper function that runs the specified command, and takes care of providing answers to interactive prompts. This is a convenience wrapper around the pexpect library. Unlikes the run_command helper, this helper is not capable of separating the standard output from standard error (unfortunately). The failure message returned describes only issues related to command not providing the expected prompt for answer, or if command gets stuck in a prompt after all expected prompts were processed. :param prompt_answers: List of prompts and their correspnding answers. To send a control character, start the answer with 'Ctrl-' (for example 'Ctrl-d'). :type prompt_answers: list[(str, str)] :param command: Command that should be run. :type command: str :param *args: Zero or more arguments to pass to the command. :type *args: str :returns: (failure, output, exit_code) -- Prompt failure message, combined standard output and error, and exit code (None if prompt failure happened). :rtype: (str or None, str, int) """ # Assume that all prompts/answers worked as expected. failure = None # Spawn the process, use dedicated stream for capturin command # stdout/stderr. output_stream = io.StringIO() send_stream = io.StringIO() process = pexpect.spawnu(command, list(args), timeout=4) process.logfile_read = output_stream process.logfile_send = send_stream # Try to feed the interactive process with answers. Stop iteration # at first prompt that was not reached. for prompt, answer in prompt_answers: try: process.expect(prompt) if answer.startswith('Ctrl-'): process.sendcontrol(answer.lstrip('Ctrl-')) else: process.sendline(answer) except pexpect.TIMEOUT: failure = "Command never prompted us with: %s" % prompt process.terminate() break # If we were successful until now, wait for the process to exit. if failure is None: try: process.expect(pexpect.EOF) except pexpect.TIMEOUT: failure = "Command got stuck waiting for input." process.terminate() process.close() output = output_stream.getvalue() exit_code = process.exitstatus return failure, output, exit_code
reversed( sorted([ d for d in os.listdir(result_dir_parent) if os.path.isdir(os.path.join(result_dir_parent, d)) ]))) return os.path.join(result_dir_parent, latest_subdir) device_detected_re = re.compile(r"DeviceManager: Detected new device ") device_detected_search_re = re.compile( r"DeviceManager: Detected new device .*$", flags=re.M) tradefed_start_retry_count = 5 all_devices_names = set(device.serial_or_address for device in devices) for tradefed_start_retry in range(tradefed_start_retry_count): child = pexpect.spawnu(command, logfile=tradefed_stdout) try: devices_to_detect = all_devices_names.copy() while devices_to_detect: # Find and parse output lines following this pattern: # 04-23 12:30:33 I/DeviceManager: Detected new device serial_or_address child.expect(device_detected_re, timeout=30) output_lines = subprocess.check_output(["tail", TRADEFED_STDOUT ]).decode("utf-8") matches = [ match[1].strip() for match in (device_detected_re.split(line_match) for line_match in device_detected_search_re.findall(output_lines)) if len(match) == 2 and match[1] ]