def no_es_pesado_en_la_cpu(self): "la duplicación de stdin no requiere mucha CPU" # La medición de CPU bajo PyPy es ... bastante diferente. NBD. if PYPY: skip() # Se ha visto que Python 3.5 usa hasta ~ 6.0 s de tiempo de CPU bajo Travis with asegurar_el_uso_de_la_cpu(lt=7.0): correr("python -u ocupadoafull.py 10", pty=True, ocultar=True)
def bytes_no_imprimibles_en_pty(self): if WINDOWS: return # El uso de PTY agrega otro punto de decodificación utf-8 que # también puede fallar. correr( "echo '\xff'", pty=True, ocultar="stderr", sal_stream=self.bad_stdout, )
def ambos_streams(self): centinelas = [ Respondedor("salida estandar", "con eso\n"), Respondedor("error estandar", "entre silla y teclado\n"), ] correr( "python -u responder_ambos.py", centinelas=centinelas, ocultar=True, tiempofuera=5, )
def desencadena_una_excepcion_cuando_el_comando_es_lento(self): antes = time.time() with raises(CaducoComando) as info: correr("sleep 5", tiempofuera=0.5) despues = time.time() # Modifique un poco la comprobación en tiempo real, <= 0,5 # normalmente falla debido a overhead, etc. ¿Es posible que # necesite aumentar más para evitar carreras? Meh. assert (despues - antes) <= 0.75 # Comprobaciones de cordura del obj de excepción assert info.valor.tiempofuera == 0.5 assert info.valor.resultado.comando == "sleep 5"
def caso_base(self): # prueba básica "no explota": respond.py saldrá distinto de cero # a menos que esto funcione, provocando una Falla. centinela = Respondedor(r"Cual es la contraseña\?", "Subamarillo\n") # Tengo que dar -u o Python almacenará en búfer de línea su # stdout, por lo que nunca veremos el prompt. correr( "python -u responder_base.py", centinelas=[centinela], ocultar=True, tiempofuera=5, )
def anidamiento_complejo_bajo_ptys_no_se_rompe(self): if WINDOWS: # No estoy seguro de cómo hacer que esto funcione en Windows return # GH issue 191 subcadena = " hola\t\t\nmundo con espacios" cmd = """ eval 'echo "{}" ' """.format(subcadena) esperado = " hola\t\t\r\nmundo con espacios\r\n" assert correr(cmd, pty=True, ocultar="ambos").stdout == esperado
def pty_pone_ambas_streams_en_stdout(self): if WINDOWS: return os.chdir("_soporte") err_echo = "{} err.py".format(sys.executable) comando = "echo foo && {} bar".format(err_echo) r = correr(comando, ocultar="ambos", pty=True) assert r.stdout == "foo\r\nbar\r\n" assert r.stderr == ""
def Errores_del_centinela_se_convierten_en_Fallas(self): centinela = DetectorDeRespuestasIncorrectas( patron=r"Cual es la contraseña\?", respuesta="Subamarillo\n", centinela="¡No eres ciudadano Cleb!", ) try: correr( "python -u responder_falla.py", centinelas=[centinela], ocultar=True, tiempofuera=5, ) except Falla as e: assert isinstance(e.motivo, ErrorDeCentinela) assert e.resultado.salida is None else: assert False, "No dio Falla!"
def comando_simple_con_pty(self): """ Correr comando bajo PTY """ # La mayoría de los sistemas Unix deben tener stty, que explota # cuando no corre bajo una pty, e imprime información útil de otra # manera resultado = correr("stty -a", ocultar=True, pty=True) # PTYs use \r\n, no \n, linea de separacion assert "\r\n" in resultado.stdout assert resultado.pty is True
def dimension_de_pty_es_realista(self): # Cuando no establecemos explícitamente el tamaño pty, 'stty size' # lo ve como 0x0. # Cuando lo fijamos, debería ser un valor distinto de 0x0, no # 80x24 (el valor por defecto). (sí, esto significa que falla si # realmente tienes una terminal de 80x24. pero ¿quién hace eso?) dimension = correr("stty dimension", ocultar=True, pty=True).stdout.strip() assert dimension != "" assert dimension != "0 0" assert dimension != "24 80"
def bytes_no_imprimibles(self): # Los caracteres que no se imprimen (es decir, que no son UTF8) # tampoco explotan (se imprimirían como escapes normalmente, # pero aún así) correr("echo '\xff'", ocultar="stderr", sal_stream=self.bad_stdout)
def mostrar_ayuda(self): assert "Uso: du[ed] " in correr("dued --help").stdout
def _salida_eq(cmd, esperado): assert correr(cmd, ocultar=True).stdout == esperado
def stdin_canalizado_no_se_combina_con_stdin_simulado(self): # Re: número 308 de GH # Morirá en OSError de tubería rota si el error está presente. correr("echo 'lollerskates' | du -c anidado_o_canalizado foo", ocultar=True)
def no_se_dispara_cuando_el_comando_es_rapido(self): assert correr("sleep 1", tiempofuera=5)
def salidas_de_mala_coleccion_no_son_cero(self): resultado = correr("du -c nop -l", alarma=True) assert resultado.salida == 1 assert not resultado.stdout assert resultado.stderr
def caracteres_basicos_no_estandar(self): os.chdir("_soporte") # Crummy "no explota con errores de decodificación" prueba cmd = ("type" if WINDOWS else "cat") + " arbol.salida" correr(cmd, ocultar="stderr", sal_stream=self.bad_stdout)
def sesiones_dued_anidadas_no_combinadas_con_stdin_simulado(self): # También sobre: GH número 308. Este simplemente se quedará # colgado para siempre. ¡Cortejar! correr("du -c anidado_o_canalizado calls-foo", ocultar=True)
def ayuda_por_artefacto(self): assert "Frobazz" in correr("dued -c _explicito foo --help").stdout
def no_se_rompe_cuando_existe_stdin_sino_nulo(self): # Re: #425 - IOError ocurre cuando hay un error presente correr("du -c anidado_o_canalizado foo < /dev/null", ocultar=True)
def correr(self, Contexto): resultado = dued.correr("foo", bar="biz") ctx = Contexto.valor_de_retorno ctx.correr.asercion_llamado_una_vez_con("foo", bar="biz") assert resultado is ctx.correr.valor_de_retorno