diff --git a/app/controllers/code_ocean/errors_controller.rb b/app/controllers/code_ocean/errors_controller.rb deleted file mode 100644 index 632c354d..00000000 --- a/app/controllers/code_ocean/errors_controller.rb +++ /dev/null @@ -1,40 +0,0 @@ -module CodeOcean - class ErrorsController < ApplicationController - before_action :set_execution_environment - - def authorize! - authorize(@error || @errors) - end - private :authorize! - - def create - @error = CodeOcean::Error.new(error_params) - authorize! - respond_to do |format| - format.json do - head (@error.save ? :created : :unprocessable_entity) - end - end - end - - def error_params - params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id) if params[:error].present? - end - private :error_params - - def index - @errors = CodeOcean::Error.for_execution_environment(@execution_environment).grouped_by_message.paginate(page: params[:page]) - authorize! - end - - def set_execution_environment - @execution_environment = ExecutionEnvironment.find(params[:execution_environment_id]) - end - private :set_execution_environment - - def show - @error = CodeOcean::Error.find(params[:id]) - authorize! - end - end -end \ No newline at end of file diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 0bf3ea07..039efa02 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -126,10 +126,6 @@ class SubmissionsController < ApplicationController # server_sent_event.write({stdout: output[:stdout]}, event: 'output') if output[:stdout] # server_sent_event.write({stderr: output[:stderr]}, event: 'output') if output[:stderr] - - # unless output[:stderr].nil? - # store_error(output[:stderr]) - # end # end hijack do |tubesock| @@ -361,11 +357,6 @@ class SubmissionsController < ApplicationController head :ok end - def store_error(stderr) - CodeOcean::Error.create(submission_id: @submission.id, execution_environment_id: @submission.execution_environment.id, message: stderr) - end - private :store_error - def test hijack do |tubesock| Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive? diff --git a/app/models/code_ocean/error.rb b/app/models/code_ocean/error.rb deleted file mode 100644 index 935962cf..00000000 --- a/app/models/code_ocean/error.rb +++ /dev/null @@ -1,19 +0,0 @@ -module CodeOcean - class Error < ApplicationRecord - belongs_to :execution_environment - - scope :for_execution_environment, ->(execution_environment) { where(execution_environment_id: execution_environment.id) } - scope :grouped_by_message, -> { select('MAX(created_at) AS created_at, MAX(id) AS id, message, COUNT(id) AS count').group(:message).order('count DESC') } - - validates :execution_environment_id, presence: true - validates :message, presence: true - - def self.nested_resource? - true - end - - def to_s - id.to_s - end - end -end diff --git a/app/policies/code_ocean/error_policy.rb b/app/policies/code_ocean/error_policy.rb deleted file mode 100644 index 376af8d8..00000000 --- a/app/policies/code_ocean/error_policy.rb +++ /dev/null @@ -1,7 +0,0 @@ -module CodeOcean - class ErrorPolicy < AdminOrAuthorPolicy - def author? - @user == @record.execution_environment.author - end - end -end diff --git a/app/views/code_ocean/errors/index.html.slim b/app/views/code_ocean/errors/index.html.slim deleted file mode 100644 index dbfa2312..00000000 --- a/app/views/code_ocean/errors/index.html.slim +++ /dev/null @@ -1,19 +0,0 @@ -h1 = CodeOcean::Error.model_name.human(count: 2) - -.table-responsive - table.table - thead - tr - th = t('errors.index.count') - th = t('activerecord.attributes.error.message') - th = t('shared.created_at') - th = t('shared.actions') - tbody - - @errors.each do |error| - tr - td = error.count - td = error.message - td = l(error.created_at, format: :short) - td = link_to(t('shared.show'), execution_environment_error_path(params[:execution_environment_id], error)) - -p = render('shared/pagination', collection: @errors) diff --git a/app/views/code_ocean/errors/show.html.slim b/app/views/code_ocean/errors/show.html.slim deleted file mode 100644 index 1bb6623e..00000000 --- a/app/views/code_ocean/errors/show.html.slim +++ /dev/null @@ -1,4 +0,0 @@ -h1 = CodeOcean::Error.model_name.human - -= row(label: 'error.message', value: @error.message) -= row(label: 'shared.created_at', value: l(@error.created_at, format: :short)) diff --git a/app/views/execution_environments/index.html.slim b/app/views/execution_environments/index.html.slim index 62fbd533..a749df7c 100644 --- a/app/views/execution_environments/index.html.slim +++ b/app/views/execution_environments/index.html.slim @@ -11,7 +11,6 @@ h1 = ExecutionEnvironment.model_name.human(count: 2) th = t('activerecord.attributes.execution_environment.network_enabled') th = t('activerecord.attributes.execution_environment.permitted_execution_time') th colspan=5 = t('shared.actions') - th colspan=2 = t('shared.resources') tbody - @execution_environments.each do |execution_environment| tr @@ -26,7 +25,6 @@ h1 = ExecutionEnvironment.model_name.human(count: 2) td = link_to(t('shared.destroy'), execution_environment, data: {confirm: t('shared.confirm_destroy')}, method: :delete) td = link_to(t('.shell'), shell_execution_environment_path(execution_environment)) td = link_to(t('shared.statistics'), statistics_execution_environment_path(execution_environment)) - td = link_to(t('activerecord.models.error.other'), execution_environment_errors_path(execution_environment.id)) = render('shared/pagination', collection: @execution_environments) p = render('shared/new_button', model: ExecutionEnvironment) diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim index 44fc0aec..700a9855 100644 --- a/app/views/exercises/_editor.html.slim +++ b/app/views/exercises/_editor.html.slim @@ -4,7 +4,7 @@ - show_break_interventions = @show_break_interventions || "false" - show_rfc_interventions = @show_rfc_interventions || "false" - hide_rfc_button = @hide_rfc_button || false -#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id data-user-external-id=external_user_external_id data-working-times-url=working_times_exercise_path(@exercise) data-intervention-save-url=intervention_exercise_path(@exercise) data-rfc-interventions=show_rfc_interventions data-break-interventions=show_break_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise) +#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-submissions-url=submissions_path data-user-id=@current_user.id data-user-external-id=external_user_external_id data-working-times-url=working_times_exercise_path(@exercise) data-intervention-save-url=intervention_exercise_path(@exercise) data-rfc-interventions=show_rfc_interventions data-break-interventions=show_break_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise) div id="sidebar" class=(@exercise.hide_file_tree ? 'sidebar-col-collapsed' : 'sidebar-col') = render('editor_file_tree', exercise: @exercise, files: @files) div.editor-col.col.p-0 id='frames' #editor-buttons.btn-group.enforce-bottom-margin diff --git a/config/locales/de.yml b/config/locales/de.yml index ae535eb9..d8085c25 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -7,8 +7,6 @@ de: name: Name oauth_key: OAuth Key oauth_secret: OAuth Secret - error: - message: Nachricht execution_environment: docker_image: Docker-Image exposed_ports: Zugängliche Ports @@ -140,9 +138,6 @@ de: consumer: one: Konsument other: Konsumenten - error: - one: Fehler - other: Fehler error_template: one: Fehlertemplate other: Fehlertemplates @@ -229,10 +224,6 @@ de: consumers: show: link: Konsument - errors: - connection_refused: Verbindung abgelehnt - index: - count: Anzahl execution_environments: form: hints: diff --git a/config/locales/en.yml b/config/locales/en.yml index 8501572f..4c179c08 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -7,8 +7,6 @@ en: name: Name oauth_key: OAuth Key oauth_secret: OAuth Secret - error: - message: Message execution_environment: docker_image: Docker Image exposed_ports: Exposed Ports @@ -140,9 +138,6 @@ en: consumer: one: Consumer other: Consumers - error: - one: Error - other: Errors error_template: one: Error Template other: Error Templates @@ -229,10 +224,6 @@ en: consumers: show: link: Consumer - errors: - connection_refused: Connection refused - index: - count: Count execution_environments: form: hints: diff --git a/config/routes.rb b/config/routes.rb index e5c863fc..200a895d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,8 +62,6 @@ Rails.application.routes.draw do post 'shell', as: :execute_command, action: :execute_command get :statistics end - - resources :errors, only: [:create, :index, :show], controller: 'code_ocean/errors' end post '/import_proforma_xml' => 'exercises#import_proforma_xml' diff --git a/db/migrate/20181129093207_drop_errors.rb b/db/migrate/20181129093207_drop_errors.rb new file mode 100644 index 00000000..fde39f6d --- /dev/null +++ b/db/migrate/20181129093207_drop_errors.rb @@ -0,0 +1,46 @@ +class DropErrors < ActiveRecord::Migration[5.2] + + # define old CodeOcean::Error module so that the migration works + module CodeOcean + class Error < ApplicationRecord + belongs_to :execution_environment + + scope :for_execution_environment, ->(execution_environment) { where(execution_environment_id: execution_environment.id) } + scope :grouped_by_message, -> { select('MAX(created_at) AS created_at, MAX(id) AS id, message, COUNT(id) AS count').group(:message).order('count DESC') } + + validates :execution_environment_id, presence: true + validates :message, presence: true + + def self.nested_resource? + true + end + + def to_s + id.to_s + end + end + end + + + + def change + + puts 'Migrating CodeOcean::Errors to StructuredErrors using RegEx. This might take a (long) while but will return.' + submissions_controller = SubmissionsController.new + + # Iterate only over those Errors containing a message and submission_id + CodeOcean::Error.where.not(message: [nil, ""]).where.not(submission_id: [nil, ""]).each do |error| + raw_output = error.message + submission = Submission.find_by(id: error.submission_id) + + # Validate that we have everything we need: the output, the submission and the execution environment + next if submission.exercise.execution_environment.blank? + + submissions_controller.instance_variable_set(:@raw_output, raw_output) + submissions_controller.instance_variable_set(:@submission, submission) + submissions_controller.extract_errors + end + + drop_table :errors + end +end diff --git a/db/schema.rb b/db/schema.rb index 54d459df..82ec19bf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_11_27_160857) do +ActiveRecord::Schema.define(version: 2018_11_29_093207) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -81,15 +81,6 @@ ActiveRecord::Schema.define(version: 2018_11_27_160857) do t.text "hint" end - create_table "errors", force: :cascade do |t| - t.integer "execution_environment_id" - t.text "message" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "submission_id" - t.index ["submission_id"], name: "index_errors_on_submission_id" - end - create_table "events", force: :cascade do |t| t.string "category" t.string "data" diff --git a/db/seeds/development.rb b/db/seeds/development.rb index 845caeb9..b266a20b 100644 --- a/db/seeds/development.rb +++ b/db/seeds/development.rb @@ -10,9 +10,6 @@ Rails.application.routes.default_url_options = Rails.application.config.action_m # execution environments ExecutionEnvironment.create_factories -# errors -CodeOcean::Error.create_factories - # exercises @exercises = find_factories_by_class(Exercise).map(&:name).map { |factory_name| [factory_name, FactoryBot.create(factory_name)] }.to_h diff --git a/spec/controllers/submissions_controller_spec.rb b/spec/controllers/submissions_controller_spec.rb index 9b2b1e98..6aaf8555 100644 --- a/spec/controllers/submissions_controller_spec.rb +++ b/spec/controllers/submissions_controller_spec.rb @@ -157,21 +157,6 @@ describe SubmissionsController do pending("todo") end - - context 'when an error occurs during execution' do - let(:stderr) { "undefined method `foo' for main:Object (NoMethodError)" } - - before(:each) do - expect_any_instance_of(DockerClient).to receive(:execute_run_command).with(submission, filename).and_yield(:stderr, stderr) - end - - after(:each) { perform_request } - - it 'stores the error' do - pending("no server sent events used right now") - expect(CodeOcean::Error).to receive(:create).with(execution_environment_id: submission.exercise.execution_environment_id, message: stderr) - end - end end describe 'GET #show' do diff --git a/spec/factories/code_ocean/error.rb b/spec/factories/code_ocean/error.rb deleted file mode 100644 index 0bcae320..00000000 --- a/spec/factories/code_ocean/error.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryBot.define do - factory :error, class: CodeOcean::Error do - association :execution_environment, factory: :ruby - message { "exercise.rb:4:in `
': undefined local variable or method `foo' for main:Object (NameError)" } - end -end diff --git a/spec/models/code_ocean/error_spec.rb b/spec/models/code_ocean/error_spec.rb deleted file mode 100644 index aa111b3c..00000000 --- a/spec/models/code_ocean/error_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'rails_helper' - -describe CodeOcean::Error do - let(:error) { described_class.create } - - it 'validates the presence of an execution environment' do - expect(error.errors[:execution_environment_id]).to be_present - end - - it 'validates the presence of a message' do - expect(error.errors[:message]).to be_present - end - - describe '.nested_resource?' do - it 'is true' do - expect(described_class.nested_resource?).to be true - end - end -end diff --git a/spec/policies/code_ocean/error_policy_spec.rb b/spec/policies/code_ocean/error_policy_spec.rb deleted file mode 100644 index 71ff72d5..00000000 --- a/spec/policies/code_ocean/error_policy_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'rails_helper' - -describe CodeOcean::ErrorPolicy do - subject { described_class } - - let(:error) { FactoryBot.build(:error) } - - [:create?, :index?, :new?].each do |action| - permissions(action) do - it 'grants access to admins' do - expect(subject).to permit(FactoryBot.build(:admin), error) - end - - it 'grants access to teachers' do - expect(subject).to permit(FactoryBot.build(:teacher), error) - end - - it 'does not grant access to external users' do - expect(subject).not_to permit(FactoryBot.build(:external_user), error) - end - end - end - - [:destroy?, :edit?, :show?, :update?].each do |action| - permissions(action) do - it 'grants access to admins' do - expect(subject).to permit(FactoryBot.build(:admin), error) - end - - it 'grants access to authors' do - expect(subject).to permit(error.execution_environment.author, error) - end - - it 'does not grant access to all other users' do - [:external_user, :teacher].each do |factory_name| - expect(subject).not_to permit(FactoryBot.build(factory_name), error) - end - end - end - end -end diff --git a/spec/views/exercises/implement.html.slim_spec.rb b/spec/views/exercises/implement.html.slim_spec.rb index 7c5e641a..fe9ab0d0 100644 --- a/spec/views/exercises/implement.html.slim_spec.rb +++ b/spec/views/exercises/implement.html.slim_spec.rb @@ -14,7 +14,6 @@ describe 'exercises/implement.html.slim' do end it 'contains the required editor data attributes' do - expect(rendered).to have_css("#editor[data-errors-url='#{execution_environment_errors_path(exercise.execution_environment)}']") expect(rendered).to have_css("#editor[data-exercise-id='#{exercise.id}']") expect(rendered).to have_css('#editor[data-message-timeout]') expect(rendered).to have_css("#editor[data-submissions-url='#{submissions_path}']")