|
|
|
|
# encoding: utf-8
|
|
|
|
|
class MyshixunsController < ApplicationController
|
|
|
|
|
layout 'base_myshixun'
|
|
|
|
|
skip_before_filter :verify_authenticity_token, :only => [:training_task_status, :close_webssh, :code_runinng_message]
|
|
|
|
|
before_filter :require_login, :except => [:training_task_status, :close_webssh, :code_runinng_message]
|
|
|
|
|
before_filter :check_authentication, :except => [:training_task_status, :close_webssh, :mul_test_home, :mul_test_user,
|
|
|
|
|
:mul_test_myshixun, :mul_test_shixun, :mul_test_start, :code_runinng_message]
|
|
|
|
|
before_filter :find_myshixun, :only => [:show, :myshixun_reset, :open_webssh, :sync_reset_time, :destroy, :search_file_list, :vnc]
|
|
|
|
|
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
|
|
|
|
|
|
|
|
|
include ApplicationHelper
|
|
|
|
|
|
|
|
|
|
def forbidden
|
|
|
|
|
render_403
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def not_found
|
|
|
|
|
render_404
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def search_file_list
|
|
|
|
|
path = params[:path]
|
|
|
|
|
@path = to_path_param(path)
|
|
|
|
|
g = Gitlab.client
|
|
|
|
|
@dir = g.trees(@myshixun.gpid, :path => @path).map{|tree|[tree.type, (@path.blank? ? tree.name : "#{@path}"+"/"+tree.name )]}
|
|
|
|
|
logger.info("dir is ##{@dir}")
|
|
|
|
|
@page = (params['page'] || 1).to_i
|
|
|
|
|
@dir_count = @dir.count
|
|
|
|
|
@limit = 5
|
|
|
|
|
@is_remote = true
|
|
|
|
|
@dir_pages = Paginator.new @dir_count, @limit, params['page'] || 1
|
|
|
|
|
@offset ||= @dir_pages.offset
|
|
|
|
|
@dir = paginateHelper @dir, @limit
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 并发测试:主页
|
|
|
|
|
# http://localhost:3000/myshixuns/mul_test_home?num=5
|
|
|
|
|
def mul_test_home
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
uri = Setting.protocol + "://" + Setting.host_name
|
|
|
|
|
num.times do
|
|
|
|
|
Thread.new{get_url_exec(uri)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 并发测试:个人主页
|
|
|
|
|
def mul_test_user
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
login = params[:login]
|
|
|
|
|
uri = Setting.protocol + "://" + Setting.host_name + "/users/#{login}"
|
|
|
|
|
num.times do
|
|
|
|
|
Thread.new{get_url_exec(uri)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
#并发测试:tpi
|
|
|
|
|
def mul_test_myshixun
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
identifier = params[:identifier]
|
|
|
|
|
uri = Setting.protocol + "://" + Setting.host_name + "/tasks/#{identifier}"
|
|
|
|
|
num.times do
|
|
|
|
|
Thread.new{get_url_exec(uri)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
#并发测试:tpm
|
|
|
|
|
def mul_test_shixun
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
identifier = params[:identifier]
|
|
|
|
|
uri = Setting.protocol + "://" + Setting.host_name + "/shixuns/#{identifier}"
|
|
|
|
|
num.times do
|
|
|
|
|
Thread.new{get_url_exec(uri)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 并发测试
|
|
|
|
|
# num为进程数
|
|
|
|
|
# 分三种JAVA/PYTHON/C++
|
|
|
|
|
# 方式模拟请求
|
|
|
|
|
# 实训ID: p - 122,178,120; J - 571,895,50; c++ - 101,70,118
|
|
|
|
|
# http://localhost:3000/myshixuns/mul_test?shixun_id=122,178,120&num=10
|
|
|
|
|
def mul_test
|
|
|
|
|
unless User.current.admin?
|
|
|
|
|
render_403
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
codes = %W(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
|
|
|
|
|
begin
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
@myshixuns = Myshixun.where(:shixun_id => params[:shixun_id].split(",")).first(num)
|
|
|
|
|
logger.warn("###1mul test game_build start : myshixuns count is #{@myshixuns.count}")
|
|
|
|
|
@myshixuns.each do |myshixun|
|
|
|
|
|
game = myshixun.games.last
|
|
|
|
|
logger.warn("###2mul test game_build start ")
|
|
|
|
|
identifier = game.try(:identifier)
|
|
|
|
|
if game.status == 2
|
|
|
|
|
code = codes.sample(8).join
|
|
|
|
|
resubmit = "#{code}_#{myshixun.id}"
|
|
|
|
|
end
|
|
|
|
|
logger.warn("###3mul test game_build start ...")
|
|
|
|
|
uri = Setting.protocol + "://" + Setting.host_name + "/api/v1/games/#{identifier}/game_build?resubmit=#{resubmit}&content_modified=0&first=1"
|
|
|
|
|
Thread.new{get_url_exec(uri)}
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error("mul test failed ===> #{e.message}")
|
|
|
|
|
end
|
|
|
|
|
render :json => {:status => "start"}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 最新可以用的并发测试接口
|
|
|
|
|
def sigle_mul_test
|
|
|
|
|
|
|
|
|
|
codes = %W(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
|
|
|
|
|
begin
|
|
|
|
|
identifiers = Myshixun.where(:shixun_id => params[:shixun_id].split(",")).pluck(:identifier)
|
|
|
|
|
ide = identifiers[rand(identifiers.length)]
|
|
|
|
|
myshixun = Myshixun.where(:identifier => ide).first
|
|
|
|
|
|
|
|
|
|
game = myshixun.games.last
|
|
|
|
|
logger.warn("###2mul test game_build start ")
|
|
|
|
|
identifier = game.try(:identifier)
|
|
|
|
|
if game.status == 2
|
|
|
|
|
code = codes.sample(8).join
|
|
|
|
|
resubmit = "#{code}_#{myshixun.id}"
|
|
|
|
|
end
|
|
|
|
|
logger.warn("###3mul test game_build start ...")
|
|
|
|
|
EvaluateRecord.create!(:user_id => myshixun.user_id, :shixun_id => myshixun.shixun.id, :game_id => game.id)
|
|
|
|
|
redirect_to "/api/v1/games/#{identifier}/game_build?resubmit=#{resubmit}&content_modified=0&first=1"
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error("mul test failed ===> #{e.message}")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 慎用,只能用于测试版
|
|
|
|
|
def sigle_update_myshixun
|
|
|
|
|
shixun = Shixun.find_by_identifier(params[:shixun_id])
|
|
|
|
|
user = User.find(rand(50000))
|
|
|
|
|
code = down_generate_identifier("myshixun")
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
begin
|
|
|
|
|
Myshixun.create!(:shixun_id => shixun.id, :user_id => user.id, :identifier => code, :modify_time => shixun.modify_time,
|
|
|
|
|
:reset_time => shixun.reset_time, :onclick_time => Time.now, :gpid => -1,
|
|
|
|
|
:git_url => "", :commit_id => "123123")
|
|
|
|
|
render :json => {:status => 200}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error("sigle test #{e.message}")
|
|
|
|
|
render :json => {:error => "#{e}"}
|
|
|
|
|
raise ActiveRecord::Rollback
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 开启实训
|
|
|
|
|
def mul_test_start
|
|
|
|
|
unless User.current.admin?
|
|
|
|
|
render_403
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
num = params[:num].to_i
|
|
|
|
|
shixuns = params[:shixun_identifier].split(",")
|
|
|
|
|
|
|
|
|
|
num.times do |n|
|
|
|
|
|
lastnames = []
|
|
|
|
|
100.times do |n|
|
|
|
|
|
lastnames << "educoder#{sprintf("%04d", n)}"
|
|
|
|
|
end
|
|
|
|
|
lastname = lastnames[rand(lastnames.count)]
|
|
|
|
|
shixun = Shixun.where(:identifier => shixuns[rand(shixuns.count)]).first
|
|
|
|
|
current_user = User.where(:lastname => lastname).first
|
|
|
|
|
Thread.new{start_shixun(shixun, current_user)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def start_shixun shixun, current_user
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
begin
|
|
|
|
|
# fork版本库,如果用户没有同步,则先同步用户
|
|
|
|
|
g = Gitlab.client
|
|
|
|
|
if current_user.gid.nil?
|
|
|
|
|
s = Trustie::Gitlab::Sync.new
|
|
|
|
|
s.sync_user(current_user)
|
|
|
|
|
end
|
|
|
|
|
gshixun = g.fork(shixun.gpid, current_user.gid)
|
|
|
|
|
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
code = down_generate_identifier("myshixun")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 一般通过默认分支是否存在来判断一个项目是否fork成功
|
|
|
|
|
if gshixun.try(:id).present?
|
|
|
|
|
commit_id = g.commits(shixun.gpid).first.try(:id)
|
|
|
|
|
# educoder 加入到myshixun中
|
|
|
|
|
myshixun_admin_gid = User.where(:login => "educoder").first.try(:gid)
|
|
|
|
|
g.add_team_member(gshixun.id, myshixun_admin_gid, 40) # 40代表角色master
|
|
|
|
|
|
|
|
|
|
myshixun = Myshixun.create!(:shixun_id => shixun.id, :user_id => current_user.id, :identifier => code, :modify_time => @shixun.modify_time,
|
|
|
|
|
:reset_time => shixun.reset_time, :onclick_time => Time.now, :gpid => gshixun.id,
|
|
|
|
|
:git_url => gshixun.try(:path_with_namespace), :commit_id => commit_id)
|
|
|
|
|
|
|
|
|
|
# tpm 不需要目录的
|
|
|
|
|
# rep = Repository.create!(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
|
|
|
|
|
# rep.update_column(:type, "Repository::Gitlab")
|
|
|
|
|
rep_url = Base64.urlsafe_encode64(gitlab_url shixun) # 注意:educoder为默认给实训创建版本库的用户,如果换成别的用户,名字要相应的修改
|
|
|
|
|
|
|
|
|
|
logger.info("start openGameInstance")
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
|
|
|
|
|
logger.info("end openGameInstance")
|
|
|
|
|
params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: gshixun.try(:name)}
|
|
|
|
|
logger.info("openGameInstance params is #{params}")
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'].to_i != 0)
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:83)")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 其它创建关卡等操作
|
|
|
|
|
challenges = shixun.challenges
|
|
|
|
|
# 之所以增加user_id是为了方便统计查询性能
|
|
|
|
|
challenges.each_with_index do |challenge, index|
|
|
|
|
|
status = (index == 0 ? 0 : 3)
|
|
|
|
|
code = down_generate_identifier("game")
|
|
|
|
|
Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id,
|
|
|
|
|
:open_time => Time.now, :identifier => code, :modify_time => challenge.modify_time)
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:81)")
|
|
|
|
|
end
|
|
|
|
|
# unlock
|
|
|
|
|
logger.info("myshixun id is #{myshixun.try(:identifier)} and current_task id is#{myshixun.try(:current_task).try(:id)}")
|
|
|
|
|
# 开启实训时更新关联作品的状态
|
|
|
|
|
update_myshixun_work_status myshixun
|
|
|
|
|
render :json => {:status => 1}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
if e.message == "shixun error"
|
|
|
|
|
flash[:error] = "正在后台执行,请稍后重试"
|
|
|
|
|
elsif e.message.include?("Mysql2::Error")
|
|
|
|
|
flash[:error] = "正在后台执行,请稍后重试"
|
|
|
|
|
else
|
|
|
|
|
flash[:error] = e.message
|
|
|
|
|
end
|
|
|
|
|
logger.info("failed to exec shixun: current task id is #{e}")
|
|
|
|
|
g.delete_project(gshixun.id) if gshixun.try(:id).present?
|
|
|
|
|
render :json => {:status => -1}
|
|
|
|
|
raise ActiveRecord::Rollback
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def down_generate_identifier type
|
|
|
|
|
if type == "game"
|
|
|
|
|
code = DCODES.sample(12).join
|
|
|
|
|
return down_generate_identifier(type) if Game.where(identifier: code).present?
|
|
|
|
|
elsif type == "myshixun"
|
|
|
|
|
code = DCODES.sample(10).join
|
|
|
|
|
return down_generate_identifier(type) if Myshixun.where(identifier: code).present?
|
|
|
|
|
end
|
|
|
|
|
code
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def game_build myshixun_id, game_id, gitUrl, step, language, mul_test, testcases, podtype, tpmScript, mirror_repositories, time_limit, file, port
|
|
|
|
|
logger.info("############### game_build")
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
# 注意:这个地方的参数写的时候不能换行
|
|
|
|
|
params = {:tpiID => "#{myshixun_id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{game_id}",:instanceChallenge => "#{step}",
|
|
|
|
|
:testCases => "#{testcases}", :resubmit => "", :times => 1, :podType => podtype,
|
|
|
|
|
:containers => "#{Base64.urlsafe_encode64(container_limit(mirror_repositories))}", :tpmScript => "#{tpmScript}",
|
|
|
|
|
:timeLimit => "#{time_limit}", :file => "#{file}", :needPortMapping => "#{port}"}
|
|
|
|
|
logger.info("############### start gameEvaluate")
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/gameEvaluate"
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
logger.info("############### end gameEvaluate")
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
@message = "实训云平台繁忙(繁忙等级:86)"
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:86)")
|
|
|
|
|
mul_test.update_attributes(:time => (Time.now - mul_test.updated_at), :status => 3)
|
|
|
|
|
else
|
|
|
|
|
mul_test.update_attribute(:time, res['costTime'].to_i)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 临时使用
|
|
|
|
|
def destroy
|
|
|
|
|
if User.current.admin?
|
|
|
|
|
user = @myshixun.owner
|
|
|
|
|
@myshixun.games.each do |game|
|
|
|
|
|
ex =Experience.where(:container_type => "Game", :container_id => game.id).first
|
|
|
|
|
ex.destroy if ex.present?
|
|
|
|
|
gr = Grade.where(:container_type => "Game", :container_id => game.id).first
|
|
|
|
|
gr.destroy if gr.present?
|
|
|
|
|
grade = user.try(:grade).to_i - game.try(:final_score).to_i
|
|
|
|
|
grade = grade > 0 ? grade : 0
|
|
|
|
|
user.update_column(:grade, grade)
|
|
|
|
|
end
|
|
|
|
|
@myshixun.destroy
|
|
|
|
|
# 删除积分和经验值
|
|
|
|
|
#g = Gitlab.client
|
|
|
|
|
#g.delete_project(@myshixun.gpid) if @myshixun.gpid.present?
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def sync_reset_time
|
|
|
|
|
@myshixun.update_column(:modify_time, @myshixun.shixun.try(:modify_time))
|
|
|
|
|
render :json => {:data => "success"}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 将代码重置到开启状态
|
|
|
|
|
# 方法:使用文件更新,非Git重置
|
|
|
|
|
def code_reset
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def code_reset_success
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 连接webssh
|
|
|
|
|
def open_webssh
|
|
|
|
|
username = Redmine::Configuration['webssh_username']
|
|
|
|
|
password = Redmine::Configuration['webssh_password']
|
|
|
|
|
old_time = Time.now.to_i
|
|
|
|
|
begin
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo"
|
|
|
|
|
user_id = User.current.id
|
|
|
|
|
params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), containers:(Base64.urlsafe_encode64(container_limit @myshixun.shixun.mirror_repositories))}
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if res && res['code'].to_i != 0
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:92)")
|
|
|
|
|
end
|
|
|
|
|
render :json => {:host => res['address'],
|
|
|
|
|
:port => res['port'],
|
|
|
|
|
:ws_url => res['ws_address'],
|
|
|
|
|
:username => username,
|
|
|
|
|
:password => password,
|
|
|
|
|
:game_id => @myshixun.id,
|
|
|
|
|
:webssh_url => Redmine::Configuration['tomcat_webssh']}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error(e)
|
|
|
|
|
render :json => {:error => e.try(:message)}
|
|
|
|
|
# @message = e.try(:message)
|
|
|
|
|
ensure
|
|
|
|
|
use_time = Time.now.to_i - old_time
|
|
|
|
|
logger.info "open_webssh tpiID #{@myshixun.id} use time #{use_time}"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def vnc
|
|
|
|
|
vnc_password = Redmine::Configuration['vnc']
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
host = Redmine::Configuration['tomcat_php']
|
|
|
|
|
begin
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/vnc/getvnc"
|
|
|
|
|
params = {tpiID:@myshixun.id}
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if res && res['code'].to_i != 0
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:99)")
|
|
|
|
|
end
|
|
|
|
|
# url = host + ":" + res['port'] + "?password=" + vnc_password
|
|
|
|
|
url = host +":#{res['port']}/vnc.html"
|
|
|
|
|
render :json => {:url => url}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error(e)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 断开webssh连接
|
|
|
|
|
def close_webssh
|
|
|
|
|
username = Redmine::Configuration['webssh_username']
|
|
|
|
|
password = Redmine::Configuration['webssh_password']
|
|
|
|
|
begin
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/webssh/deleteSSH"
|
|
|
|
|
user_id = User.current.id
|
|
|
|
|
logger.info("#############################")
|
|
|
|
|
logger.info("game_id:" + @_params[:id])
|
|
|
|
|
params = {tpiID:@_params[:id]} # @_params[:id] 是webssh传过来的gameId
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if res && res['code'].to_i != 0
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:93)")
|
|
|
|
|
end
|
|
|
|
|
render :jsonp => {:host => res['address'], :port => res['port'], :username => username, :password => password}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error(e)
|
|
|
|
|
@message = e.try(:message)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 实训重置只更新脚本
|
|
|
|
|
def myshixun_reset
|
|
|
|
|
shixun = @myshixun.shixun
|
|
|
|
|
# ActiveRecord::Base.transaction do
|
|
|
|
|
begin
|
|
|
|
|
g = Gitlab.client
|
|
|
|
|
# shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
# @challenges = shixun.challenges
|
|
|
|
|
# # 删除选择题用户记录
|
|
|
|
|
# unless @challenges.blank?
|
|
|
|
|
# @challenges.each do |challenge|
|
|
|
|
|
# if challenge.st != 0
|
|
|
|
|
# challenge.challenge_chooses.each do |choose|
|
|
|
|
|
# user_output = choose.choose_outputs
|
|
|
|
|
# unless user_output.blank?
|
|
|
|
|
# user_output.delete
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
#end
|
|
|
|
|
StudentWork.where(:myshixun_id => @myshixun.id).update_all(:myshixun_id => nil, :work_status => 0)
|
|
|
|
|
|
|
|
|
|
# 数据不关联删除,以后的数据可能要做行为分析
|
|
|
|
|
# @myshixun.destroy
|
|
|
|
|
@myshixun.delete
|
|
|
|
|
# 主从复制出现脏读的情况
|
|
|
|
|
if @myshixun.gpid
|
|
|
|
|
g.delete_project(@myshixun.gpid)
|
|
|
|
|
end
|
|
|
|
|
sleep(1)
|
|
|
|
|
redirect_to shixun_exec_shixun_path(shixun, :type => 1, :is_subject => params[:is_subject])
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
flash[:error] = "实训云平台繁忙(繁忙等级:89)"
|
|
|
|
|
redirect_to shixun_challenges_path(@shixun)
|
|
|
|
|
logger.error("myshixun reset failed #{e}")
|
|
|
|
|
# raise ActiveRecord::Rollback
|
|
|
|
|
end
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 代码运行中的信息接口
|
|
|
|
|
def code_runinng_message
|
|
|
|
|
begin
|
|
|
|
|
logger.info("######################params: #{params}")
|
|
|
|
|
jsonTestDetails = JSON.parse(params[:jsonTestDetails])
|
|
|
|
|
game_id = jsonTestDetails['buildID']
|
|
|
|
|
message = jsonTestDetails['textMsg']
|
|
|
|
|
logger.info("##################code_runinng_message:#{jsonTestDetails}")
|
|
|
|
|
logger.info("##################buildID: #{game_id}")
|
|
|
|
|
logger.info("##################textMsg: #{message}")
|
|
|
|
|
if game_id.present? && message.present?
|
|
|
|
|
game = Game.find game_id
|
|
|
|
|
msg = game.run_code_message
|
|
|
|
|
# 只有评测中的game才会创建和更新代码评测中的信息
|
|
|
|
|
logger.info("##################game: #{game.status}")
|
|
|
|
|
logger.info("##################retry_status: #{game.retry_status}")
|
|
|
|
|
if game.status == 1 || game.status == 2
|
|
|
|
|
if msg.blank?
|
|
|
|
|
RunCodeMessage.create!(:game_id => game_id, :status => 1, :message => message)
|
|
|
|
|
else
|
|
|
|
|
msg.update_attributes(:status => (msg.status + 1), :message => message)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
render :json => {:data => "success"}
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
render :json => {:data => "failed, exception_message: #{e}"}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# taskId 即返回的game id
|
|
|
|
|
# 返回结果:params [:stauts] 0 表示运行结果成功,其它则失败
|
|
|
|
|
# compile_success 1 表示成功; 0表示编译失败; -1 表示创建pod失败; -2 表示克隆代码失败
|
|
|
|
|
# msg 错误信息
|
|
|
|
|
# output 为测试用户编译输出结果
|
|
|
|
|
# myshixun:status 1为完成实训
|
|
|
|
|
# @jenkins: caseId对应test_set的position,passed: 1表示成功,0表示失败
|
|
|
|
|
# resubmit 1:表示已通关后重新评测;0:表示非重新评测
|
|
|
|
|
# retry_status 0:初始值;1:重新评测失败;2:重新评测成功
|
|
|
|
|
# tpiRepoPath 中间层图片的workspace路径
|
|
|
|
|
# params[:jsonTestDetails] = '{"buildID":"19284","compileSuccess":"1","createPodStatus": "1", "downloadStatus": "1",
|
|
|
|
|
# "msg":[{"caseId":"1","expectedOutput":"MSAyIDMNCg","input":"MiAzIDE","output":"MSAyIDMNCg","passed":"1"},
|
|
|
|
|
# {"caseId":"2","expectedOutput":"LTMgMSA2DQo","input":"LTMgNiAx","output":"LTMgMSA2DQo","passed":"1"},
|
|
|
|
|
# {"caseId":"3","expectedOutput":"LTcgLTUgLTMNCg","input":"LTcgLTMgLTU","output":"LTcgLTUgLTMNCg","passed":"1"}],
|
|
|
|
|
# "outPut":"Y29tcGlsZSBzdWNjZXNzZnVsbHk","resubmit":"","status":"0"}'
|
|
|
|
|
# params[:timeCost] = '{"evaluateEnd":"2017-11-24 11:04:37","pull":"0.086",
|
|
|
|
|
# "createPod":"1.610","evaluateAllTime":2820,"evaluateStart":"2017-11-24 11:04:35","execute":"0.294"}'
|
|
|
|
|
# params[:pics] = "a.png,b.png,c.png"
|
|
|
|
|
def training_task_status
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
begin
|
|
|
|
|
t1 = Time.now
|
|
|
|
|
jsonTestDetails = JSON.parse(params[:jsonTestDetails])
|
|
|
|
|
timeCost = JSON.parse(params[:timeCost])
|
|
|
|
|
brige_end_time = Time.parse(timeCost['evaluateEnd']) if timeCost['evaluateEnd'].present?
|
|
|
|
|
return_back_time = format("%.3f", ( t1.to_f - brige_end_time.to_f)).to_f
|
|
|
|
|
status = jsonTestDetails['status']
|
|
|
|
|
game_id = jsonTestDetails['buildID']
|
|
|
|
|
sec_key = jsonTestDetails['sec_key']
|
|
|
|
|
logger.info("training_task_status start#1**#{game_id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
resubmit = jsonTestDetails['resubmit']
|
|
|
|
|
outPut = tran_base64_decode64(jsonTestDetails['outPut'])
|
|
|
|
|
jenkins_testsets = jsonTestDetails['msg']
|
|
|
|
|
compile_success = jsonTestDetails['compileSuccess']
|
|
|
|
|
# # 创建pod的状态 0 失败 1 成功
|
|
|
|
|
# create_pod_status = jsonTestDetails['createPodStatus']
|
|
|
|
|
# # 克隆代码的装填 0 失败 1 成功
|
|
|
|
|
# clone_code_status = jsonTestDetails['downloadStatus']
|
|
|
|
|
# # 1表示编译成功;0 表示运行异常; -1 表示克隆代码失败; -2 表示创建pod失败
|
|
|
|
|
# compile_success = if clone_code_status == "0"
|
|
|
|
|
# -1
|
|
|
|
|
# elsif create_pod_status == "0"
|
|
|
|
|
# -2
|
|
|
|
|
# else
|
|
|
|
|
# jsonTestDetails['compileSuccess']
|
|
|
|
|
# end
|
|
|
|
|
# message = Base64.decode64(params[:msg]) unless params[:msg].blank?
|
|
|
|
|
logger.info(outPut)
|
|
|
|
|
game = Game.find(game_id)
|
|
|
|
|
myshixun = game.myshixun
|
|
|
|
|
challenge = game.challenge
|
|
|
|
|
# test_sets = challenge.test_sets
|
|
|
|
|
if challenge.picture_path.present?
|
|
|
|
|
#pics = params[:files]
|
|
|
|
|
pics = params[:tpiRepoPath]
|
|
|
|
|
game.update_column(:picture_path, pics)
|
|
|
|
|
end
|
|
|
|
|
logger.info("training_task_status start#2**#{game_id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
unless jenkins_testsets.blank?
|
|
|
|
|
jenkins_testsets.each_with_index do |j_test_set, i|
|
|
|
|
|
logger.info("j_test_set: ############## #{j_test_set}")
|
|
|
|
|
actual_output = tran_base64_decode64(j_test_set['output'])
|
|
|
|
|
# is_public = test_sets.where(:position => j_test_set['caseId']).first.try(:is_public)
|
|
|
|
|
logger.info "actual_output:################################################# #{actual_output}"
|
|
|
|
|
Output.create!(:code => status, :game_id => game_id, :out_put => outPut, :test_set_position => j_test_set['caseId'],
|
|
|
|
|
:actual_output => actual_output, :result => j_test_set['passed'].to_i, :query_index => game.query_index,
|
|
|
|
|
:compile_success => compile_success.to_i)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
logger.info("#############status: #{status}")
|
|
|
|
|
logger.info("#############resubmit: #{resubmit}")
|
|
|
|
|
logger.info("sec_key is#############resubmit: #{sec_key}")
|
|
|
|
|
record = EvaluateRecord.where(:identifier => sec_key).first
|
|
|
|
|
logger.info("training_task_status start#3**#{game_id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
|
|
|
|
|
# status:0表示评测成功
|
|
|
|
|
if status == "0"
|
|
|
|
|
if !resubmit.blank?
|
|
|
|
|
game.update_attributes!(:retry_status => 2, :resubmit_identifier => resubmit)
|
|
|
|
|
#if game.had_done == 1
|
|
|
|
|
challenge.path.split(";").each do |path|
|
|
|
|
|
game_passed_code(game.id, path.try(:strip), myshixun.try(:gpid), 1)
|
|
|
|
|
end
|
|
|
|
|
#end
|
|
|
|
|
else
|
|
|
|
|
game.update_attributes!(:status => 2, :end_time => Time.now, :accuracy => format("%.4f", 1.0 / game.query_index))
|
|
|
|
|
myshixun.update_attributes!(:status => 1) if game.had_done == 1
|
|
|
|
|
challenge.path.split(";").each do |path|
|
|
|
|
|
game_passed_code(game.id, path, myshixun.try(:gpid), 1)
|
|
|
|
|
end
|
|
|
|
|
if game.answer_open == 0 && (challenge.shixun.try(:status) > 1) # 如果没有查看答案,则获得该关卡得分
|
|
|
|
|
reward_grade(game.user, game.id, 'Game', challenge.score)
|
|
|
|
|
reward_experience(game.user, game.id, 'Game', challenge.score)
|
|
|
|
|
game.update_attributes!(:final_score => challenge.score)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 更新实训关联的作品分数
|
|
|
|
|
update_myshixun_work_score myshixun
|
|
|
|
|
end
|
|
|
|
|
# 如果过关了,下一关的状态是3(为开启),则需要把状态改成1(已开启)
|
|
|
|
|
# next_game = game.next_game
|
|
|
|
|
next_game = Game.next_game(myshixun.shixun_id, game.myshixun_id, challenge.position)
|
|
|
|
|
next_game.update_column(:status, 0) if next_game.present? && next_game.status == 3
|
|
|
|
|
else # status == "-1" 表示返回结果错误
|
|
|
|
|
if !resubmit.blank?
|
|
|
|
|
game.update_attributes!(:retry_status => 1, :resubmit_identifier => resubmit)
|
|
|
|
|
else
|
|
|
|
|
game.update_attributes!(:status => 0)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
test_cases_time = format("%.3f", (Time.now.to_f - t1.to_f)).to_f
|
|
|
|
|
if record.present?
|
|
|
|
|
consume_time = format("%.3f", (Time.now - record.created_at)).to_f
|
|
|
|
|
record.update_attributes!(:consume_time => consume_time, :git_pull => timeCost['pull'] ,
|
|
|
|
|
:create_pod => timeCost['createPod'], :pod_execute => timeCost['execute'], :test_cases => test_cases_time,
|
|
|
|
|
:brige => timeCost['evaluateAllTime'], :return_back => return_back_time)
|
|
|
|
|
end
|
|
|
|
|
logger.info("training_task_status start#4**#{game_id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
render :json => {:data => "success"}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
render :json => {:data => "failed, errer_message:#{e}"}
|
|
|
|
|
logger.error("training_task_status error: #{e}")
|
|
|
|
|
raise ActiveRecord::Rollback
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def show
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.html{redirect_to myshixun_game_path(@myshixun.current_task, :myshixun_id => @myshixun)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
# Find myshixun of id params[:id]
|
|
|
|
|
def find_myshixun
|
|
|
|
|
@myshixun = Myshixun.find_by_identifier(params[:id])
|
|
|
|
|
render_404 unless @myshixun.present?
|
|
|
|
|
end
|
|
|
|
|
end
|