]> git.llucax.com Git - software/sercom-old.git/blobdiff - src/sc_test
Manda mails notificando si compila bien.
[software/sercom-old.git] / src / sc_test
index 08096c6b977b85d43a2c7f10aeb894730835728a..2e4be200312e48e41f49a5e65c85316bbcee8fa8 100755 (executable)
@@ -11,10 +11,11 @@ import glob
 import shutil
 import datetime
 import subprocess
 import shutil
 import datetime
 import subprocess
+import email.MIMEMultipart
 # Módulos locales
 import sercom
 # Módulos locales
 import sercom
-import sercom.dbo
-from sercom.dbo import *
+import sercom.sqlo
+from sercom.sqlo import *
 
 class secure_process:
     def __init__(self, chroot, uid, gid, cpu):
 
 class secure_process:
     def __init__(self, chroot, uid, gid, cpu):
@@ -56,30 +57,41 @@ def sigterm(signum, frame):
 def chroot_dir(intento):
     return os.path.join(intento.path, 'chroot')
 
 def chroot_dir(intento):
     return os.path.join(intento.path, 'chroot')
 
-def compilar(intento):
+def compilar(intento, mail):
     global log
     # Busco makefile
     makefile = os.path.join(intento.entrega.ejercicio.path, 'Makefile')
     # Compilo
     log.debug('Ejecutando: make -f %s', makefile)
     intento.inicioCompila = datetime.datetime.now()
     global log
     # Busco makefile
     makefile = os.path.join(intento.entrega.ejercicio.path, 'Makefile')
     # Compilo
     log.debug('Ejecutando: make -f %s', makefile)
     intento.inicioCompila = datetime.datetime.now()
-    make = subprocess.Popen(('make', '-f', makefile), stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE, cwd=intento.path)
+    make = subprocess.Popen(('make', '-f', makefile), stderr=subprocess.PIPE,
+        cwd=intento.path)
     make.wait()
     intento.finCompila = datetime.datetime.now()
     log.debug('Fin del comando: make -f %s', makefile)
     # Verifico compilación
     make.wait()
     intento.finCompila = datetime.datetime.now()
     log.debug('Fin del comando: make -f %s', makefile)
     # Verifico compilación
-    if make.returncode:
-        log.debug('Error al compilar, código de retorno: %d, salida estándar: '
-            '%s, salida de error: %s)', make.returncode, make.stdout.read(),
-            make.stderr.read())
-        intento.compila = False
-        #TODO enviar_respuesta(R_ERR, $mail, "ERROR AL COMPILAR!\n\n$err\n\nCódigo de retorno: $ret\n", $intento);
-        return False
-    log.debug('Compilado OK')
-    intento.compila = True
-    #TODO mail acumulativo
-    return True
+    stderr = make.stderr.read()
+    intento.compila = not make.returncode
+    msg = 'Compilación: '
+    if intento.compila and not stderr:
+        msg += 'BIEN'
+    elif intento.compila:
+        msg += 'CON ADVERTENCIAS'
+    else:
+        msg += 'ERROR (código de retorno: %d)' % make.returncode
+    mail.body += msg
+    if stderr:
+        msg += '''Salida:
+------------------------------------------------------------------------
+%s
+------------------------------------------------------------------------
+
+''' % stderr
+        mail.body += "\n(se adjunta salida, archivo 'make.stderr')\n"
+        mail.attachText(stderr, 'make.stderr')
+    mail.body += '\n\n'
+    intento.observaciones = msg + '\n\n'
+    log.debug(msg)
 
 def preparar(intento):
     # Creo chroot - TODO copiarlo de algún lado donde ande el valgrind?
 
 def preparar(intento):
     # Creo chroot - TODO copiarlo de algún lado donde ande el valgrind?
@@ -91,7 +103,7 @@ def limpiar(intento):
     # Borro chroot entero
     shutil.rmtree(chroot_dir(intento))
 
     # Borro chroot entero
     shutil.rmtree(chroot_dir(intento))
 
-def probar(intento, caso_de_prueba):
+def probar(intento, caso_de_prueba, mail):
     # Cosas útiles
     global log, conn, conf, uid, gid
     # Para manejo de SIGCHLD
     # Cosas útiles
     global log, conn, conf, uid, gid
     # Para manejo de SIGCHLD
@@ -250,6 +262,48 @@ def params2seq(params):
         seq.append(buff)
     return seq
 
         seq.append(buff)
     return seq
 
+class MailIntento(email.MIMEMultipart.MIMEMultipart, object):
+    def __init__(self, intento):
+        global conf
+        from email.MIMEMultipart import MIMEMultipart
+        from email.MIMEMessage import MIMEMessage
+        from email.MIMEText import MIMEText
+        MIMEMultipart.__init__(self)
+        self.subject = '[%s] Resultado del intento %d del ejercicio %d.%d' % \
+            (conf.get('mail', 'prefijo'), intento.numero,
+                intento.entrega.nroEjercicio, intento.entrega.entrega)
+        self['From'] = conf.get('mail', 'from')
+        self['To'] = intento.mailRespuesta
+        self['Reply-To'] = conf.get('mail', 'admin')
+        self['Return-Path'] = conf.get('mail', 'admin')
+        self['X-Mailer'] = 'sercom 0.3'
+        self['X-Priority'] = '5'
+        self.epilogue = 'Para ver correctamente este e-mail su cliente debe ' \
+            'soportar MIME.\n\n'
+        self.prologue = '' # Garantiza que termine en \n el mensaje
+        self.attach(MIMEMessage(MIMEText('', 'plain', 'iso-8859-1')))
+        self.resultado = None
+    def __set_body(self, body):
+        self.get_payload(0).get_payload(0).set_payload(body)
+    def __get_body(self):
+        return self.get_payload(0).get_payload(0).get_payload()
+    body = property(__get_body, __set_body, doc='Cuerpo del mensaje.')
+    def attachText(self, text, nombre=None):
+        from email.MIMEText import MIMEText
+        attach = MIMEText(text, 'plain', 'iso-8859-1')
+        if nombre:
+            attach.add_header('Content-Disposition', 'attachment', filename=nombre)
+        self.attach(attach)
+    def send(self, resultado=None):
+        import smtplib
+        global conf
+        smtp = smtplib.SMTP(conf.get('mail', 'smtp'))
+        if resultado:
+            self.subject += ': ' + resultado
+        self['Subject'] = self.subject
+        smtp.sendmail(self['From'], self['To'], self.as_string())
+        smtp.close()
+
 # Manejadores de señales
 signal.signal(signal.SIGTERM, sigterm)
 signal.signal(signal.SIGINT, sigterm)
 # Manejadores de señales
 signal.signal(signal.SIGTERM, sigterm)
 signal.signal(signal.SIGINT, sigterm)
@@ -271,7 +325,7 @@ os.seteuid(uid)
 intervalo = float(conf.get('general', 'intervalo'))
 
 # Utilizo el directorio de datos como base para todos los SQLObjects
 intervalo = float(conf.get('general', 'intervalo'))
 
 # Utilizo el directorio de datos como base para todos los SQLObjects
-sercom.dbo.dir_base = conf.get('general', 'data_dir')
+sercom.sqlo.dir_base = conf.get('general', 'data_dir')
 
 # Hasta que nos maten
 while continuar:
 
 # Hasta que nos maten
 while continuar:
@@ -282,9 +336,11 @@ while continuar:
         time.sleep(intervalo)
         continue
     log.info('Nuevo intento a probar (%s)', intento)
         time.sleep(intervalo)
         continue
     log.info('Nuevo intento a probar (%s)', intento)
+    mail = MailIntento(intento)
     # Compila
     # Compila
-    if not compilar(intento):
-        #TODO mandar mail
+    compilar(intento, mail)
+    if not intento.compila:
+        mail.send('NO COMPILA')
         continue
     # Ejecución de casos de prueba
     intento.inicioPruebas = datetime.datetime.now()
         continue
     # Ejecución de casos de prueba
     intento.inicioPruebas = datetime.datetime.now()
@@ -293,17 +349,17 @@ while continuar:
         # Preparo chroot
         preparar(intento)
         # Pruebo y agrego prueba a la lista
         # Preparo chroot
         preparar(intento)
         # Pruebo y agrego prueba a la lista
-        pruebas.append(probar(intento, caso_de_prueba))
+        prueba = probar(intento, caso_de_prueba, mail)
+        mail.body += 'Prueba %s: %s (%s)\n' % (prueba.casoDePrueba.nombre, prueba.pasada, prueba.observaciones)
+        pruebas.append(prueba)
         # Limpio chroot
         limpiar(intento)
         # Limpio chroot
         limpiar(intento)
+    #TODO Si es publica, veo si se hizo ok o no y voy creando mail
     intento.finPruebas = datetime.datetime.now()
     intento.finPruebas = datetime.datetime.now()
+    mail.send('NO SEP')
     # Limpio directorio
     log.debug('Borrando ejecutable y código objeto (*.o)')
     os.remove(os.path.join(intento.path, 'tp'))
     [os.remove(obj) for obj in glob.glob(os.path.join(intento.path, '*.o'))]
     # Limpio directorio
     log.debug('Borrando ejecutable y código objeto (*.o)')
     os.remove(os.path.join(intento.path, 'tp'))
     [os.remove(obj) for obj in glob.glob(os.path.join(intento.path, '*.o'))]
-    #TODO Armar mail de respuesta al alumno
-    for prueba in pruebas:
-        #TODO Si es publica, veo si se hizo ok o no y voy creando mail
-        pass
-    time.sleep(intervalo)
+    # time.sleep(intervalo) #XXX Puede servir para enlentecer el server