Beispiel #1
0
class RuntimeParam(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    env_id = db.Column(db.Integer,
                       db.ForeignKey("runtime_env.id"),
                       nullable=False)
    env = db.relationship("RuntimeEnv", back_populates="params", uselist=False)
    key = db.Column(db.String(100))
    value = db.Column(db.Text)
Beispiel #2
0
class Teacher(db.Model):
    '''Model for the teachers table.'''

    __tablename__ = 'teachers'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)

    def __repr__(self):
        return '<Teacher {}>'.format(self.name)
Beispiel #3
0
class Class(db.Model):
    '''Model for the classes table.'''

    __tablename__ = 'classes'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    teacher_id = db.Column(db.Integer,
                           db.ForeignKey('teachers.id'),
                           nullable=True)

    teacher = db.relationship(Teacher, backref='classes')

    def __repr__(self):
        return '<Class {}>'.format(self.name)
Beispiel #4
0
class BenchmarkSuite(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    created = db.Column(db.DateTime, default=datetime.utcnow)
    author = db.Column(db.String(50))
    env = db.relationship("RuntimeEnv", back_populates="suite", uselist=False)
    tasks = db.relationship("BenchmarkTask",
                            back_populates="suite",
                            lazy=False,
                            order_by="asc(BenchmarkTask.id)")
    description = db.Column(db.Text)

    def completedTaskCount(self):
        return sum(x.state in [TaskState.evaluated, TaskState.cancelled]
                   for x in self.tasks)

    def assignedTaskCount(self):
        return sum(x.state == TaskState.assigned for x in self.tasks)
Beispiel #5
0
class Feedback(db.Model):
    '''Model for the feedbacks table.'''

    __tablename__ = 'feedbacks'

    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer,
                           db.ForeignKey('users.id'),
                           nullable=False)
    class_id = db.Column(db.Integer,
                         db.ForeignKey('classes.id'),
                         nullable=False)
    content = db.Column(db.Text, nullable=False)
    is_anonymous = db.Column(db.Boolean, default=False)

    student = db.relationship(User, backref='feedbacks')
    class_ = db.relationship(Class, backref='feedbacks')

    def __repr__(self):
        return '<Feedback #{}>'.format(self.id)
Beispiel #6
0
class User(db.Model, UserMixin):
    '''Model for the users table.'''

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    school_id = db.Column(db.String(128), nullable=False, unique=True)
    name = db.Column(db.String(128), nullable=False)
    password = db.Column(db.String(128), nullable=False)
    is_teacher = db.Column(db.Boolean, nullable=False)
    teacher_id = db.Column(db.Integer,
                           db.ForeignKey('teachers.id'),
                           nullable=True)

    teacher = db.relationship(Teacher, backref='users')

    def __repr__(self):
        return '<User {}>'.format(self.name)

    def authenticate(self, password):
        '''Checks if provided password matches stored password.'''
        return check_password_hash(self.password, password)

    @staticmethod
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(user_id)
Beispiel #7
0
class RuntimeEnv(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    suite_id = db.Column(db.Integer,
                         db.ForeignKey("benchmark_suite.id"),
                         nullable=False)
    suite = db.relationship("BenchmarkSuite",
                            back_populates="env",
                            uselist=False)
    dockerfile = db.Column(db.Text)
    params = db.relationship("RuntimeParam",
                             back_populates="env",
                             lazy="joined")
    cpuLimit = db.Column(db.Integer)
    memoryLimit = db.Column(db.BigInteger)
    cpuTimeLimit = db.Column(db.Integer)
    wallClockTimeLimit = db.Column(db.Integer)
Beispiel #8
0
class BenchmarkTask(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    suite_id = db.Column(db.Integer,
                         db.ForeignKey("benchmark_suite.id"),
                         nullable=False)
    suite = db.relationship("BenchmarkSuite",
                            back_populates="tasks",
                            uselist=False)

    command = db.Column(db.Text)
    state = db.Column(db.Enum(TaskState), default=TaskState.created)
    assignedAt = db.Column(db.DateTime, default=None)
    updatedAt = db.Column(db.DateTime, default=None)
    assignee = db.Column(db.String(100), default=None)

    # Exit code of the benchmarking command
    exitcode = db.Column(db.Integer, default=None)
    # Combination of stdout & stderr from the build phase
    buildOutput = db.deferred(db.Column(db.Text, default=None))
    # Combination of stdout & stderr
    output = db.deferred(db.Column(db.Text, default=None))
    # Statistics collected by the runner
    stats = db.Column(db.JSON, default=None)
    # The JSON object produced by the evaluation task
    result = db.Column(db.JSON, default=None)

    @staticmethod
    def fetchNew(availableCores, availableMemory):
        """
        Fetch and reserve an unfinished task that fits inside the given limits.
        """
        # TBA extend the query by tasks that are assigned, but haven't been
        # updated in a long time
        baseQuery = (BenchmarkTask.query.join(BenchmarkTask.suite).join(
            BenchmarkSuite.env).filter(
                RuntimeEnv.cpuLimit <= availableCores,
                RuntimeEnv.memoryLimit <= availableMemory))
        task = (baseQuery.filter(
            BenchmarkTask.state == TaskState.pending).order_by(
                BenchmarkTask.id).limit(1).first())
        if task:
            return task
        # Fetch tasks that are assigned, but haven't been updated for more than
        # 5 minutes
        t = datetime.utcnow() - timedelta(minutes=5)
        task = (baseQuery.filter(
            BenchmarkTask.state == TaskState.assigned).filter(
                BenchmarkTask.updatedAt <= t).order_by(
                    BenchmarkTask.id).limit(1).first())
        return task

    def acquire(self, assignee):
        """
        Acquire the task to the assignee
        """
        self.state = TaskState.assigned
        self.assignee = assignee
        t = datetime.utcnow()
        self.assignedAt = t
        self.updatedAt = t

    def abandon(self):
        """
        Abandon the task without successfully evaluating it.
        """
        self.state = TaskState.pending
        self.assignedAt = None
        self.updatedAt = None
        self.assignee = None

    def buildPoke(self, output):
        """
        Poke the task - notify the database that the task's runtime environment
        is still being build, update its output.
        """
        self.updatedAt = datetime.utcnow()
        self.buildOutput = output

    def poke(self, output):
        """
        Poke the task - notify the database that the task is still being
        evaluated, update its output.
        """
        self.updatedAt = datetime.utcnow()
        self.output = output

    def finish(self, exitcode, output, stats, result):
        """
        Sucessfully finish evaluation of the task
        """
        self.state = TaskState.evaluated
        self.exitcode = exitcode
        self.output = output
        self.stats = stats
        self.result = result