'sin usar un Makefile (debe ser un solo archivo que se llame tito.c)')
tp = TareaPrueba(nombre='Probar', terminar_si_falla=True,
rechazar_si_falla=True)
-cp = tp.add_comando(1, [], retorno=0, terminar_si_falla=True,
+cp = tp.add_comando(1, retorno=0, terminar_si_falla=True,
rechazar_si_falla=True, descripcion='Prueba normalmente, sin filtros')
# Enunciados
# Casos de prueba
cp1 = e1.add_caso_de_prueba(nombre=u'Sin parámetros', retorno=0,
- descripcion=u'Un caso', comando=[])
+ descripcion=u'Un caso', comando='./tito')
cp2 = e1.add_caso_de_prueba(nombre=u'2 parámetross', retorno=0,
- comando='--test -c "con espacios"')
+ comando='./tito --test -c "con espacios"')
# Ejercicios
ej1 = c.ejercicios[0]
from sqlobject.col import PickleValidator, UnicodeStringValidator
from turbogears import identity
from turbogears.identity import encrypt_password as encryptpw
-from sercom.validators import params_to_list, ParseError
from formencode import Invalid
hub = PackageHub("sercom")
class TupleCol(PickleCol):
baseClass = SOTupleCol
-class ParamsValidator(UnicodeStringValidator):
- def to_python(self, value, state):
- if isinstance(value, basestring) or value is None:
- value = super(ParamsValidator, self).to_python(value, state)
- try:
- value = params_to_list(value)
- except ParseError, e:
- raise Invalid("invalid parameters in the ParamsCol '%s', parse "
- "error: %s" % (self.name, e), value, state)
- elif not isinstance(value, (list, tuple)):
- raise Invalid("expected a tuple, list or valid string in the "
- "ParamsCol '%s', got %s %r instead"
- % (self.name, type(value), value), value, state)
- return value
- def from_python(self, value, state):
- if isinstance(value, (list, tuple)):
- value = ' '.join([repr(p) for p in value])
- elif isinstance(value, basestring) or value is None:
- value = super(ParamsValidator, self).to_python(value, state)
- try:
- params_to_list(value)
- except ParseError, e:
- raise Invalid("invalid parameters in the ParamsCol '%s', parse "
- "error: %s" % (self.name, e), value, state)
- else:
- raise Invalid("expected a tuple, list or valid string in the "
- "ParamsCol '%s', got %s %r instead"
- % (self.name, type(value), value), value, state)
- return value
-
-class SOParamsCol(SOUnicodeCol):
- def createValidators(self):
- return [ParamsValidator(db_encoding=self.dbEncoding, name=self.name)]
-
-class ParamsCol(UnicodeCol):
- baseClass = SOParamsCol
-
#}}}
#{{{ Clases
# Joins
comandos = MultipleJoin('ComandoPrueba', joinColumn='tarea_id')
- def add_comando(self, orden, comando, **kw):
- return ComandoPrueba(tarea=self, orden=orden, comando=comando, **kw)
+ 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()
RET_ANY = None
RET_FAIL = -1
# Campos
- comando = ParamsCol(length=255, notNone=True)
+ comando = UnicodeCol(length=255, notNone=True)
descripcion = UnicodeCol(length=255, default=None)
retorno = IntCol(default=None) # None es que no importa
max_tiempo_cpu = IntCol(default=None) # En segundos
from docutils.core import publish_parts
from sercom.subcontrollers import validate as val
from sercom.model import CasoDePrueba, Enunciado
-from sercom.validators import ParamsValidator
#}}}
#{{{ Configuración
validator=V.UnicodeString(not_empty=False, max=255,
strip=True))
comando = W.TextField(label=_(u'Comando'),
- validator=ParamsValidator(not_empty=False, strip=True))
+ validator=V.UnicodeString(not_empty=False, strip=True))
retorno = W.TextField(label=_(u'Código de retorno'),
validator=V.Int(not_empty=False, strip=True))
- tiempo_cpu = W.TextField(label=_(u'Tiempo de CPU'),
+ max_tiempo_cpu = W.TextField(label=_(u'Máximo tiempo de CPU'),
validator=V.Number(not_empty=False, strip=True))
fields = Fields()
javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('form_nombre');")]
#{{{ Controlador
-def params2str(params):
- return ' '.join([repr(p)[1:] for p in params])
-
class CasoDePruebaController(controllers.Controller, identity.SecureResource):
"""Basic model admin interface"""
require = identity.has_permission('admin')
r = cls.select()
else:
r = cls.selectBy(enunciadoID=enunciado)
- return dict(records=r, name=name, namepl=namepl, parcial=enunciado,
- params2str=params2str)
+ return dict(records=r, name=name, namepl=namepl, parcial=enunciado)
@expose(template='kid:%s.templates.new' % __name__)
def new(self, **kw):
def edit(self, id, **kw):
"""Edit record in model"""
r = validate_get(id)
- return dict(name=name, namepl=namepl, record=r, form=form,
- params2str=params2str)
+ return dict(name=name, namepl=namepl, record=r, form=form)
@validate(form=form)
@error_handler(edit)
r.desc = ''
else:
r.desc = publish_parts(r.descripcion, writer_name='html')['html_body']
- return dict(name=name, namepl=namepl, record=r, params2str=params2str)
+ return dict(name=name, namepl=namepl, record=r)
@expose()
def delete(self, id):
<th>Descripción</th>
<th>Parámetros</th>
<th title="Código de retorno">RET</th>
- <th title="Tiempo de CPU">CPU</th>
+ <th title="Máximo tiempo de CPU">CPU</th>
<th>Operaciones</th>
</tr>
<tr py:for="record in records">
href="${tg.url('/enunciado/show/%d' % record.enunciado.id)}"><span
py:replace="tg.summarize(record.enunciado.shortrepr(), 30)">enunciado</span></a></td>
<td><span py:replace="tg.summarize(record.descripcion, 30)">descripción</span></td>
- <td><span py:if="record.comando" py:replace="tg.summarize(params2str(record.comando), 30)">comando --con-parámetros</span></td>
+ <td><span py:if="record.comando" py:replace="tg.summarize(record.comando, 30)">comando --con-parámetros</span></td>
<td><span py:replace="record.retorno">retorno</span></td>
- <td><span py:replace="record.tiempo_cpu">tiempo de cpu</span></td>
+ <td><span py:replace="record.max_tiempo_cpu">máx tiempo de cpu</span></td>
<td><a href="${tg.url('/caso_de_prueba/edit/%d' % record.id)}">Editar</a>
<a href="${tg.url('/caso_de_prueba/delete/%d' % record.id)}" onclick="if (confirm('${_(u'Estás seguro? Yo creo que no...')}')) { var f = document.createElement('form'); this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit(); };return false;">Eliminar</a></td>
</tr>
<tr>
<th>Parámetros:</th>
<td>
- <span py:if="record.comando" py:replace="params2str(record.comando)">comando --con-parámetros</span>:
+ <span py:if="record.comando" py:replace="record.comando">comando --con-parámetros</span>:
</td>
</tr>
<tr>
<td><span py:replace="record.retorno">retorno</span></td>
</tr>
<tr>
- <th>Tiempo de CPU:</th>
- <td><span py:replace="record.tiempo_cpu">tiempo_cpu</span></td>
+ <th>Máximo tiempo de CPU:</th>
+ <td><span py:replace="record.max_tiempo_cpu">max_tiempo_cpu</span></td>
</tr>
</table>
unzip(self.archivos_entrada, path) # TODO try/except
comando_ejecutado = entrega.add_comando_ejecutado(self)
# Abro archivos para fds básicos (FIXME)
- options = dict(close_fds=True, stdin=None, stdout=None, stderr=None,
- preexec_fn=SecureProcess(self, 'var/chroot_pepe', '/home/sercom/build'))
- log.debug(_(u'Ejecutando como root: %s'), ' '.join(self.comando))
+ options = dict(
+ close_fds=True,
+ stdin=None,
+ stdout=None,
+ stderr=None,
+ shell=True,
+ preexec_fn=SecureProcess(self, 'var/chroot_pepe', '/home/sercom/build')
+ )
+ log.debug(_(u'Ejecutando como root: %s'), self.comando)
os.seteuid(0) # Dios! (para chroot)
os.setegid(0)
try:
+++ /dev/null
-# vim: set et sw=4 sts=4 encoding=utf-8 :
-
-from turbogears.validators import *
-
-class ParseError(ValueError): pass
-
-def params_to_list(params):
- r"""Parsea un string de forma similar al bash, separando por espacios y
- teniendo en cuenta comillas simples y dobles para agrupar. Para poner
- comillas se puede usar el \ como caracter de escape (\' y \") y también
- interpreta \n y \t. Devuelve una lista con los parámetros encontrados.
- >>> param2seq('--prueba')
- ['--prueba']
- >>> params_to_list('--prueba larga "con espacios"')
- ['--prueba', 'larga', 'con espacios']
- >>> params_to_list(u'''"con enter\\nentre 'comillas \\"dobles\\"'" --unicode''')
- [u'con enter\nentre \'comillas "dobles"\'', u'--unicode']
- >>> params_to_list('"archivo\\tseparado\\tpor\\ttabs" -h')
- ['archivo\tseparado\tpor\ttabs', '-h']
- """
- # Constantes
- SEP, TOKEN, DQUOTE, SQUOTE = ' ', None, '"', "'"
- seq = []
- buff = ''
- escape = False
- state = SEP
- if not params: return seq
- for c in params:
- # Es un caracter escapado
- if escape:
- if c == 'n':
- buff += '\n'
- elif c == 't':
- buff += '\t'
- else:
- buff += c
- escape = False
- continue
- # Es una secuencia de escape
- if c == '\\':
- escape = True
- continue
- # Si está buscando espacios
- if state == SEP:
- if c == SEP:
- continue
- else:
- state = TOKEN # Encontró
- if state == TOKEN:
- if c == DQUOTE:
- state = DQUOTE
- continue
- if c == SQUOTE:
- state = SQUOTE
- continue
- if c == SEP:
- state = SEP
- seq.append(buff)
- buff = ''
- continue
- buff += c
- continue
- if state == DQUOTE:
- if c == DQUOTE:
- state = TOKEN
- continue
- buff += c
- continue
- if state == SQUOTE:
- if c == SQUOTE:
- state = TOKEN
- continue
- buff += c
- continue
- raise ParseError, 'Invalid syntax'
- if state == DQUOTE or state == SQUOTE:
- raise ParseError, 'Missing closing quote %s' % state
- if buff:
- seq.append(buff)
- return seq
-
-class ParamsValidator(UnicodeString):
- def validate_python(self, value, state):
- try:
- params_to_list(value)
- except ParseError, e:
- raise Invalid(str(e), value, state)
-