+#}}}
+
+class TareaPrueba(Tarea): #{{{
+ _inheritable = False
+ # Joins
+ comandos = MultipleJoin('ComandoPrueba', joinColumn='tarea_id')
+
+ def add_comando(self, orden, **kw):
+ return ComandoPrueba(tarea=self, orden=orden, comando='', **kw)
+
+ def remove_comando(self, orden):
+ ComandoPrueba.pk.get(self.id, orden).destroySelf()
+
+ def __repr__(self):
+ return 'TareaPrueba(id=%s, nombre=%s, descripcion=%s)' \
+ % (self.id, self.nombre, self.descripcion)
+#}}}
+
+class Comando(InheritableSQLObject): #{{{
+ # Tipos de retorno especiales
+ RET_ANY = None
+ RET_FAIL = -256
+ # Archivos especiales
+ STDIN = '__stdin__'
+ STDOUT = '__stdout__'
+ STDERR = '__stderr__'
+ STDOUTERR = '__stdouterr__'
+ # Campos
+ comando = UnicodeCol(length=255, notNone=True)
+ descripcion = UnicodeCol(length=255, default=None)
+ retorno = IntCol(default=None) # Ver RET_XXX y si es negativo
+ # se espera una señal
+ max_tiempo_cpu = IntCol(default=None) # En segundos
+ max_memoria = IntCol(default=None) # En MB
+ max_tam_archivo = IntCol(default=None) # En MB
+ max_cant_archivos = IntCol(default=None)
+ max_cant_procesos = IntCol(default=None)
+ max_locks_memoria = IntCol(default=None)
+ terminar_si_falla = BoolCol(notNone=True, default=True)
+ rechazar_si_falla = BoolCol(notNone=True, default=True)
+ publico = BoolCol(notNone=True, default=True)
+ archivos_entrada = BLOBCol(default=None) # ZIP con archivos de entrada
+ # __stdin__ es caso especial
+ # Si un caso de prueba tiene
+ # comandos que tiene algún
+ # archivo de entrada (incluyendo
+ # stdin) con los propios, se usa
+ # el archivo del caso de prueba,
+ # no del comando.
+ archivos_a_comparar = BLOBCol(default=None) # ZIP con archivos de salida
+ # __stdout__, __stderr__ y
+ # __stdouterr__ (ambos juntos)
+ # son casos especiales
+ # Si un caso de prueba tiene
+ # comandos que tiene algún
+ # archivo a comparar (incluyendo
+ # stdout/err) con los propios,
+ # se compara contra el archivo
+ # del caso de prueba, no del
+ # comando.
+ archivos_a_guardar = TupleCol(notNone=True, default=()) # TODO FrozenSetCol
+ # __stdout__, __stderr__ y
+ # __stdouterr__ (ambos juntos)
+ # son casos especiales
+ activo = BoolCol(notNone=True, default=True)
+
+ def __repr__(self, clave='', mas=''):
+ return ('%s(%s comando=%s, descripcion=%s, retorno=%s, '
+ 'max_tiempo_cpu=%s, max_memoria=%s, max_tam_archivo=%s, '
+ 'max_cant_archivos=%s, max_cant_procesos=%s, max_locks_memoria=%s, '
+ 'terminar_si_falla=%s, rechazar_si_falla=%s%s)'
+ % (self.__class__.__name__, clave, self.comando,
+ self.descripcion, self.retorno, self.max_tiempo_cpu,
+ self.max_memoria, self.max_tam_archivo,
+ self.max_cant_archivos, self.max_cant_procesos,
+ self.max_locks_memoria, self.terminar_si_falla,
+ self.rechazar_si_falla, mas))