def test_parse_parameters(self): from edacc.utils import parse_parameters params = parse_parameters("-p1 5 -p2 -p3 4.0 -p5 abc -p6 2.0") assert ("-p1", "-p1", "5", False, 0) in params assert ("-p2", "-p2", "", True, 2) in params assert ("-p3", "-p3", "4.0", False, 3) in params assert ("-p5", "-p5", "abc", False, 5) in params assert ("-p6", "-p6", "2.0", False, 7) in params params = parse_parameters("-p1 1.0 -i INSTANCE SEED") assert ("-p1", "-p1", "1.0", False, 0) in params assert ("instance", "-i", "", False, 2) in params assert ("seed", "", "", False, 4) in params
def submit_solver(database, id=None): """ Form to submit solvers to a database """ db = models.get_database(database) or abort(404) # Disallow submissions of new solvers in phase 4 if db.competition_phase() == 4 and id is None: abort(401) if id is not None: solver = db.session.query(db.Solver).get(id) or abort(404) if solver.user.idUser != g.User.idUser: abort(401) if db.competition_phase() == 4 and solver.competition_frozen: flash( 'This solver was found to be compatible with our execution environment, i.e. has no crashed test runs or test runs with unknown result, and can not be updated anymore. Please contact the organizers if there\'s a reason to submit a new version.') return redirect(url_for('accounts.list_solvers', database=database, user_id=g.User.idUser)) solver_binary = solver.binaries[0] if solver.binaries else None form = forms.SolverForm(request.form, solver) if request.method == 'GET': form.parameters.data = utils.parameter_template(solver) form.description_pdf.data = '' form.binary.data = '' form.code.data = '' if solver_binary: form.run_command.data = solver_binary.runCommand form.run_path.data = solver_binary.runPath else: form = forms.SolverForm() form.competition_categories.query = db.session.query(db.CompetitionCategory).all() error = None if form.validate_on_submit(): valid = True # assume valid, try to falsify with the following checks name = form.name.data description = form.description.data version = form.version.data authors = form.authors.data parameters = form.parameters.data run_path = form.run_path.data if id is None and db.session.query(db.Solver) \ .filter_by(name=name, version=version) \ .first() is not None: error = 'Solver with this name and version already exists' valid = False if id is None and not form.code.data and not form.binary.data: error = 'Please provide either a binary or the code (or both).' valid = False bin = None if (id is None or (id is not None and form.binary.data)) and form.binary.data: # if this is a new solver or a resubmission with new binary update binary bin = request.files[form.binary.name].stream.read() hash = hashlib.md5() hash.update(bin) # save the binary in the FS as log store_path = os.path.join(config.UPLOAD_FOLDER, 'solvers', secure_filename(str(g.User.idUser) + '-' + g.User.lastname), 'bin') try: os.makedirs(store_path) except: pass with open(os.path.join(store_path, hash.hexdigest()), 'wb') as f: f.write(bin) if not form.binary.data.filename.endswith('.zip'): tmpfile = StringIO() zip_file = zipfile.ZipFile(tmpfile, 'w', compression=zipfile.ZIP_DEFLATED) zip_file.writestr(form.binary.data.filename, bin) zip_file.close() tmpfile.seek(0) bin = tmpfile.read() run_path = form.binary.data.filename else: if not run_path: error = 'Since your binary is a .zip file, please provide the path of the executable within the archive' valid = False code = None if id is None or (id is not None and form.code.data): code = request.files[form.code.name].stream.read() code_hash = hashlib.md5() code_hash.update(code) # save the code in the FS as log store_path = os.path.join(config.UPLOAD_FOLDER, 'solvers', secure_filename(str(g.User.idUser) + '-' + g.User.lastname), 'code') try: os.makedirs(store_path) except: pass with open(os.path.join(store_path, code_hash.hexdigest()), 'wb') as f: f.write(code) description_pdf = None if id is None or (id is not None and form.description_pdf.data): description_pdf = request.files[form.description_pdf.name].stream.read() if id is None and not description_pdf: valid = False error = "Please provide a description pdf." params = utils.parse_parameters(parameters) if valid: if id is None: solver = db.Solver() if bin: solver_binary = db.SolverBinary() solver_binary.solver = solver else: solver_binary = None else: if solver_binary: for solver_config in solver_binary.solver_configurations: for pi in solver_config.parameter_instances: db.session.delete(pi) db.session.commit() db.session.delete(solver_config) db.session.commit() if not solver_binary and bin: solver_binary = db.SolverBinary() solver_binary.solver = solver solver.name = name solver.description = description solver.authors = authors solver.user = g.User solver.version = version solver.competition_categories = form.competition_categories.data if solver_binary: solver_binary.binaryName = name solver_binary.runPath = run_path solver_binary.version = version solver_binary.runCommand = form.run_command.data if bin: # new or updated binary solver_binary.binaryArchive = bin solver_binary.md5 = hash.hexdigest() if code: # new or updated code solver.code = code if description_pdf: # new or updated description pdf solver.description_pdf = description_pdf db.session.add(solver) if bin: db.session.add(solver_binary) # on resubmissions delete old parameters if id is not None: for p in solver.parameters: db.session.delete(p) db.session.commit() for p in params: param = db.Parameter() param.name = None if p[0] == '' else p[0] param.prefix = None if p[1] == '' else p[1] param.defaultValue = p[2] or '' param.hasValue = not p[3] # p[3] actually means 'is boolean' param.order = int(p[4]) param.space = p[5] param.solver = solver db.session.add(param) try: db.session.commit() if code: msg = Message("[" + db.label + "][Admin] Code submitted", recipients=[config.DEFAULT_MAIL_SENDER]) msg.body = ("The user %s %s just submitted code for the solver with id %d" % ( g.User.firstname, g.User.lastname, solver.idSolver)) mail.send(msg) except Exception as e: print e db.session.rollback() flash("Couldn't save solver to the database. Please contact an administrator for support.") return render('/accounts/submit_solver.html', database=database, error=error, db=db, id=id, form=form) flash( 'Solver submitted successfully. If you provided a binary, test jobs will be generated within the next minute. You will be notified by email once they are computed. Please check the Results page at any time for the computation progress.') return redirect(url_for('accounts.list_solvers', database=database, user_id=g.User.idUser)) return render('/accounts/submit_solver.html', database=database, error=error, db=db, id=id, form=form)
def submit_solver(database, id=None): """ Form to submit solvers to a database """ db = models.get_database(database) or abort(404) # Disallow submissions of new solvers in phase 4 if db.competition_phase() == 4 and id is None: abort(401) if id is not None: solver = db.session.query(db.Solver).get(id) or abort(404) if solver.user.idUser != g.User.idUser: abort(401) if db.competition_phase() == 4 and solver.competition_frozen: flash( 'This solver was found to be compatible with our execution environment, i.e. has no crashed test runs or test runs with unknown result, and can not be updated anymore. Please contact the organizers if there\'s a reason to submit a new version.' ) return redirect( url_for('accounts.list_solvers', database=database, user_id=g.User.idUser)) solver_binary = solver.binaries[0] if solver.binaries else None form = forms.SolverForm(request.form, solver) if request.method == 'GET': form.parameters.data = utils.parameter_template(solver) form.description_pdf.data = '' form.binary.data = '' form.code.data = '' if solver_binary: form.run_command.data = solver_binary.runCommand form.run_path.data = solver_binary.runPath else: form = forms.SolverForm() form.competition_categories.query = db.session.query( db.CompetitionCategory).all() error = None if form.validate_on_submit(): valid = True # assume valid, try to falsify with the following checks name = form.name.data description = form.description.data version = form.version.data authors = form.authors.data parameters = form.parameters.data run_path = form.run_path.data if id is None and db.session.query(db.Solver) \ .filter_by(name=name, version=version) \ .first() is not None: error = 'Solver with this name and version already exists' valid = False if id is None and not form.code.data and not form.binary.data: error = 'Please provide either a binary or the code (or both).' valid = False bin = None if (id is None or (id is not None and form.binary.data)) and form.binary.data: # if this is a new solver or a resubmission with new binary update binary bin = request.files[form.binary.name].stream.read() hash = hashlib.md5() hash.update(bin) # save the binary in the FS as log store_path = os.path.join( config.UPLOAD_FOLDER, 'solvers', secure_filename(str(g.User.idUser) + '-' + g.User.lastname), 'bin') try: os.makedirs(store_path) except: pass with open(os.path.join(store_path, hash.hexdigest()), 'wb') as f: f.write(bin) if not form.binary.data.filename.endswith('.zip'): tmpfile = StringIO() zip_file = zipfile.ZipFile(tmpfile, 'w', compression=zipfile.ZIP_DEFLATED) zip_file.writestr(form.binary.data.filename, bin) zip_file.close() tmpfile.seek(0) bin = tmpfile.read() run_path = form.binary.data.filename else: if not run_path: error = 'Since your binary is a .zip file, please provide the path of the executable within the archive' valid = False code = None if id is None or (id is not None and form.code.data): code = request.files[form.code.name].stream.read() code_hash = hashlib.md5() code_hash.update(code) # save the code in the FS as log store_path = os.path.join( config.UPLOAD_FOLDER, 'solvers', secure_filename(str(g.User.idUser) + '-' + g.User.lastname), 'code') try: os.makedirs(store_path) except: pass with open(os.path.join(store_path, code_hash.hexdigest()), 'wb') as f: f.write(code) description_pdf = None if id is None or (id is not None and form.description_pdf.data): description_pdf = request.files[ form.description_pdf.name].stream.read() if id is None and not description_pdf: valid = False error = "Please provide a description pdf." params = utils.parse_parameters(parameters) if valid: if id is None: solver = db.Solver() if bin: solver_binary = db.SolverBinary() solver_binary.solver = solver else: solver_binary = None else: if solver_binary: for solver_config in solver_binary.solver_configurations: for pi in solver_config.parameter_instances: db.session.delete(pi) db.session.commit() db.session.delete(solver_config) db.session.commit() if not solver_binary and bin: solver_binary = db.SolverBinary() solver_binary.solver = solver solver.name = name solver.description = description solver.authors = authors solver.user = g.User solver.version = version solver.competition_categories = form.competition_categories.data if solver_binary: solver_binary.binaryName = name solver_binary.runPath = run_path solver_binary.version = version solver_binary.runCommand = form.run_command.data if bin: # new or updated binary solver_binary.binaryArchive = bin solver_binary.md5 = hash.hexdigest() if code: # new or updated code solver.code = code if description_pdf: # new or updated description pdf solver.description_pdf = description_pdf db.session.add(solver) if bin: db.session.add(solver_binary) # on resubmissions delete old parameters if id is not None: for p in solver.parameters: db.session.delete(p) db.session.commit() for p in params: param = db.Parameter() param.name = None if p[0] == '' else p[0] param.prefix = None if p[1] == '' else p[1] param.defaultValue = p[2] or '' param.hasValue = not p[3] # p[3] actually means 'is boolean' param.order = int(p[4]) param.space = p[5] param.solver = solver db.session.add(param) try: db.session.commit() if code: msg = Message("[" + db.label + "][Admin] Code submitted", recipients=[config.DEFAULT_MAIL_SENDER]) msg.body = ( "The user %s %s just submitted code for the solver with id %d" % (g.User.firstname, g.User.lastname, solver.idSolver)) mail.send(msg) except Exception as e: print e db.session.rollback() flash( "Couldn't save solver to the database. Please contact an administrator for support." ) return render('/accounts/submit_solver.html', database=database, error=error, db=db, id=id, form=form) flash( 'Solver submitted successfully. If you provided a binary, test jobs will be generated within the next minute. You will be notified by email once they are computed. Please check the Results page at any time for the computation progress.' ) return redirect( url_for('accounts.list_solvers', database=database, user_id=g.User.idUser)) return render('/accounts/submit_solver.html', database=database, error=error, db=db, id=id, form=form)