From d5121cab07b9f63922db23c296a66c32bf2ba338 Mon Sep 17 00:00:00 2001
From: Ralf Teusner
Date: Wed, 13 Sep 2017 13:28:31 +0200
Subject: [PATCH 01/15] add cause to testruns trigger run and assess on
request_for_comment
---
.../editor/participantsupport.js.erb | 4 +--
.../javascripts/editor/submissions.js.erb | 28 ++++++++++---------
app/assets/stylesheets/statistics.css.scss | 8 ++++++
.../concerns/submission_scoring.rb | 2 +-
.../request_for_comments_controller.rb | 5 ++++
app/controllers/submissions_controller.rb | 2 +-
.../external_users/statistics.html.slim | 4 ++-
.../20170830083601_add_cause_to_testruns.rb | 18 ++++++++++++
8 files changed, 53 insertions(+), 18 deletions(-)
create mode 100644 db/migrate/20170830083601_add_cause_to_testruns.rb
diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb
index 91e9f0d1..63787f4a 100644
--- a/app/assets/javascripts/editor/participantsupport.js.erb
+++ b/app/assets/javascripts/editor/participantsupport.js.erb
@@ -59,8 +59,6 @@ CodeOceanEditorCodePilot = {
}
};
-//Request for comments does currently not work on staging platform (no relative root_url used here).
-//To fix this rely on ruby routes
CodeOceanEditorRequestForComments = {
requestComments: function () {
var user_id = $('#editor').data('user-id');
@@ -83,6 +81,8 @@ CodeOceanEditorRequestForComments = {
}).done(function () {
this.hideSpinner();
$.flash.success({text: $('#askForCommentsButton').data('message-success')});
+ // trigger a run
+ this.runSubmission.call(this, submission);
}.bind(this)).error(this.ajaxError.bind(this));
};
diff --git a/app/assets/javascripts/editor/submissions.js.erb b/app/assets/javascripts/editor/submissions.js.erb
index 20d8cd10..21250f7e 100644
--- a/app/assets/javascripts/editor/submissions.js.erb
+++ b/app/assets/javascripts/editor/submissions.js.erb
@@ -142,19 +142,21 @@ CodeOceanEditorSubmissions = {
* Execution-Logic
*/
runCode: function(event) {
- event.preventDefault();
- if ($('#run').is(':visible')) {
- this.createSubmission('#run', null, function(response) {
- //Run part starts here
- $('#stop').data('url', response.stop_url);
- this.running = true;
- this.showSpinner($('#run'));
- $('#score_div').addClass('hidden');
- this.toggleButtonStates();
- var url = response.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
- this.initializeSocketForRunning(url);
- }.bind(this));
- }
+ event.preventDefault();
+ if ($('#run').is(':visible')) {
+ this.createSubmission('#run', null, this.runSubmission.bind(this));
+ }
+ },
+
+ runSubmission: function (submission) {
+ //Run part starts here
+ $('#stop').data('url', submission.stop_url);
+ this.running = true;
+ this.showSpinner($('#run'));
+ $('#score_div').addClass('hidden');
+ this.toggleButtonStates();
+ var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
+ this.initializeSocketForRunning(url);
},
saveCode: function(event) {
diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss
index f656cd9a..a5ea4430 100644
--- a/app/assets/stylesheets/statistics.css.scss
+++ b/app/assets/stylesheets/statistics.css.scss
@@ -42,6 +42,14 @@ div.positive-result {
box-shadow: 0px 0px 11px 1px rgba(44,222,0,1);
}
+div.unknown-result {
+ border-radius: 50%;
+ background-color: #ffca00;
+ -webkit-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ -moz-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+}
+
div.negative-result {
border-radius: 50%;
background-color: #ff2600;
diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb
index 16f1f061..41f9ff26 100644
--- a/app/controllers/concerns/submission_scoring.rb
+++ b/app/controllers/concerns/submission_scoring.rb
@@ -9,7 +9,7 @@ module SubmissionScoring
assessment = assessor.assess(output)
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
testrun_output = passed ? nil : output[:stderr]
- Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save
+ Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save
output.merge!(assessment)
output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)
end
diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb
index fca5c99b..6e587c73 100644
--- a/app/controllers/request_for_comments_controller.rb
+++ b/app/controllers/request_for_comments_controller.rb
@@ -1,4 +1,5 @@
class RequestForCommentsController < ApplicationController
+ include SubmissionScoring
before_action :set_request_for_comment, only: [:show, :edit, :update, :destroy, :mark_as_solved, :set_thank_you_note]
skip_after_action :verify_authorized
@@ -110,6 +111,10 @@ class RequestForCommentsController < ApplicationController
@request_for_comment = RequestForComment.new(request_for_comment_params)
respond_to do |format|
if @request_for_comment.save
+ # create thread here and execute tests. A run is triggered from the frontend and does not need to be handled here.
+ Thread.new do
+ score_submission(@request_for_comment.submission)
+ end
format.json { render :show, status: :created, location: @request_for_comment }
else
format.html { render :new }
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index 9b37fde0..52baefe1 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -262,7 +262,7 @@ class SubmissionsController < ApplicationController
def save_run_output
if !@message_buffer.blank?
@message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars
- Testrun.create(file: @file, submission: @submission, output: @message_buffer)
+ Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer)
end
end
diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim
index 313a19b0..8b5c3b30 100644
--- a/app/views/exercises/external_users/statistics.html.slim
+++ b/app/views/exercises/external_users/statistics.html.slim
@@ -54,8 +54,10 @@ h1 = "#{@exercise} (external user #{@external_user})"
-submission_or_intervention.testruns.each do |run|
- if run.passed
.unit-test-result.positive-result title=run.output
- - else
+ - elsif run.failed
.unit-test-result.negative-result title=run.output
+ - else
+ .unit-test-result.unknown-result title=run.output
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
-working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
- elsif submission_or_intervention.is_a? UserExerciseIntervention
diff --git a/db/migrate/20170830083601_add_cause_to_testruns.rb b/db/migrate/20170830083601_add_cause_to_testruns.rb
new file mode 100644
index 00000000..f9a859c4
--- /dev/null
+++ b/db/migrate/20170830083601_add_cause_to_testruns.rb
@@ -0,0 +1,18 @@
+class AddCauseToTestruns < ActiveRecord::Migration
+ def up
+ add_column :testruns, :cause, :string
+ Testrun.reset_column_information
+ Testrun.all.each{ |testrun|
+ if(testrun.submission.nil?)
+ say_with_time "#{testrun.id} has no submission" do end
+ else
+ testrun.cause = testrun.submission.cause
+ testrun.save
+ end
+ }
+ end
+
+ def down
+ remove_column :testruns, :cause
+ end
+end
From ae1e465d1fb08d3f7d51b6500ee95b5afb06e5ec Mon Sep 17 00:00:00 2001
From: Ralf Teusner
Date: Wed, 13 Sep 2017 13:28:31 +0200
Subject: [PATCH 02/15] add cause to testruns trigger run and assess on
request_for_comment
---
.../editor/participantsupport.js.erb | 4 +--
.../javascripts/editor/submissions.js.erb | 28 ++++++++++---------
app/assets/stylesheets/statistics.css.scss | 8 ++++++
.../concerns/submission_scoring.rb | 2 +-
.../request_for_comments_controller.rb | 5 ++++
app/controllers/submissions_controller.rb | 2 +-
.../external_users/statistics.html.slim | 4 ++-
.../20170830083601_add_cause_to_testruns.rb | 18 ++++++++++++
8 files changed, 53 insertions(+), 18 deletions(-)
create mode 100644 db/migrate/20170830083601_add_cause_to_testruns.rb
diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb
index 91e9f0d1..63787f4a 100644
--- a/app/assets/javascripts/editor/participantsupport.js.erb
+++ b/app/assets/javascripts/editor/participantsupport.js.erb
@@ -59,8 +59,6 @@ CodeOceanEditorCodePilot = {
}
};
-//Request for comments does currently not work on staging platform (no relative root_url used here).
-//To fix this rely on ruby routes
CodeOceanEditorRequestForComments = {
requestComments: function () {
var user_id = $('#editor').data('user-id');
@@ -83,6 +81,8 @@ CodeOceanEditorRequestForComments = {
}).done(function () {
this.hideSpinner();
$.flash.success({text: $('#askForCommentsButton').data('message-success')});
+ // trigger a run
+ this.runSubmission.call(this, submission);
}.bind(this)).error(this.ajaxError.bind(this));
};
diff --git a/app/assets/javascripts/editor/submissions.js.erb b/app/assets/javascripts/editor/submissions.js.erb
index 20d8cd10..21250f7e 100644
--- a/app/assets/javascripts/editor/submissions.js.erb
+++ b/app/assets/javascripts/editor/submissions.js.erb
@@ -142,19 +142,21 @@ CodeOceanEditorSubmissions = {
* Execution-Logic
*/
runCode: function(event) {
- event.preventDefault();
- if ($('#run').is(':visible')) {
- this.createSubmission('#run', null, function(response) {
- //Run part starts here
- $('#stop').data('url', response.stop_url);
- this.running = true;
- this.showSpinner($('#run'));
- $('#score_div').addClass('hidden');
- this.toggleButtonStates();
- var url = response.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
- this.initializeSocketForRunning(url);
- }.bind(this));
- }
+ event.preventDefault();
+ if ($('#run').is(':visible')) {
+ this.createSubmission('#run', null, this.runSubmission.bind(this));
+ }
+ },
+
+ runSubmission: function (submission) {
+ //Run part starts here
+ $('#stop').data('url', submission.stop_url);
+ this.running = true;
+ this.showSpinner($('#run'));
+ $('#score_div').addClass('hidden');
+ this.toggleButtonStates();
+ var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
+ this.initializeSocketForRunning(url);
},
saveCode: function(event) {
diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss
index f656cd9a..a5ea4430 100644
--- a/app/assets/stylesheets/statistics.css.scss
+++ b/app/assets/stylesheets/statistics.css.scss
@@ -42,6 +42,14 @@ div.positive-result {
box-shadow: 0px 0px 11px 1px rgba(44,222,0,1);
}
+div.unknown-result {
+ border-radius: 50%;
+ background-color: #ffca00;
+ -webkit-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ -moz-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+}
+
div.negative-result {
border-radius: 50%;
background-color: #ff2600;
diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb
index 16f1f061..41f9ff26 100644
--- a/app/controllers/concerns/submission_scoring.rb
+++ b/app/controllers/concerns/submission_scoring.rb
@@ -9,7 +9,7 @@ module SubmissionScoring
assessment = assessor.assess(output)
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
testrun_output = passed ? nil : output[:stderr]
- Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save
+ Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save
output.merge!(assessment)
output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)
end
diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb
index 20d77bea..6057f647 100644
--- a/app/controllers/request_for_comments_controller.rb
+++ b/app/controllers/request_for_comments_controller.rb
@@ -1,4 +1,5 @@
class RequestForCommentsController < ApplicationController
+ include SubmissionScoring
before_action :set_request_for_comment, only: [:show, :edit, :update, :destroy, :mark_as_solved, :set_thank_you_note]
skip_after_action :verify_authorized
@@ -110,6 +111,10 @@ class RequestForCommentsController < ApplicationController
@request_for_comment = RequestForComment.new(request_for_comment_params)
respond_to do |format|
if @request_for_comment.save
+ # create thread here and execute tests. A run is triggered from the frontend and does not need to be handled here.
+ Thread.new do
+ score_submission(@request_for_comment.submission)
+ end
format.json { render :show, status: :created, location: @request_for_comment }
else
format.html { render :new }
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index 9b37fde0..52baefe1 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -262,7 +262,7 @@ class SubmissionsController < ApplicationController
def save_run_output
if !@message_buffer.blank?
@message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars
- Testrun.create(file: @file, submission: @submission, output: @message_buffer)
+ Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer)
end
end
diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim
index 313a19b0..8b5c3b30 100644
--- a/app/views/exercises/external_users/statistics.html.slim
+++ b/app/views/exercises/external_users/statistics.html.slim
@@ -54,8 +54,10 @@ h1 = "#{@exercise} (external user #{@external_user})"
-submission_or_intervention.testruns.each do |run|
- if run.passed
.unit-test-result.positive-result title=run.output
- - else
+ - elsif run.failed
.unit-test-result.negative-result title=run.output
+ - else
+ .unit-test-result.unknown-result title=run.output
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
-working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
- elsif submission_or_intervention.is_a? UserExerciseIntervention
diff --git a/db/migrate/20170830083601_add_cause_to_testruns.rb b/db/migrate/20170830083601_add_cause_to_testruns.rb
new file mode 100644
index 00000000..f9a859c4
--- /dev/null
+++ b/db/migrate/20170830083601_add_cause_to_testruns.rb
@@ -0,0 +1,18 @@
+class AddCauseToTestruns < ActiveRecord::Migration
+ def up
+ add_column :testruns, :cause, :string
+ Testrun.reset_column_information
+ Testrun.all.each{ |testrun|
+ if(testrun.submission.nil?)
+ say_with_time "#{testrun.id} has no submission" do end
+ else
+ testrun.cause = testrun.submission.cause
+ testrun.save
+ end
+ }
+ end
+
+ def down
+ remove_column :testruns, :cause
+ end
+end
From 44f70ea3dabc60be0709ce4ba88e85d7803debad Mon Sep 17 00:00:00 2001
From: Ralf Teusner
Date: Wed, 20 Sep 2017 13:10:37 +0200
Subject: [PATCH 03/15] save run outputs with cause requestComments with more
content (5000 chars instead of 500). Always save full JSON content.
---
app/controllers/submissions_controller.rb | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index 52baefe1..4dfa182c 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -13,8 +13,12 @@ class SubmissionsController < ApplicationController
before_action :set_mime_type, only: [:download_file, :render_file]
skip_before_action :verify_authenticity_token, only: [:download_file, :render_file]
- def max_message_buffer_size
- 500
+ def max_run_output_buffer_size
+ if(@submission.cause == 'requestComments')
+ 5000
+ else
+ 500
+ end
end
def authorize!
@@ -196,7 +200,7 @@ class SubmissionsController < ApplicationController
end
def handle_message(message, tubesock, container)
- @message_buffer ||= ""
+ @run_output ||= ""
# Handle special commands first
if (/^#exit/.match(message))
# Just call exit_container on the docker_client.
@@ -205,19 +209,19 @@ class SubmissionsController < ApplicationController
# kill_socket is called in the "on close handler" of the websocket to the container
@docker_client.exit_container(container)
elsif /^#timeout/.match(message)
- @message_buffer = 'timeout: ' + @message_buffer # add information that this run timed out to the buffer
+ @run_output = 'timeout: ' + @run_output # add information that this run timed out to the buffer
else
# Filter out information about run_command, test_command, user or working directory
run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename])
test_command = @submission.execution_environment.test_command % command_substitutions(params[:filename])
if !(/root|workspace|#{run_command}|#{test_command}/.match(message))
- @message_buffer += message if @message_buffer.size <= max_message_buffer_size
parse_message(message, 'stdout', tubesock)
end
end
end
def parse_message(message, output_stream, socket, recursive = true)
+ parsed = '';
begin
parsed = JSON.parse(message)
if(parsed.class == Hash && parsed.key?('cmd'))
@@ -256,13 +260,16 @@ class SubmissionsController < ApplicationController
socket.send_data JSON.dump(parsed)
Rails.logger.info('parse_message sent: ' + JSON.dump(parsed))
end
+ ensure
+ # save the data that was send to the run_output if there is enough space left. this will be persisted as a testrun with cause "run"
+ @run_output += JSON.dump(parsed) if @run_output.size <= max_run_output_buffer_size
end
end
def save_run_output
- if !@message_buffer.blank?
- @message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars
- Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer)
+ if !@run_output.blank?
+ @run_output = @run_output[(0..max_run_output_buffer_size-1)] # trim the string to max_message_buffer_size chars
+ Testrun.create(file: @file, cause: 'run', submission: @submission, output: @run_output)
end
end
From 194984a62067883779dcf62ac3d11fc165c4777e Mon Sep 17 00:00:00 2001
From: Ralf Teusner
Date: Wed, 13 Sep 2017 13:28:31 +0200
Subject: [PATCH 04/15] add cause to testruns trigger run and assess on
request_for_comment
---
.../editor/participantsupport.js.erb | 4 +--
.../javascripts/editor/submissions.js.erb | 28 ++++++++++---------
app/assets/stylesheets/statistics.css.scss | 8 ++++++
.../concerns/submission_scoring.rb | 2 +-
.../request_for_comments_controller.rb | 5 ++++
app/controllers/submissions_controller.rb | 2 +-
.../external_users/statistics.html.slim | 4 ++-
.../20170830083601_add_cause_to_testruns.rb | 18 ++++++++++++
8 files changed, 53 insertions(+), 18 deletions(-)
create mode 100644 db/migrate/20170830083601_add_cause_to_testruns.rb
diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb
index 91e9f0d1..63787f4a 100644
--- a/app/assets/javascripts/editor/participantsupport.js.erb
+++ b/app/assets/javascripts/editor/participantsupport.js.erb
@@ -59,8 +59,6 @@ CodeOceanEditorCodePilot = {
}
};
-//Request for comments does currently not work on staging platform (no relative root_url used here).
-//To fix this rely on ruby routes
CodeOceanEditorRequestForComments = {
requestComments: function () {
var user_id = $('#editor').data('user-id');
@@ -83,6 +81,8 @@ CodeOceanEditorRequestForComments = {
}).done(function () {
this.hideSpinner();
$.flash.success({text: $('#askForCommentsButton').data('message-success')});
+ // trigger a run
+ this.runSubmission.call(this, submission);
}.bind(this)).error(this.ajaxError.bind(this));
};
diff --git a/app/assets/javascripts/editor/submissions.js.erb b/app/assets/javascripts/editor/submissions.js.erb
index 20d8cd10..21250f7e 100644
--- a/app/assets/javascripts/editor/submissions.js.erb
+++ b/app/assets/javascripts/editor/submissions.js.erb
@@ -142,19 +142,21 @@ CodeOceanEditorSubmissions = {
* Execution-Logic
*/
runCode: function(event) {
- event.preventDefault();
- if ($('#run').is(':visible')) {
- this.createSubmission('#run', null, function(response) {
- //Run part starts here
- $('#stop').data('url', response.stop_url);
- this.running = true;
- this.showSpinner($('#run'));
- $('#score_div').addClass('hidden');
- this.toggleButtonStates();
- var url = response.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
- this.initializeSocketForRunning(url);
- }.bind(this));
- }
+ event.preventDefault();
+ if ($('#run').is(':visible')) {
+ this.createSubmission('#run', null, this.runSubmission.bind(this));
+ }
+ },
+
+ runSubmission: function (submission) {
+ //Run part starts here
+ $('#stop').data('url', submission.stop_url);
+ this.running = true;
+ this.showSpinner($('#run'));
+ $('#score_div').addClass('hidden');
+ this.toggleButtonStates();
+ var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
+ this.initializeSocketForRunning(url);
},
saveCode: function(event) {
diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss
index f656cd9a..a5ea4430 100644
--- a/app/assets/stylesheets/statistics.css.scss
+++ b/app/assets/stylesheets/statistics.css.scss
@@ -42,6 +42,14 @@ div.positive-result {
box-shadow: 0px 0px 11px 1px rgba(44,222,0,1);
}
+div.unknown-result {
+ border-radius: 50%;
+ background-color: #ffca00;
+ -webkit-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ -moz-box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+ box-shadow: 0px 0px 11px 1px rgb(255, 202, 0);
+}
+
div.negative-result {
border-radius: 50%;
background-color: #ff2600;
diff --git a/app/controllers/concerns/submission_scoring.rb b/app/controllers/concerns/submission_scoring.rb
index 16f1f061..41f9ff26 100644
--- a/app/controllers/concerns/submission_scoring.rb
+++ b/app/controllers/concerns/submission_scoring.rb
@@ -9,7 +9,7 @@ module SubmissionScoring
assessment = assessor.assess(output)
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
testrun_output = passed ? nil : output[:stderr]
- Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save
+ Testrun.new(submission: submission, cause: 'assess', file: file, passed: passed, output: testrun_output).save
output.merge!(assessment)
output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)
end
diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb
index 8ef8f866..4fd19a92 100644
--- a/app/controllers/request_for_comments_controller.rb
+++ b/app/controllers/request_for_comments_controller.rb
@@ -1,4 +1,5 @@
class RequestForCommentsController < ApplicationController
+ include SubmissionScoring
before_action :set_request_for_comment, only: [:show, :edit, :update, :destroy, :mark_as_solved, :set_thank_you_note]
skip_after_action :verify_authorized
@@ -107,6 +108,10 @@ class RequestForCommentsController < ApplicationController
@request_for_comment = RequestForComment.new(request_for_comment_params)
respond_to do |format|
if @request_for_comment.save
+ # create thread here and execute tests. A run is triggered from the frontend and does not need to be handled here.
+ Thread.new do
+ score_submission(@request_for_comment.submission)
+ end
format.json { render :show, status: :created, location: @request_for_comment }
else
format.html { render :new }
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index 9b37fde0..52baefe1 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -262,7 +262,7 @@ class SubmissionsController < ApplicationController
def save_run_output
if !@message_buffer.blank?
@message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars
- Testrun.create(file: @file, submission: @submission, output: @message_buffer)
+ Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer)
end
end
diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim
index 313a19b0..8b5c3b30 100644
--- a/app/views/exercises/external_users/statistics.html.slim
+++ b/app/views/exercises/external_users/statistics.html.slim
@@ -54,8 +54,10 @@ h1 = "#{@exercise} (external user #{@external_user})"
-submission_or_intervention.testruns.each do |run|
- if run.passed
.unit-test-result.positive-result title=run.output
- - else
+ - elsif run.failed
.unit-test-result.negative-result title=run.output
+ - else
+ .unit-test-result.unknown-result title=run.output
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
-working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
- elsif submission_or_intervention.is_a? UserExerciseIntervention
diff --git a/db/migrate/20170830083601_add_cause_to_testruns.rb b/db/migrate/20170830083601_add_cause_to_testruns.rb
new file mode 100644
index 00000000..f9a859c4
--- /dev/null
+++ b/db/migrate/20170830083601_add_cause_to_testruns.rb
@@ -0,0 +1,18 @@
+class AddCauseToTestruns < ActiveRecord::Migration
+ def up
+ add_column :testruns, :cause, :string
+ Testrun.reset_column_information
+ Testrun.all.each{ |testrun|
+ if(testrun.submission.nil?)
+ say_with_time "#{testrun.id} has no submission" do end
+ else
+ testrun.cause = testrun.submission.cause
+ testrun.save
+ end
+ }
+ end
+
+ def down
+ remove_column :testruns, :cause
+ end
+end
From da4d54859c52d2fdc1910694d290c8d38566143a Mon Sep 17 00:00:00 2001
From: Ralf Teusner
Date: Wed, 20 Sep 2017 13:10:37 +0200
Subject: [PATCH 05/15] save run outputs with cause requestComments with more
content (5000 chars instead of 500). Always save full JSON content.
---
app/controllers/submissions_controller.rb | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
index 52baefe1..4dfa182c 100644
--- a/app/controllers/submissions_controller.rb
+++ b/app/controllers/submissions_controller.rb
@@ -13,8 +13,12 @@ class SubmissionsController < ApplicationController
before_action :set_mime_type, only: [:download_file, :render_file]
skip_before_action :verify_authenticity_token, only: [:download_file, :render_file]
- def max_message_buffer_size
- 500
+ def max_run_output_buffer_size
+ if(@submission.cause == 'requestComments')
+ 5000
+ else
+ 500
+ end
end
def authorize!
@@ -196,7 +200,7 @@ class SubmissionsController < ApplicationController
end
def handle_message(message, tubesock, container)
- @message_buffer ||= ""
+ @run_output ||= ""
# Handle special commands first
if (/^#exit/.match(message))
# Just call exit_container on the docker_client.
@@ -205,19 +209,19 @@ class SubmissionsController < ApplicationController
# kill_socket is called in the "on close handler" of the websocket to the container
@docker_client.exit_container(container)
elsif /^#timeout/.match(message)
- @message_buffer = 'timeout: ' + @message_buffer # add information that this run timed out to the buffer
+ @run_output = 'timeout: ' + @run_output # add information that this run timed out to the buffer
else
# Filter out information about run_command, test_command, user or working directory
run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename])
test_command = @submission.execution_environment.test_command % command_substitutions(params[:filename])
if !(/root|workspace|#{run_command}|#{test_command}/.match(message))
- @message_buffer += message if @message_buffer.size <= max_message_buffer_size
parse_message(message, 'stdout', tubesock)
end
end
end
def parse_message(message, output_stream, socket, recursive = true)
+ parsed = '';
begin
parsed = JSON.parse(message)
if(parsed.class == Hash && parsed.key?('cmd'))
@@ -256,13 +260,16 @@ class SubmissionsController < ApplicationController
socket.send_data JSON.dump(parsed)
Rails.logger.info('parse_message sent: ' + JSON.dump(parsed))
end
+ ensure
+ # save the data that was send to the run_output if there is enough space left. this will be persisted as a testrun with cause "run"
+ @run_output += JSON.dump(parsed) if @run_output.size <= max_run_output_buffer_size
end
end
def save_run_output
- if !@message_buffer.blank?
- @message_buffer = @message_buffer[(0..max_message_buffer_size-1)] # trim the string to max_message_buffer_size chars
- Testrun.create(file: @file, cause: 'run', submission: @submission, output: @message_buffer)
+ if !@run_output.blank?
+ @run_output = @run_output[(0..max_run_output_buffer_size-1)] # trim the string to max_message_buffer_size chars
+ Testrun.create(file: @file, cause: 'run', submission: @submission, output: @run_output)
end
end
From 1e71b46960db13db309636be6175e94c2e585215 Mon Sep 17 00:00:00 2001
From: Maximilian Grundke
Date: Thu, 21 Sep 2017 17:20:21 +0200
Subject: [PATCH 06/15] Update schema
---
db/schema.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/db/schema.rb b/db/schema.rb
index e7e0c6d6..988cd447 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -304,6 +304,7 @@ ActiveRecord::Schema.define(version: 20170920145852) do
t.integer "submission_id"
t.datetime "created_at"
t.datetime "updated_at"
+ t.string "cause"
end
create_table "user_exercise_feedbacks", force: :cascade do |t|
From 0e93a0bb2ea0cef27b8a67817cd16e2485d914d6 Mon Sep 17 00:00:00 2001
From: Maximilian Grundke
Date: Thu, 21 Sep 2017 17:36:52 +0200
Subject: [PATCH 07/15] Pull out admin menu
---
.../request_for_comments/_admin_menu.html.slim | 9 +++++++++
app/views/request_for_comments/show.html.erb | 17 +++--------------
2 files changed, 12 insertions(+), 14 deletions(-)
create mode 100644 app/views/request_for_comments/_admin_menu.html.slim
diff --git a/app/views/request_for_comments/_admin_menu.html.slim b/app/views/request_for_comments/_admin_menu.html.slim
new file mode 100644
index 00000000..3f71b2ed
--- /dev/null
+++ b/app/views/request_for_comments/_admin_menu.html.slim
@@ -0,0 +1,9 @@
+br
+h4 Admin Menu
+h5
+ ul
+ li = link_to "User's current status of this exercise", statistics_external_user_exercise_path(id: @request_for_comment.exercise_id, external_user_id: @request_for_comment.user_id)
+ li = link_to "All exercises of this user", statistics_external_user_path(id: @request_for_comment.user_id)
+ ul
+ li = link_to "Implement the exercise yourself", implement_exercise_path(id: @request_for_comment.exercise_id)
+ li = link_to "Show the exercise", exercise_path(id: @request_for_comment.exercise_id)
diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb
index 83741a87..3814ba21 100644
--- a/app/views/request_for_comments/show.html.erb
+++ b/app/views/request_for_comments/show.html.erb
@@ -44,21 +44,10 @@
<% end %>
-
-
- <% if @current_user.admin? && user.is_a?(ExternalUser) %>
-
-
-
Admin Menu
-
-
-
<%= link_to "User's current status of this exercise", statistics_external_user_exercise_path(id: @request_for_comment.exercise_id, external_user_id: @request_for_comment.user_id) %>
-
<%= link_to "All exercises of this user", statistics_external_user_path(id: @request_for_comment.user_id) %>
-
<%= link_to "Implement the exercise yourself", implement_exercise_path(id: @request_for_comment.exercise_id) %>
-
<%= link_to "Show the exercise", exercise_path(id: @request_for_comment.exercise_id) %>
-
-
+ <% if @current_user.admin? && user.is_a?(ExternalUser) %>
+ <%= render('admin_menu') %>
<% end %>
+
<%= testrun.try(:output) or t('request_for_comments.no_output') %>
+
<%= testrun.try(:output) or t('request_for_comments.no_output') %>
<% end %>
<% end %>
@@ -142,6 +143,12 @@ also, all settings from the rails model needed for the editor configuration in t
thankYouContainer.hide();
});
+ $('.text > .collapse-button').on('click', function(e) {
+ $(this).toggleClass('fa-chevron-down');
+ $(this).toggleClass('fa-chevron-up');
+ $(this).parent().toggleClass('collapsed');
+ });
+
// set file paths for ace
var ACE_FILES_PATH = '/assets/ace/';
_.each(['modePath', 'themePath', 'workerPath'], function(attribute) {
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 88a3b1c0..f2a080de 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -494,7 +494,7 @@ de:
Um Kommentare zu einer Programmzeile hinzuzufügen, kann einfach auf die jeweilige Zeilennummer auf der linken Seite geklickt werden.
Es öffnet sich ein Textfeld, in dem der Kommentar eingetragen werden kann.
Mit "Kommentar abschicken" wird der Kommentar dann gesichert und taucht als Sprechblase neben der Zeile auf.
- howto_title: 'Anleitung:'
+ howto_title: 'Anleitung'
index:
get_my_comment_requests: Meine Kommentaranfragen
all: "Alle Kommentaranfragen"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5d9b78d8..0542bfd4 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -494,7 +494,7 @@ en:
To leave comments to a specific code line, click on the respective line number.
Enter your comment in the popup and save it by clicking "Comment this".
Your comment will show up next to the line number as a speech bubble symbol.
- howto_title: 'How to comment:'
+ howto_title: 'How to comment'
index:
all: All Requests for Comments
get_my_comment_requests: My Requests for Comments
From 54f312dfd395b4cbf8fc4ad405288d7cd3970dba Mon Sep 17 00:00:00 2001
From: Maximilian Grundke
Date: Wed, 27 Sep 2017 15:04:52 +0200
Subject: [PATCH 15/15] Remove comment
---
app/views/request_for_comments/show.html.erb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb
index a95970f6..eb88caf1 100644
--- a/app/views/request_for_comments/show.html.erb
+++ b/app/views/request_for_comments/show.html.erb
@@ -36,8 +36,7 @@
<% if policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved? %>
<%= render('mark_as_solved') %>
<% end %>
-
-
+
<% if testruns.size > 0 %>