Merge remote-tracking branch 'origin/master' into exercise-anomaly-detection
# Conflicts: # Capfile # Gemfile.lock # db/schema.rb
29
.travis.yml
@ -5,20 +5,18 @@ services:
|
|||||||
|
|
||||||
addons:
|
addons:
|
||||||
code_climate:
|
code_climate:
|
||||||
repo_token: 53a2c2608c848714e96f6a1fc0365dcfdfec051f7827d50cea965ea625f49734
|
repo_token:
|
||||||
postgresql: "9.5"
|
secure: "cZoMNjQKB/D7W4B7JDk9PXooy2WCDypu7R4C/Vi0DziZCU9HRwLbdt9aoH5hgHFa7Fe2rHFgflPAAP7h698ozvP0waFtPqLAj+PbEt27LbBDvW8JcvNkKXA0rj5wyTkzuc/0kD+kPB4oDXMak6gZlB9HCJDsa3kdXScQGTVuPdU="
|
||||||
|
postgresql: "9.6"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- export DISPLAY=:99.0
|
- export DISPLAY=:99.0
|
||||||
- sh -e /etc/init.d/xvfb start
|
- sh -e /etc/init.d/xvfb start
|
||||||
# Config to run docker tests - doesn't work so far
|
- echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2376 -H unix:///var/run/docker.sock --iptables=false"' | sudo tee /etc/default/docker > /dev/null
|
||||||
# - sudo apt-get update
|
- sudo service docker restart
|
||||||
# - sudo apt-get upgrade lxc-docker
|
- sleep 5
|
||||||
# - echo 'DOCKER_OPTS="-H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock --iptables=false"' | sudo tee /etc/default/docker > /dev/null
|
- docker pull openhpi/co_execenv_python
|
||||||
# - export DOCKER_HOST=tcp://192.168.23.75:2375
|
- docker pull openhpi/co_execenv_java
|
||||||
# - sudo service docker restart
|
|
||||||
# - sleep 5
|
|
||||||
# - docker pull openhpi/docker_ruby
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- cp .rspec.travis .rspec
|
- cp .rspec.travis .rspec
|
||||||
@ -26,18 +24,13 @@ before_script:
|
|||||||
- cp config/code_ocean.yml.travis config/code_ocean.yml
|
- cp config/code_ocean.yml.travis config/code_ocean.yml
|
||||||
- cp config/database.yml.travis config/database.yml
|
- cp config/database.yml.travis config/database.yml
|
||||||
- cp config/secrets.yml.travis config/secrets.yml
|
- cp config/secrets.yml.travis config/secrets.yml
|
||||||
|
- cp config/docker.yml.erb.travis config/docker.yml.erb
|
||||||
- psql --command='CREATE DATABASE travis_ci_test;' --username=postgres
|
- psql --command='CREATE DATABASE travis_ci_test;' --username=postgres
|
||||||
- bundle exec rake db:schema:load RAILS_ENV=test
|
- bundle exec rake db:schema:load RAILS_ENV=test
|
||||||
|
|
||||||
cache: bundler
|
cache: bundler
|
||||||
language: ruby
|
language: ruby
|
||||||
rvm:
|
rvm:
|
||||||
- 2.3.1
|
- 2.3.6
|
||||||
# - 2.1.5
|
|
||||||
# - 2.2.1
|
|
||||||
|
|
||||||
script: bundle exec rspec --color --format documentation --require spec_helper --require rails_helper --tag ~docker
|
script: bundle exec rspec --color --format documentation --require spec_helper --require rails_helper && bundle exec codeclimate-test-reporter
|
||||||
# one of the solutions I've found
|
|
||||||
# - sudo docker run --rm=true -v `pwd`:/ansible-apache:rw weldpua2008/docker-ansible:${OS_TYPE}${OS_VERSION}_v${ANSIBLE_VERSION} /bin/bash -c "/ansible-apache/tests/test-in-docker-image.sh ${OS_TYPE} ${OS_VERSION} ${ANSIBLE_VERSION}"
|
|
||||||
|
|
||||||
|
|
||||||
|
7
Capfile
@ -1,8 +1,13 @@
|
|||||||
require 'capistrano/setup'
|
require 'capistrano/setup'
|
||||||
require 'capistrano/deploy'
|
require 'capistrano/deploy'
|
||||||
|
require 'capistrano/scm/git'
|
||||||
require 'capistrano/puma'
|
require 'capistrano/puma'
|
||||||
require 'capistrano/puma/nginx'
|
require 'capistrano/puma/nginx'
|
||||||
require 'capistrano/rails'
|
require 'capistrano/rails'
|
||||||
require 'capistrano/rvm'
|
require 'capistrano/rvm'
|
||||||
require 'capistrano/upload-config'
|
require 'capistrano/upload-config'
|
||||||
require "whenever/capistrano"
|
require 'whenever/capistrano'
|
||||||
|
|
||||||
|
install_plugin Capistrano::SCM::Git
|
||||||
|
install_plugin Capistrano::Puma
|
||||||
|
install_plugin Capistrano::Puma::Nginx
|
||||||
|
41
Gemfile
@ -1,42 +1,43 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
|
gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
|
||||||
gem 'bcrypt', '~> 3.1.7'
|
gem 'bcrypt'
|
||||||
gem 'bootstrap-will_paginate'
|
gem 'bootstrap-will_paginate'
|
||||||
gem 'carrierwave'
|
gem 'carrierwave'
|
||||||
gem 'coffee-rails', '~> 4.0.0'
|
gem 'coffee-rails'
|
||||||
gem 'concurrent-ruby', '~> 1.0.1'
|
gem 'concurrent-ruby'
|
||||||
gem 'concurrent-ruby-ext', '~> 1.0.1', platform: :ruby
|
gem 'concurrent-ruby-ext', platform: :ruby
|
||||||
gem 'docker-api','~> 1.25.0', require: 'docker'
|
gem 'docker-api', require: 'docker'
|
||||||
gem 'factory_bot_rails', '~> 4.8.2'
|
gem 'factory_bot_rails'
|
||||||
gem 'forgery'
|
gem 'forgery'
|
||||||
gem 'highline'
|
gem 'highline'
|
||||||
gem 'jbuilder', '~> 2.0'
|
gem 'jbuilder'
|
||||||
gem 'jquery-rails'
|
gem 'jquery-rails'
|
||||||
gem 'jquery-turbolinks'
|
gem 'jquery-turbolinks'
|
||||||
gem 'ims-lti'
|
gem 'ims-lti', '1.1.10' # version 1.1.13 will crash, because @provider.valid_request?(request) on lti.rb line 89 will return false.
|
||||||
gem 'kramdown'
|
gem 'kramdown'
|
||||||
gem 'newrelic_rpm'
|
gem 'newrelic_rpm'
|
||||||
gem 'pg', platform: :ruby
|
gem 'pg', '< 1.0', platform: :ruby
|
||||||
gem 'pry-byebug'
|
gem 'pry-byebug'
|
||||||
gem 'puma', '~> 2.15.3'
|
gem 'puma'
|
||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
gem 'rails', '4.2.5'
|
gem 'rails', '4.2.10'
|
||||||
gem 'rails-i18n', '~> 4.0.0'
|
gem 'rails-i18n'
|
||||||
gem 'ransack'
|
gem 'ransack'
|
||||||
gem 'rubytree'
|
gem 'rubytree'
|
||||||
gem 'sass-rails', '~> 4.0.3'
|
gem 'sass-rails'
|
||||||
gem 'sdoc', '~> 0.4.0', group: :doc
|
gem 'sdoc', group: :doc
|
||||||
gem 'slim'
|
gem 'slim'
|
||||||
gem 'bootstrap_pagedown'
|
gem 'bootstrap_pagedown'
|
||||||
gem 'pagedown-rails', '~> 1.1.4'
|
gem 'pagedown-rails'
|
||||||
gem 'sorcery'
|
gem 'sorcery'
|
||||||
gem 'thread_safe'
|
gem 'thread_safe'
|
||||||
gem 'turbolinks'
|
gem 'turbolinks', '< 5.0.0' # newer versions prevent loading ACE if the page containing is not accessed directly / refreshed
|
||||||
gem 'uglifier', '>= 1.3.0'
|
gem 'uglifier'
|
||||||
gem 'will_paginate', '~> 3.0'
|
gem 'will_paginate'
|
||||||
gem 'tubesock'
|
gem 'tubesock'
|
||||||
gem 'faye-websocket'
|
gem 'faye-websocket'
|
||||||
|
gem 'eventmachine', '1.0.9.1' # explicitly added, this is used by faye-websocket, version 1.2.5 still has an error in eventmachine.rb:202: [BUG] Segmentation fault, which is not yet fixed and causes the whole ruby process to crash
|
||||||
gem 'nokogiri'
|
gem 'nokogiri'
|
||||||
gem 'd3-rails'
|
gem 'd3-rails'
|
||||||
gem 'rest-client'
|
gem 'rest-client'
|
||||||
@ -46,7 +47,7 @@ gem 'whenever', require: false
|
|||||||
group :development, :staging do
|
group :development, :staging do
|
||||||
gem 'better_errors', platform: :ruby
|
gem 'better_errors', platform: :ruby
|
||||||
gem 'binding_of_caller', platform: :ruby
|
gem 'binding_of_caller', platform: :ruby
|
||||||
gem 'capistrano', '~> 3.3.0'
|
gem 'capistrano'
|
||||||
gem 'capistrano3-puma'
|
gem 'capistrano3-puma'
|
||||||
gem 'capistrano-rails'
|
gem 'capistrano-rails'
|
||||||
gem 'capistrano-rvm'
|
gem 'capistrano-rvm'
|
||||||
@ -54,7 +55,7 @@ group :development, :staging do
|
|||||||
gem 'rack-mini-profiler'
|
gem 'rack-mini-profiler'
|
||||||
gem 'rubocop', require: false
|
gem 'rubocop', require: false
|
||||||
gem 'rubocop-rspec'
|
gem 'rubocop-rspec'
|
||||||
gem 'web-console', '~> 2.0', platform: :ruby
|
gem 'web-console', platform: :ruby
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test, :staging do
|
group :development, :test, :staging do
|
||||||
|
162
Gemfile.lock
@ -2,43 +2,42 @@ GEM
|
|||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
ZenTest (4.11.0)
|
ZenTest (4.11.0)
|
||||||
actionmailer (4.2.5)
|
actionmailer (4.2.10)
|
||||||
actionpack (= 4.2.5)
|
actionpack (= 4.2.10)
|
||||||
actionview (= 4.2.5)
|
actionview (= 4.2.10)
|
||||||
activejob (= 4.2.5)
|
activejob (= 4.2.10)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionpack (4.2.5)
|
actionpack (4.2.10)
|
||||||
actionview (= 4.2.5)
|
actionview (= 4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
rack (~> 1.6)
|
rack (~> 1.6)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.5)
|
actionview (4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
activejob (4.2.5)
|
activejob (4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.5)
|
activemodel (4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.5)
|
activerecord (4.2.10)
|
||||||
activemodel (= 4.2.5)
|
activemodel (= 4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activerecord-jdbc-adapter (1.3.19)
|
activerecord-jdbc-adapter (1.3.19)
|
||||||
activerecord (>= 2.2)
|
activerecord (>= 2.2)
|
||||||
activerecord-jdbcpostgresql-adapter (1.3.19)
|
activerecord-jdbcpostgresql-adapter (1.3.19)
|
||||||
activerecord-jdbc-adapter (~> 1.3.19)
|
activerecord-jdbc-adapter (~> 1.3.19)
|
||||||
jdbc-postgres (>= 9.1)
|
jdbc-postgres (>= 9.1)
|
||||||
activesupport (4.2.5)
|
activesupport (4.2.10)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.3, >= 0.3.4)
|
thread_safe (~> 0.3, >= 0.3.4)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
@ -59,7 +58,7 @@ GEM
|
|||||||
will_paginate
|
will_paginate
|
||||||
bootstrap_pagedown (1.1.0)
|
bootstrap_pagedown (1.1.0)
|
||||||
rails (>= 3.2)
|
rails (>= 3.2)
|
||||||
builder (3.2.2)
|
builder (3.2.3)
|
||||||
byebug (8.2.2)
|
byebug (8.2.2)
|
||||||
capistrano (3.3.5)
|
capistrano (3.3.5)
|
||||||
capistrano-stats (~> 1.1.0)
|
capistrano-stats (~> 1.1.0)
|
||||||
@ -110,6 +109,7 @@ GEM
|
|||||||
concurrent-ruby (1.0.2-java)
|
concurrent-ruby (1.0.2-java)
|
||||||
concurrent-ruby-ext (1.0.2)
|
concurrent-ruby-ext (1.0.2)
|
||||||
concurrent-ruby (~> 1.0.2)
|
concurrent-ruby (~> 1.0.2)
|
||||||
|
crass (1.0.3)
|
||||||
d3-rails (3.5.11)
|
d3-rails (3.5.11)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
database_cleaner (1.5.1)
|
database_cleaner (1.5.1)
|
||||||
@ -139,13 +139,14 @@ GEM
|
|||||||
ffi (1.9.10)
|
ffi (1.9.10)
|
||||||
ffi (1.9.10-java)
|
ffi (1.9.10-java)
|
||||||
forgery (0.6.0)
|
forgery (0.6.0)
|
||||||
globalid (0.3.7)
|
globalid (0.4.1)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.2.0)
|
||||||
highline (1.7.8)
|
highline (1.7.8)
|
||||||
hike (1.2.3)
|
hike (1.2.3)
|
||||||
http-cookie (1.0.2)
|
http-cookie (1.0.2)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
i18n (0.7.0)
|
i18n (0.9.5)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
ims-lti (1.1.10)
|
ims-lti (1.1.10)
|
||||||
builder
|
builder
|
||||||
oauth (~> 0.4.5)
|
oauth (~> 0.4.5)
|
||||||
@ -159,19 +160,21 @@ GEM
|
|||||||
jquery-turbolinks (2.1.0)
|
jquery-turbolinks (2.1.0)
|
||||||
railties (>= 3.1.0)
|
railties (>= 3.1.0)
|
||||||
turbolinks
|
turbolinks
|
||||||
json (1.8.3)
|
json (1.8.6)
|
||||||
json (1.8.3-java)
|
json (1.8.6-java)
|
||||||
jwt (1.5.1)
|
jwt (1.5.1)
|
||||||
kramdown (1.9.0)
|
kramdown (1.9.0)
|
||||||
loofah (2.0.3)
|
loofah (2.2.0)
|
||||||
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.4)
|
mail (2.7.0)
|
||||||
mime-types (>= 1.16, < 4)
|
mini_mime (>= 0.1.1)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (2.99.3)
|
mime-types (2.99.3)
|
||||||
mini_portile2 (2.1.0)
|
mini_mime (1.0.0)
|
||||||
minitest (5.10.1)
|
mini_portile2 (2.3.0)
|
||||||
multi_json (1.12.1)
|
minitest (5.11.3)
|
||||||
|
multi_json (1.13.1)
|
||||||
multi_xml (0.5.5)
|
multi_xml (0.5.5)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
@ -179,9 +182,9 @@ GEM
|
|||||||
net-ssh (3.0.2)
|
net-ssh (3.0.2)
|
||||||
netrc (0.10.3)
|
netrc (0.10.3)
|
||||||
newrelic_rpm (3.14.3.313)
|
newrelic_rpm (3.14.3.313)
|
||||||
nokogiri (1.7.0.1)
|
nokogiri (1.8.2)
|
||||||
mini_portile2 (~> 2.1.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
nokogiri (1.7.0.1-java)
|
nokogiri (1.8.2-java)
|
||||||
nyan-cat-formatter (0.11)
|
nyan-cat-formatter (0.11)
|
||||||
rspec (>= 2.99, >= 2.14.2, < 4)
|
rspec (>= 2.99, >= 2.14.2, < 4)
|
||||||
oauth (0.4.7)
|
oauth (0.4.7)
|
||||||
@ -203,6 +206,11 @@ GEM
|
|||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
|
pry (0.10.3-java)
|
||||||
|
coderay (~> 1.1.0)
|
||||||
|
method_source (~> 0.8.1)
|
||||||
|
slop (~> 3.4)
|
||||||
|
spoon (~> 0.0)
|
||||||
pry-byebug (3.3.0)
|
pry-byebug (3.3.0)
|
||||||
byebug (~> 8.0)
|
byebug (~> 8.0)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
@ -210,26 +218,26 @@ GEM
|
|||||||
puma (2.15.3-java)
|
puma (2.15.3-java)
|
||||||
pundit (1.1.0)
|
pundit (1.1.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
rack (1.6.5)
|
rack (1.6.9)
|
||||||
rack-mini-profiler (0.10.1)
|
rack-mini-profiler (0.10.1)
|
||||||
rack (>= 1.2.0)
|
rack (>= 1.2.0)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.5)
|
rails (4.2.10)
|
||||||
actionmailer (= 4.2.5)
|
actionmailer (= 4.2.10)
|
||||||
actionpack (= 4.2.5)
|
actionpack (= 4.2.10)
|
||||||
actionview (= 4.2.5)
|
actionview (= 4.2.10)
|
||||||
activejob (= 4.2.5)
|
activejob (= 4.2.10)
|
||||||
activemodel (= 4.2.5)
|
activemodel (= 4.2.10)
|
||||||
activerecord (= 4.2.5)
|
activerecord (= 4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.5)
|
railties (= 4.2.10)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
activesupport (>= 4.2.0.alpha)
|
activesupport (>= 4.2.0.alpha)
|
||||||
rails-dom-testing (1.0.8)
|
rails-dom-testing (1.0.9)
|
||||||
activesupport (>= 4.2.0.beta, < 5.0)
|
activesupport (>= 4.2.0, < 5.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
@ -237,13 +245,13 @@ GEM
|
|||||||
rails-i18n (4.0.8)
|
rails-i18n (4.0.8)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
railties (~> 4.0)
|
railties (~> 4.0)
|
||||||
railties (4.2.5)
|
railties (4.2.10)
|
||||||
actionpack (= 4.2.5)
|
actionpack (= 4.2.10)
|
||||||
activesupport (= 4.2.5)
|
activesupport (= 4.2.10)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.2.1)
|
rainbow (2.2.1)
|
||||||
rake (12.0.0)
|
rake (12.3.0)
|
||||||
ransack (1.7.0)
|
ransack (1.7.0)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
@ -319,6 +327,8 @@ GEM
|
|||||||
bcrypt (~> 3.1)
|
bcrypt (~> 3.1)
|
||||||
oauth (~> 0.4, >= 0.4.4)
|
oauth (~> 0.4, >= 0.4.4)
|
||||||
oauth2 (>= 0.8.0)
|
oauth2 (>= 0.8.0)
|
||||||
|
spoon (0.0.6)
|
||||||
|
ffi
|
||||||
spring (1.6.3)
|
spring (1.6.3)
|
||||||
sprockets (2.12.4)
|
sprockets (2.12.4)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
@ -334,16 +344,16 @@ GEM
|
|||||||
net-ssh (>= 2.8.0)
|
net-ssh (>= 2.8.0)
|
||||||
structured_warnings (0.2.0)
|
structured_warnings (0.2.0)
|
||||||
temple (0.7.6)
|
temple (0.7.6)
|
||||||
thor (0.19.4)
|
thor (0.20.0)
|
||||||
thread_safe (0.3.5)
|
thread_safe (0.3.6)
|
||||||
thread_safe (0.3.5-java)
|
thread_safe (0.3.6-java)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
tubesock (0.2.5)
|
tubesock (0.2.5)
|
||||||
rack (>= 1.5.0)
|
rack (>= 1.5.0)
|
||||||
websocket (>= 1.1.0)
|
websocket (>= 1.1.0)
|
||||||
turbolinks (2.5.3)
|
turbolinks (2.5.3)
|
||||||
coffee-rails
|
coffee-rails
|
||||||
tzinfo (1.2.2)
|
tzinfo (1.2.5)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (2.7.2)
|
uglifier (2.7.2)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
@ -377,13 +387,13 @@ PLATFORMS
|
|||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
activerecord-jdbcpostgresql-adapter
|
activerecord-jdbcpostgresql-adapter
|
||||||
autotest-rails
|
autotest-rails
|
||||||
bcrypt (~> 3.1.7)
|
bcrypt
|
||||||
better_errors
|
better_errors
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
bootstrap-will_paginate
|
bootstrap-will_paginate
|
||||||
bootstrap_pagedown
|
bootstrap_pagedown
|
||||||
byebug
|
byebug
|
||||||
capistrano (~> 3.3.0)
|
capistrano
|
||||||
capistrano-rails
|
capistrano-rails
|
||||||
capistrano-rvm
|
capistrano-rvm
|
||||||
capistrano-upload-config
|
capistrano-upload-config
|
||||||
@ -391,32 +401,33 @@ DEPENDENCIES
|
|||||||
capybara
|
capybara
|
||||||
carrierwave
|
carrierwave
|
||||||
codeclimate-test-reporter
|
codeclimate-test-reporter
|
||||||
coffee-rails (~> 4.0.0)
|
coffee-rails
|
||||||
concurrent-ruby (~> 1.0.1)
|
concurrent-ruby
|
||||||
concurrent-ruby-ext (~> 1.0.1)
|
concurrent-ruby-ext
|
||||||
d3-rails
|
d3-rails
|
||||||
database_cleaner
|
database_cleaner
|
||||||
docker-api (~> 1.25.0)
|
docker-api
|
||||||
factory_bot_rails (~> 4.8.2)
|
eventmachine (= 1.0.9.1)
|
||||||
|
factory_bot_rails
|
||||||
faye-websocket
|
faye-websocket
|
||||||
forgery
|
forgery
|
||||||
highline
|
highline
|
||||||
ims-lti
|
ims-lti (= 1.1.10)
|
||||||
jbuilder (~> 2.0)
|
jbuilder
|
||||||
jquery-rails
|
jquery-rails
|
||||||
jquery-turbolinks
|
jquery-turbolinks
|
||||||
kramdown
|
kramdown
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
nokogiri
|
nokogiri
|
||||||
nyan-cat-formatter
|
nyan-cat-formatter
|
||||||
pagedown-rails (~> 1.1.4)
|
pagedown-rails
|
||||||
pg
|
pg (< 1.0)
|
||||||
pry-byebug
|
pry-byebug
|
||||||
puma (~> 2.15.3)
|
puma
|
||||||
pundit
|
pundit
|
||||||
rack-mini-profiler
|
rack-mini-profiler
|
||||||
rails (= 4.2.5)
|
rails (= 4.2.10)
|
||||||
rails-i18n (~> 4.0.0)
|
rails-i18n
|
||||||
rake
|
rake
|
||||||
ransack
|
ransack
|
||||||
rest-client
|
rest-client
|
||||||
@ -426,8 +437,8 @@ DEPENDENCIES
|
|||||||
rubocop-rspec
|
rubocop-rspec
|
||||||
rubytree
|
rubytree
|
||||||
rubyzip
|
rubyzip
|
||||||
sass-rails (~> 4.0.3)
|
sass-rails
|
||||||
sdoc (~> 0.4.0)
|
sdoc
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
simplecov
|
simplecov
|
||||||
slim
|
slim
|
||||||
@ -435,8 +446,11 @@ DEPENDENCIES
|
|||||||
spring
|
spring
|
||||||
thread_safe
|
thread_safe
|
||||||
tubesock
|
tubesock
|
||||||
turbolinks
|
turbolinks (< 5.0.0)
|
||||||
uglifier (>= 1.3.0)
|
uglifier
|
||||||
web-console (~> 2.0)
|
web-console
|
||||||
whenever
|
whenever
|
||||||
will_paginate (~> 3.0)
|
will_paginate
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.16.1
|
||||||
|
@ -26,4 +26,4 @@
|
|||||||
//= require markdown.converter
|
//= require markdown.converter
|
||||||
//= require markdown.sanitizer
|
//= require markdown.sanitizer
|
||||||
//= require markdown.editor
|
//= require markdown.editor
|
||||||
//= require ../../../vendor/assets/javascripts/ace/ext-language_tools
|
//= require ace/ext-language_tools
|
@ -3,7 +3,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chosen-container {
|
.chosen-container {
|
||||||
width: 100% !important;
|
width: 250px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-field {
|
.code-field {
|
||||||
|
@ -9,7 +9,7 @@ module SubmissionScoring
|
|||||||
assessment = assessor.assess(output)
|
assessment = assessor.assess(output)
|
||||||
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
|
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
|
||||||
testrun_output = passed ? nil : 'message: ' + output[:message].to_s + "\n stdout: " + output[:stdout].to_s + "\n stderr: " + output[:stderr].to_s
|
testrun_output = passed ? nil : 'message: ' + output[:message].to_s + "\n stdout: " + output[:stdout].to_s + "\n stderr: " + output[:stderr].to_s
|
||||||
if !testrun_output.blank?
|
unless testrun_output.blank?
|
||||||
submission.exercise.execution_environment.error_templates.each do |template|
|
submission.exercise.execution_environment.error_templates.each do |template|
|
||||||
pattern = Regexp.new(template.signature).freeze
|
pattern = Regexp.new(template.signature).freeze
|
||||||
if pattern.match(testrun_output)
|
if pattern.match(testrun_output)
|
||||||
@ -47,6 +47,14 @@ module SubmissionScoring
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
submission.update(score: score)
|
submission.update(score: score)
|
||||||
|
if submission.normalized_score == 1.0
|
||||||
|
Thread.new do
|
||||||
|
RequestForComment.where(exercise_id: submission.exercise_id, user_id: submission.user_id, user_type: submission.user_type).each{ |rfc|
|
||||||
|
rfc.full_score_reached = true
|
||||||
|
rfc.save
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
outputs
|
outputs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -416,6 +416,9 @@ class ExercisesController < ApplicationController
|
|||||||
flash[:notice] = I18n.t('exercises.submit.full_score_redirect_to_rfc')
|
flash[:notice] = I18n.t('exercises.submit.full_score_redirect_to_rfc')
|
||||||
flash.keep(:notice)
|
flash.keep(:notice)
|
||||||
|
|
||||||
|
# increase counter 'times_featured' in rfc
|
||||||
|
rfc.increment!(:times_featured)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {redirect_to(rfc)}
|
format.html {redirect_to(rfc)}
|
||||||
format.json {render(json: {redirect: url_for(rfc)})}
|
format.json {render(json: {redirect: url_for(rfc)})}
|
||||||
|
@ -14,46 +14,40 @@ class RequestForCommentsController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
@search = RequestForComment
|
@search = RequestForComment
|
||||||
.last_per_user(2)
|
.last_per_user(2)
|
||||||
.joins('join "submissions" s on s.id = request_for_comments.submission_id
|
.with_last_activity
|
||||||
left outer join "files" f on f.context_id = s.id
|
|
||||||
left outer join "comments" on comments.file_id = f.id')
|
|
||||||
.group('request_for_comments.id, request_for_comments.user_id, request_for_comments.exercise_id,
|
|
||||||
request_for_comments.file_id, request_for_comments.question, request_for_comments.created_at,
|
|
||||||
request_for_comments.updated_at, request_for_comments.user_type, request_for_comments.solved,
|
|
||||||
request_for_comments.submission_id, request_for_comments.row_number') # ugly, but rails wants it this way
|
|
||||||
.select('request_for_comments.*, max(comments.updated_at) as last_comment')
|
|
||||||
.search(params[:q])
|
.search(params[:q])
|
||||||
@request_for_comments = @search.result.order('created_at DESC').paginate(page: params[:page], total_entries: @search.result.length)
|
@request_for_comments = @search.result
|
||||||
|
.order('created_at DESC')
|
||||||
|
.paginate(page: params[:page], total_entries: @search.result.length)
|
||||||
authorize!
|
authorize!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# GET /my_request_for_comments
|
||||||
def get_my_comment_requests
|
def get_my_comment_requests
|
||||||
@search = RequestForComment
|
@search = RequestForComment
|
||||||
|
.with_last_activity
|
||||||
.where(user_id: current_user.id)
|
.where(user_id: current_user.id)
|
||||||
.joins('join "submissions" s on s.id = request_for_comments.submission_id
|
|
||||||
left outer join "files" f on f.context_id = s.id
|
|
||||||
left outer join "comments" on comments.file_id = f.id')
|
|
||||||
.group('request_for_comments.id')
|
|
||||||
.select('request_for_comments.*, max(comments.updated_at) as last_comment')
|
|
||||||
.search(params[:q])
|
.search(params[:q])
|
||||||
@request_for_comments = @search.result.order('created_at DESC').paginate(page: params[:page])
|
@request_for_comments = @search.result
|
||||||
|
.order('created_at DESC')
|
||||||
|
.paginate(page: params[:page])
|
||||||
render 'index'
|
render 'index'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# GET /my_rfc_activity
|
||||||
def get_rfcs_with_my_comments
|
def get_rfcs_with_my_comments
|
||||||
@search = RequestForComment
|
@search = RequestForComment
|
||||||
|
.with_last_activity
|
||||||
.joins(:comments) # we don't need to outer join here, because we know the user has commented on these
|
.joins(:comments) # we don't need to outer join here, because we know the user has commented on these
|
||||||
.where(comments: {user_id: current_user.id})
|
.where(comments: {user_id: current_user.id})
|
||||||
.joins('join "submissions" s on s.id = request_for_comments.submission_id
|
|
||||||
left outer join "files" f on f.context_id = s.id
|
|
||||||
left outer join "comments" as c on c.file_id = f.id')
|
|
||||||
.group('request_for_comments.id')
|
|
||||||
.select('request_for_comments.*, max(c.updated_at) as last_comment')
|
|
||||||
.search(params[:q])
|
.search(params[:q])
|
||||||
@request_for_comments = @search.result.order('last_comment DESC').paginate(page: params[:page])
|
@request_for_comments = @search.result
|
||||||
|
.order('last_comment DESC')
|
||||||
|
.paginate(page: params[:page])
|
||||||
render 'index'
|
render 'index'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# GET /request_for_comments/1/mark_as_solved
|
||||||
def mark_as_solved
|
def mark_as_solved
|
||||||
authorize!
|
authorize!
|
||||||
@request_for_comment.solved = true
|
@request_for_comment.solved = true
|
||||||
@ -66,6 +60,7 @@ class RequestForCommentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# POST /request_for_comments/1/set_thank_you_note
|
||||||
def set_thank_you_note
|
def set_thank_you_note
|
||||||
authorize!
|
authorize!
|
||||||
@request_for_comment.thank_you_note = params[:note]
|
@request_for_comment.thank_you_note = params[:note]
|
||||||
@ -82,10 +77,6 @@ class RequestForCommentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def submit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# GET /request_for_comments/1
|
# GET /request_for_comments/1
|
||||||
# GET /request_for_comments/1.json
|
# GET /request_for_comments/1.json
|
||||||
def show
|
def show
|
||||||
@ -146,10 +137,6 @@ class RequestForCommentsController < ApplicationController
|
|||||||
authorize!
|
authorize!
|
||||||
end
|
end
|
||||||
|
|
||||||
def comment_params
|
|
||||||
params.permit(:exercise_id, :feedback_text).merge(user_id: current_user.id, user_type: current_user.class.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
# Use callbacks to share common setup or constraints between actions.
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
def set_request_for_comment
|
def set_request_for_comment
|
||||||
@ -162,4 +149,8 @@ class RequestForCommentsController < ApplicationController
|
|||||||
params.require(:request_for_comment).permit(:exercise_id, :file_id, :question, :requested_at, :solved, :submission_id).merge(user_id: current_user.id, user_type: current_user.class.name)
|
params.require(:request_for_comment).permit(:exercise_id, :file_id, :question, :requested_at, :solved, :submission_id).merge(user_id: current_user.id, user_type: current_user.class.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def comment_params
|
||||||
|
params.permit(:exercise_id, :feedback_text).merge(user_id: current_user.id, user_type: current_user.class.name)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -202,21 +202,11 @@ class SubmissionsController < ApplicationController
|
|||||||
tubesock.close
|
tubesock.close
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_errors
|
|
||||||
if !@message_buffer.blank?
|
|
||||||
@submission.exercise.execution_environment.error_templates.each do |template|
|
|
||||||
pattern = Regexp.new(template.signature).freeze
|
|
||||||
if pattern.match(@message_buffer)
|
|
||||||
StructuredError.create_from_template(template, @message_buffer)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_message(message, tubesock, container)
|
def handle_message(message, tubesock, container)
|
||||||
@run_output ||= ""
|
@raw_output ||= ''
|
||||||
|
@run_output ||= ''
|
||||||
# Handle special commands first
|
# Handle special commands first
|
||||||
if (/^#exit/.match(message))
|
if /^#exit/.match(message)
|
||||||
# Just call exit_container on the docker_client.
|
# Just call exit_container on the docker_client.
|
||||||
# Do not call kill_socket for the websocket to the client here.
|
# Do not call kill_socket for the websocket to the client here.
|
||||||
# @docker_client.exit_container closes the socket to the container,
|
# @docker_client.exit_container closes the socket to the container,
|
||||||
@ -228,17 +218,17 @@ class SubmissionsController < ApplicationController
|
|||||||
# Filter out information about run_command, test_command, user or working directory
|
# Filter out information about run_command, test_command, user or working directory
|
||||||
run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename])
|
run_command = @submission.execution_environment.run_command % command_substitutions(params[:filename])
|
||||||
test_command = @submission.execution_environment.test_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))
|
unless /root|workspace|#{run_command}|#{test_command}/.match(message)
|
||||||
parse_message(message, 'stdout', tubesock)
|
parse_message(message, 'stdout', tubesock)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_message(message, output_stream, socket, recursive = true)
|
def parse_message(message, output_stream, socket, recursive = true)
|
||||||
parsed = '';
|
parsed = ''
|
||||||
begin
|
begin
|
||||||
parsed = JSON.parse(message)
|
parsed = JSON.parse(message)
|
||||||
if(parsed.class == Hash && parsed.key?('cmd'))
|
if parsed.class == Hash and parsed.key?('cmd')
|
||||||
socket.send_data message
|
socket.send_data message
|
||||||
Rails.logger.info('parse_message sent: ' + message)
|
Rails.logger.info('parse_message sent: ' + message)
|
||||||
else
|
else
|
||||||
@ -248,24 +238,24 @@ class SubmissionsController < ApplicationController
|
|||||||
end
|
end
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
# Check wether the message contains multiple lines, if true try to parse each line
|
# Check wether the message contains multiple lines, if true try to parse each line
|
||||||
if ((recursive == true) && (message.include? "\n"))
|
if recursive and message.include? "\n"
|
||||||
for part in message.split("\n")
|
for part in message.split("\n")
|
||||||
self.parse_message(part,output_stream,socket,false)
|
self.parse_message(part,output_stream,socket,false)
|
||||||
end
|
end
|
||||||
elsif(message.include? "<img")
|
elsif message.include? '<img'
|
||||||
#Rails.logger.info('img foung')
|
#Rails.logger.info('img foung')
|
||||||
@buffering = true
|
@buffering = true
|
||||||
@buffer = ""
|
@buffer = ''
|
||||||
@buffer += message
|
@buffer += message
|
||||||
#Rails.logger.info('Starting to buffer')
|
#Rails.logger.info('Starting to buffer')
|
||||||
elsif(@buffering && (message.include? "/>"))
|
elsif @buffering and message.include? '/>'
|
||||||
@buffer += message
|
@buffer += message
|
||||||
parsed = {'cmd'=>'write','stream'=>output_stream,'data'=>@buffer}
|
parsed = {'cmd'=>'write','stream'=>output_stream,'data'=>@buffer}
|
||||||
socket.send_data JSON.dump(parsed)
|
socket.send_data JSON.dump(parsed)
|
||||||
#socket.send_data @buffer
|
#socket.send_data @buffer
|
||||||
@buffering = false
|
@buffering = false
|
||||||
#Rails.logger.info('Sent complete buffer')
|
#Rails.logger.info('Sent complete buffer')
|
||||||
elsif(@buffering)
|
elsif @buffering
|
||||||
@buffer += message
|
@buffer += message
|
||||||
#Rails.logger.info('Appending to buffer')
|
#Rails.logger.info('Appending to buffer')
|
||||||
else
|
else
|
||||||
@ -275,18 +265,30 @@ class SubmissionsController < ApplicationController
|
|||||||
Rails.logger.info('parse_message sent: ' + JSON.dump(parsed))
|
Rails.logger.info('parse_message sent: ' + JSON.dump(parsed))
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
|
@raw_output += parsed['data'] if parsed.class == Hash and parsed.key? 'data'
|
||||||
# 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"
|
# 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
|
@run_output += JSON.dump(parsed) if @run_output.size <= max_run_output_buffer_size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_run_output
|
def save_run_output
|
||||||
if !@run_output.blank?
|
unless @run_output.blank?
|
||||||
@run_output = @run_output[(0..max_run_output_buffer_size-1)] # trim the string to max_message_buffer_size chars
|
@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)
|
Testrun.create(file: @file, cause: 'run', submission: @submission, output: @run_output)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def extract_errors
|
||||||
|
unless @raw_output.blank?
|
||||||
|
@submission.exercise.execution_environment.error_templates.each do |template|
|
||||||
|
pattern = Regexp.new(template.signature).freeze
|
||||||
|
if pattern.match(@raw_output)
|
||||||
|
StructuredError.create_from_template(template, @raw_output, @submission)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def score
|
def score
|
||||||
hijack do |tubesock|
|
hijack do |tubesock|
|
||||||
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
|
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
|
||||||
|
@ -47,7 +47,7 @@ class ExecutionEnvironment < ActiveRecord::Base
|
|||||||
private :validate_docker_image?
|
private :validate_docker_image?
|
||||||
|
|
||||||
def working_docker_image?
|
def working_docker_image?
|
||||||
DockerClient.pull(docker_image) unless DockerClient.image_tags.include?(docker_image)
|
DockerClient.pull(docker_image) unless DockerClient.find_image_by_tag(docker_image).blank?
|
||||||
output = DockerClient.new(execution_environment: self).execute_arbitrary_command(VALIDATION_COMMAND)
|
output = DockerClient.new(execution_environment: self).execute_arbitrary_command(VALIDATION_COMMAND)
|
||||||
errors.add(:docker_image, "error: #{output[:stderr]}") if output[:stderr].present?
|
errors.add(:docker_image, "error: #{output[:stderr]}") if output[:stderr].present?
|
||||||
rescue DockerClient::Error => error
|
rescue DockerClient::Error => error
|
||||||
|
@ -10,7 +10,13 @@ class RequestForComment < ActiveRecord::Base
|
|||||||
scope :unsolved, -> { where(solved: [false, nil]) }
|
scope :unsolved, -> { where(solved: [false, nil]) }
|
||||||
|
|
||||||
def self.last_per_user(n = 5)
|
def self.last_per_user(n = 5)
|
||||||
from("(#{row_number_user_sql}) as request_for_comments").where("row_number <= ?", n)
|
from("(#{row_number_user_sql}) as request_for_comments")
|
||||||
|
.where("row_number <= ?", n)
|
||||||
|
.group('request_for_comments.id, request_for_comments.user_id, request_for_comments.exercise_id,
|
||||||
|
request_for_comments.file_id, request_for_comments.question, request_for_comments.created_at,
|
||||||
|
request_for_comments.updated_at, request_for_comments.user_type, request_for_comments.solved,
|
||||||
|
request_for_comments.full_score_reached, request_for_comments.submission_id, request_for_comments.row_number')
|
||||||
|
# ugly, but necessary
|
||||||
end
|
end
|
||||||
|
|
||||||
# not used right now, finds the last submission for the respective user and exercise.
|
# not used right now, finds the last submission for the respective user and exercise.
|
||||||
@ -46,12 +52,20 @@ class RequestForComment < ActiveRecord::Base
|
|||||||
commenters.uniq {|user| user.id}
|
commenters.uniq {|user| user.id}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.with_last_activity
|
||||||
|
self.joins('join "submissions" s on s.id = request_for_comments.submission_id
|
||||||
|
left outer join "files" f on f.context_id = s.id
|
||||||
|
left outer join "comments" c on c.file_id = f.id')
|
||||||
|
.group('request_for_comments.id')
|
||||||
|
.select('request_for_comments.*, max(c.updated_at) as last_comment')
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"RFC-" + self.id.to_s
|
"RFC-" + self.id.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def self.row_number_user_sql
|
def self.row_number_user_sql
|
||||||
select("id, user_id, exercise_id, file_id, question, created_at, updated_at, user_type, solved, submission_id, row_number() OVER (PARTITION BY user_id ORDER BY created_at DESC) as row_number").to_sql
|
select("id, user_id, exercise_id, file_id, question, created_at, updated_at, user_type, solved, full_score_reached, submission_id, row_number() OVER (PARTITION BY user_id ORDER BY created_at DESC) as row_number").to_sql
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
class StructuredError < ActiveRecord::Base
|
class StructuredError < ActiveRecord::Base
|
||||||
belongs_to :error_template
|
belongs_to :error_template
|
||||||
|
belongs_to :submission
|
||||||
belongs_to :file, class_name: 'CodeOcean::File'
|
belongs_to :file, class_name: 'CodeOcean::File'
|
||||||
|
|
||||||
def self.create_from_template(template, message_buffer)
|
def self.create_from_template(template, message_buffer, submission)
|
||||||
instance = self.create(error_template: template)
|
instance = self.create(error_template: template, submission: submission)
|
||||||
template.error_template_attributes.each do |attribute|
|
template.error_template_attributes.each do |attribute|
|
||||||
StructuredErrorAttribute.create_from_template(attribute, instance, message_buffer)
|
StructuredErrorAttribute.create_from_template(attribute, instance, message_buffer)
|
||||||
end
|
end
|
||||||
|
@ -3,15 +3,13 @@ class StructuredErrorAttribute < ActiveRecord::Base
|
|||||||
belongs_to :error_template_attribute
|
belongs_to :error_template_attribute
|
||||||
|
|
||||||
def self.create_from_template(attribute, structured_error, message_buffer)
|
def self.create_from_template(attribute, structured_error, message_buffer)
|
||||||
match = false
|
|
||||||
value = nil
|
value = nil
|
||||||
result = message_buffer.match(attribute.regex)
|
result = message_buffer.match(attribute.regex)
|
||||||
if result != nil
|
if result != nil
|
||||||
match = true
|
|
||||||
if result.captures.size > 0
|
if result.captures.size > 0
|
||||||
value = result.captures[0]
|
value = result.captures[0]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.create(structured_error: structured_error, error_template_attribute: attribute, value: value, match: match)
|
self.create(structured_error: structured_error, error_template_attribute: attribute, value: value, match: result != nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -8,6 +8,7 @@ class Submission < ActiveRecord::Base
|
|||||||
belongs_to :exercise
|
belongs_to :exercise
|
||||||
|
|
||||||
has_many :testruns
|
has_many :testruns
|
||||||
|
has_many :structured_errors
|
||||||
has_many :comments, through: :files
|
has_many :comments, through: :files
|
||||||
|
|
||||||
delegate :execution_environment, to: :exercise
|
delegate :execution_environment, to: :exercise
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#flash.fixed_error_messages data-message-failure=t('shared.message_failure')
|
#flash-container
|
||||||
- %w[alert danger info notice success warning].each do |severity|
|
#flash.container.fixed_error_messages data-message-failure=t('shared.message_failure')
|
||||||
div.alert.flash class="alert-#{{'alert' => 'warning', 'notice' => 'success'}.fetch(severity, severity)}"
|
- %w[alert danger info notice success warning].each do |severity|
|
||||||
p id="flash-#{severity}" = flash[severity]
|
div.alert.flash class="alert-#{{'alert' => 'warning', 'notice' => 'success'}.fetch(severity, severity)}"
|
||||||
span.fa.fa-times
|
p id="flash-#{severity}" = flash[severity]
|
||||||
|
span.fa.fa-times
|
||||||
|
@ -32,8 +32,8 @@ html lang='en'
|
|||||||
li = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'})
|
li = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'})
|
||||||
= render('session')
|
= render('session')
|
||||||
.container data-controller=controller_name
|
.container data-controller=controller_name
|
||||||
= render('breadcrumbs')
|
|
||||||
= render('flash')
|
= render('flash')
|
||||||
|
= render('breadcrumbs')
|
||||||
- if (controller_name == "exercises" && action_name == "implement")
|
- if (controller_name == "exercises" && action_name == "implement")
|
||||||
.container-fluid
|
.container-fluid
|
||||||
= yield
|
= yield
|
||||||
|
@ -27,6 +27,9 @@ h1 = RequestForComment.model_name.human(count: 2)
|
|||||||
- if request_for_comment.solved?
|
- if request_for_comment.solved?
|
||||||
td
|
td
|
||||||
span class="fa fa-check" aria-hidden="true"
|
span class="fa fa-check" aria-hidden="true"
|
||||||
|
- elsif request_for_comment.full_score_reached
|
||||||
|
td
|
||||||
|
span class="fa fa-check" style="color:darkgrey" aria-hidden="true"
|
||||||
- else
|
- else
|
||||||
td = ''
|
td = ''
|
||||||
td = link_to(request_for_comment.exercise.title, request_for_comment)
|
td = link_to(request_for_comment.exercise.title, request_for_comment)
|
||||||
|
@ -17,7 +17,7 @@ namespace :deploy do
|
|||||||
after :compile_assets, :copy_vendor_assets do
|
after :compile_assets, :copy_vendor_assets do
|
||||||
on roles(fetch(:assets_roles)) do
|
on roles(fetch(:assets_roles)) do
|
||||||
within release_path do
|
within release_path do
|
||||||
execute :cp, 'vendor/assets/images/*', 'public/assets/'
|
execute :cp, '-r', 'vendor/assets/images/', 'public/assets/'
|
||||||
execute :cp, '-r', 'vendor/assets/javascripts/ace', 'public/assets/'
|
execute :cp, '-r', 'vendor/assets/javascripts/ace', 'public/assets/'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -34,7 +34,21 @@ production:
|
|||||||
ws_host: ws://localhost:4243 #url to connect rails server to docker host
|
ws_host: ws://localhost:4243 #url to connect rails server to docker host
|
||||||
ws_client_protocol: wss:// #set the websocket protocol to be used by the client to connect to the rails server (ws on development, wss on production)
|
ws_client_protocol: wss:// #set the websocket protocol to be used by the client to connect to the rails server (ws on development, wss on production)
|
||||||
|
|
||||||
|
staging:
|
||||||
|
<<: *default
|
||||||
|
host: unix:///var/run/docker.sock
|
||||||
|
pool:
|
||||||
|
active: true
|
||||||
|
refill:
|
||||||
|
async: false
|
||||||
|
batch_size: 8
|
||||||
|
interval: 15
|
||||||
|
timeout: 60
|
||||||
|
workspace_root: <%= Rails.root.join('tmp', 'files', Rails.env) %>
|
||||||
|
ws_host: ws://localhost:4243 #url to connect rails server to docker host
|
||||||
|
ws_client_protocol: 'wss:' #set the websocket protocol to be used by the client to connect to the rails server (ws on development, wss on production)
|
||||||
|
|
||||||
test:
|
test:
|
||||||
<<: *default
|
<<: *default
|
||||||
host: tcp://192.168.59.104:2376
|
host: tcp://127.0.0.1:2376
|
||||||
workspace_root: <%= File.join('/', 'shared', Rails.env) %>
|
workspace_root: <%= File.join('/', 'shared', Rails.env) %>
|
||||||
|
@ -32,7 +32,7 @@ production:
|
|||||||
timeout: 60
|
timeout: 60
|
||||||
workspace_root: <%= Rails.root.join('tmp', 'files', Rails.env) %>
|
workspace_root: <%= Rails.root.join('tmp', 'files', Rails.env) %>
|
||||||
ws_host: ws://localhost:4243 #url to connect rails server to docker host
|
ws_host: ws://localhost:4243 #url to connect rails server to docker host
|
||||||
ws_client_protocol: 'wss:' #set the websocket protocol to be used by the client to connect to the rails server (ws on development, wss on production)
|
ws_client_protocol: wss:// #set the websocket protocol to be used by the client to connect to the rails server (ws on development, wss on production)
|
||||||
|
|
||||||
staging:
|
staging:
|
||||||
<<: *default
|
<<: *default
|
||||||
@ -50,5 +50,5 @@ staging:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
<<: *default
|
<<: *default
|
||||||
host: tcp://192.168.59.104:2376
|
host: tcp://127.0.0.1:2376
|
||||||
workspace_root: <%= File.join('/', 'shared', Rails.env) %>
|
workspace_root: <%= File.join('/', 'shared', Rails.env) %>
|
@ -35,6 +35,9 @@ Rails.application.configure do
|
|||||||
# yet still be able to expire them through the digest params.
|
# yet still be able to expire them through the digest params.
|
||||||
config.assets.digest = true
|
config.assets.digest = true
|
||||||
|
|
||||||
|
# Suppress logger output for asset requests.
|
||||||
|
config.assets.quiet = true
|
||||||
|
|
||||||
# Adds additional error checking when serving assets at runtime.
|
# Adds additional error checking when serving assets at runtime.
|
||||||
# Checks for improperly declared sprockets dependencies.
|
# Checks for improperly declared sprockets dependencies.
|
||||||
# Raises helpful error messages.
|
# Raises helpful error messages.
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddSubmissionToStructuredErrors < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_reference :structured_errors, :submission, index: true
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,15 @@
|
|||||||
|
class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :request_for_comments, :full_score_reached, :boolean, default: false
|
||||||
|
RequestForComment.find_each { |rfc|
|
||||||
|
if rfc.submission.present? and rfc.submission.exercise.has_user_solved(rfc.user)
|
||||||
|
rfc.full_score_reached = true
|
||||||
|
rfc.save
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :request_for_comments, :full_score_reached
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddTimesFeaturedToRequestForComments < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :request_for_comments, :times_featured, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
10
db/migrate/20180222145909_fix_timestamps_on_feedback.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class FixTimestampsOnFeedback < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
change_column_default(:user_exercise_feedbacks, :created_at, nil)
|
||||||
|
change_column_default(:user_exercise_feedbacks, :updated_at, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
27
db/schema.rb
@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20180226131340) do
|
ActiveRecord::Schema.define(version: 20180222145909) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@ -291,16 +291,18 @@ ActiveRecord::Schema.define(version: 20180226131340) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
create_table "request_for_comments", force: :cascade do |t|
|
create_table "request_for_comments", force: :cascade do |t|
|
||||||
t.integer "user_id", null: false
|
t.integer "user_id", null: false
|
||||||
t.integer "exercise_id", null: false
|
t.integer "exercise_id", null: false
|
||||||
t.integer "file_id", null: false
|
t.integer "file_id", null: false
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "user_type", limit: 255
|
t.string "user_type", limit: 255
|
||||||
t.text "question"
|
t.text "question"
|
||||||
t.boolean "solved", default: false
|
t.boolean "solved", default: false
|
||||||
t.integer "submission_id"
|
t.integer "submission_id"
|
||||||
t.text "thank_you_note"
|
t.text "thank_you_note"
|
||||||
|
t.boolean "full_score_reached", default: false
|
||||||
|
t.integer "times_featured", default: 0
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "searches", force: :cascade do |t|
|
create_table "searches", force: :cascade do |t|
|
||||||
@ -326,8 +328,11 @@ ActiveRecord::Schema.define(version: 20180226131340) do
|
|||||||
t.integer "file_id"
|
t.integer "file_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.integer "submission_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "structured_errors", ["submission_id"], name: "index_structured_errors_on_submission_id", using: :btree
|
||||||
|
|
||||||
create_table "submissions", force: :cascade do |t|
|
create_table "submissions", force: :cascade do |t|
|
||||||
t.integer "exercise_id"
|
t.integer "exercise_id"
|
||||||
t.float "score"
|
t.float "score"
|
||||||
@ -368,15 +373,15 @@ ActiveRecord::Schema.define(version: 20180226131340) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
create_table "user_exercise_feedbacks", force: :cascade do |t|
|
create_table "user_exercise_feedbacks", force: :cascade do |t|
|
||||||
t.integer "exercise_id", null: false
|
t.integer "exercise_id", null: false
|
||||||
t.integer "user_id", null: false
|
t.integer "user_id", null: false
|
||||||
t.string "user_type", null: false
|
t.string "user_type", null: false
|
||||||
t.integer "difficulty"
|
t.integer "difficulty"
|
||||||
t.integer "working_time_seconds"
|
t.integer "working_time_seconds"
|
||||||
t.string "feedback_text"
|
t.string "feedback_text"
|
||||||
t.integer "user_estimated_worktime"
|
t.integer "user_estimated_worktime"
|
||||||
t.datetime "created_at", default: '2017-11-20 18:20:25', null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", default: '2017-11-20 18:20:25', null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "user_exercise_interventions", force: :cascade do |t|
|
create_table "user_exercise_interventions", force: :cascade do |t|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
#flash-container {
|
||||||
|
position: relative;
|
||||||
|
top: -21px;
|
||||||
|
}
|
||||||
|
|
||||||
.flash {
|
.flash {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@ -10,14 +15,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fixed_error_messages {
|
.fixed_error_messages {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
top: 20px;
|
padding: inherit;
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-left: 10%;
|
|
||||||
padding-right: 10%;
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
14
provision.sh
@ -13,7 +13,7 @@ add-apt-repository ppa:chris-lea/node.js
|
|||||||
apt-get update
|
apt-get update
|
||||||
|
|
||||||
# code_ocean
|
# code_ocean
|
||||||
apt-get install -y postgresql-client postgresql-9.5 postgresql-server-dev-9.5 vagrant
|
apt-get install -y postgresql-client postgresql-10 postgresql-server-dev-10 vagrant
|
||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
if [ ! -f /etc/default/docker ]
|
if [ ! -f /etc/default/docker ]
|
||||||
@ -49,18 +49,18 @@ apt-get install -y libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
|
|||||||
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
|
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
|
||||||
curl -L https://get.rvm.io | bash -s stable
|
curl -L https://get.rvm.io | bash -s stable
|
||||||
source /etc/profile.d/rvm.sh
|
source /etc/profile.d/rvm.sh
|
||||||
rvm install 2.3.1
|
rvm install 2.3.6
|
||||||
rvm use 2.3.1 --default
|
rvm use 2.3.6 --default
|
||||||
ruby -v
|
ruby -v
|
||||||
|
|
||||||
# rails
|
# rails
|
||||||
apt-get -y install nodejs
|
apt-get -y install nodejs
|
||||||
gem install rails -v 4.2.1
|
gem install rails -v 4.2.10
|
||||||
|
|
||||||
# drop postgres access control
|
# drop postgres access control
|
||||||
if ! grep -q code_ocean /etc/postgresql/9.5/main/pg_hba.conf
|
if ! grep -q code_ocean /etc/postgresql/10/main/pg_hba.conf
|
||||||
then
|
then
|
||||||
cat >/etc/postgresql/9.3/main/pg_hba.conf <<EOF
|
cat >/etc/postgresql/10/main/pg_hba.conf <<EOF
|
||||||
# code_ocean: drop access control
|
# code_ocean: drop access control
|
||||||
local all all trust
|
local all all trust
|
||||||
host all all 127.0.0.1/32 trust
|
host all all 127.0.0.1/32 trust
|
||||||
@ -110,7 +110,7 @@ passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
|
|||||||
server {
|
server {
|
||||||
server_name codeocean.local;
|
server_name codeocean.local;
|
||||||
root /vagrant/public;
|
root /vagrant/public;
|
||||||
passenger_ruby /usr/local/rvm/gems/ruby-2.1.5/wrappers/ruby;
|
passenger_ruby /usr/local/rvm/gems/ruby-2.3.6/wrappers/ruby;
|
||||||
passenger_sticky_sessions on;
|
passenger_sticky_sessions on;
|
||||||
passenger_enabled on;
|
passenger_enabled on;
|
||||||
passenger_app_env development;
|
passenger_app_env development;
|
||||||
|
Before Width: | Height: | Size: 140 KiB |
@ -98,7 +98,7 @@ describe Lti do
|
|||||||
let(:consumer) { FactoryBot.create(:consumer) }
|
let(:consumer) { FactoryBot.create(:consumer) }
|
||||||
let(:score) { 0.5 }
|
let(:score) { 0.5 }
|
||||||
let(:submission) { FactoryBot.create(:submission) }
|
let(:submission) { FactoryBot.create(:submission) }
|
||||||
let!(:lti_parameter) { FactoryBot.create(:lti_parameter)}
|
let!(:lti_parameter) { FactoryBot.create(:lti_parameter, consumers_id: consumer.id, external_users_id: submission.user_id, exercises_id: submission.exercise_id)}
|
||||||
|
|
||||||
context 'with an invalid score' do
|
context 'with an invalid score' do
|
||||||
it 'raises an exception' do
|
it 'raises an exception' do
|
||||||
@ -114,7 +114,6 @@ describe Lti do
|
|||||||
|
|
||||||
context 'when grading is not supported' do
|
context 'when grading is not supported' do
|
||||||
it 'returns a corresponding status' do
|
it 'returns a corresponding status' do
|
||||||
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
||||||
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false)
|
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false)
|
||||||
expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('unsupported')
|
expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('unsupported')
|
||||||
end
|
end
|
||||||
@ -133,12 +132,10 @@ describe Lti do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'sends the score' do
|
it 'sends the score' do
|
||||||
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
||||||
controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns code, message, and status' do
|
it 'returns code, message, and status' do
|
||||||
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
||||||
result = controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
result = controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
||||||
expect(result[:code]).to eq(response.response_code)
|
expect(result[:code]).to eq(response.response_code)
|
||||||
expect(result[:message]).to eq(response.body)
|
expect(result[:message]).to eq(response.body)
|
||||||
|
@ -2,6 +2,7 @@ FactoryBot.define do
|
|||||||
factory :user_exercise_feedback, class: UserExerciseFeedback do
|
factory :user_exercise_feedback, class: UserExerciseFeedback do
|
||||||
created_by_external_user
|
created_by_external_user
|
||||||
feedback_text 'Most suitable exercise ever'
|
feedback_text 'Most suitable exercise ever'
|
||||||
|
association :exercise, factory: :math
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -2,12 +2,22 @@ require 'rails_helper'
|
|||||||
require 'seeds_helper'
|
require 'seeds_helper'
|
||||||
|
|
||||||
describe DockerClient, docker: true do
|
describe DockerClient, docker: true do
|
||||||
|
WORKSPACE_PATH = '/tmp/code_ocean_test'
|
||||||
|
|
||||||
let(:command) { 'whoami' }
|
let(:command) { 'whoami' }
|
||||||
let(:docker_client) { described_class.new(execution_environment: FactoryBot.build(:java), user: FactoryBot.build(:admin)) }
|
let(:docker_client) { described_class.new(execution_environment: FactoryBot.build(:java), user: FactoryBot.build(:admin)) }
|
||||||
let(:execution_environment) { FactoryBot.build(:java) }
|
let(:execution_environment) { FactoryBot.build(:java) }
|
||||||
let(:image) { double }
|
let(:image) { double }
|
||||||
let(:submission) { FactoryBot.create(:submission) }
|
let(:submission) { FactoryBot.create(:submission) }
|
||||||
let(:workspace_path) { '/tmp' }
|
let(:workspace_path) { WORKSPACE_PATH }
|
||||||
|
|
||||||
|
before(:all) do
|
||||||
|
FileUtils.mkdir_p(WORKSPACE_PATH)
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
FileUtils.rm_rf(WORKSPACE_PATH)
|
||||||
|
end
|
||||||
|
|
||||||
describe '.check_availability!' do
|
describe '.check_availability!' do
|
||||||
context 'when a socket error occurs' do
|
context 'when a socket error occurs' do
|
||||||
@ -129,7 +139,7 @@ describe DockerClient, docker: true do
|
|||||||
after(:each) { docker_client.send(:create_workspace_files, container, submission) }
|
after(:each) { docker_client.send(:create_workspace_files, container, submission) }
|
||||||
|
|
||||||
it 'creates submission-specific directories' do
|
it 'creates submission-specific directories' do
|
||||||
expect(Dir).to receive(:mkdir).at_least(:once)
|
expect(Dir).to receive(:mkdir).at_least(:once).and_call_original
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'copies binary files' do
|
it 'copies binary files' do
|
||||||
|
@ -16,13 +16,8 @@
|
|||||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||||
|
|
||||||
unless RUBY_PLATFORM == 'java'
|
unless RUBY_PLATFORM == 'java'
|
||||||
if ENV['CODECLIMATE_REPO_TOKEN']
|
|
||||||
require 'codeclimate-test-reporter'
|
|
||||||
CodeClimate::TestReporter.start
|
|
||||||
else
|
|
||||||
require 'simplecov'
|
require 'simplecov'
|
||||||
SimpleCov.start('rails')
|
SimpleCov.start('rails')
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :error_template_attribute do
|
factory :error_template_attribute do
|
||||||
error_template nil
|
|
||||||
key "MyString"
|
key "MyString"
|
||||||
regex "MyString"
|
regex "MyString"
|
||||||
end
|
end
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |