{"action":"created","comment":{"url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/comments/45366137","id":45366137,"diff_hunk":"@@ -480,6 +486,261 @@ def parse_test_output(repo_assignment_dir, assignment, logfile, data)\n     # Return parsed (or unparsed) test output\n     output\n   end\n+\n+  def self.request_a_test_run(grouping_id, call_on, current_user)\n+    @current_user = current_user\n+    #@submission = Submission.find(submission_id)\n+    @grouping = Grouping.find(grouping_id)\n+    @assignment = @grouping.assignment\n+    @group = @grouping.group\n+\n+    @repo_dir = File.join(MarkusConfigurator.markus_config_automated_tests_repository, @group.repo_name)\n+    export_group_repo(@group, @repo_dir)\n+\n+    @list_run_scripts = scripts_to_run(@assignment, call_on)\n+\n+    async_test_request(grouping_id, call_on)\n+  end\n+\n+\n+  # Export group repository for testing. Students' submitted files\n+  # are stored in the group svn repository. They must be exported\n+  # before copying to the test server.\n+  def self.export_group_repo(group, repo_dir)\n+    # Create the automated test repository\n+    unless File.exists?(MarkusConfigurator.markus_config_automated_tests_repository)\n+      FileUtils.mkdir(MarkusConfigurator.markus_config_automated_tests_repository)\n+    end\n+\n+    # Delete student's assignment repository if it already exists\n+    delete_repo(repo_dir)\n+\n+    # export\n+    return group.repo.export(repo_dir)\n+  end\n+\n+  # Delete student's assignment repository if it already exists\n+  def self.delete_repo(repo_dir)\n+    if File.exists?(repo_dir)\n+      FileUtils.rm_rf(repo_dir)\n+    end\n+  end\n+\n+\n+  # Find the list of test scripts to run the test. Return the list of\n+  # test scripts in the order specified by seq_num (running order)\n+  def self.scripts_to_run(assignment, call_on)\n+    # Find all the test scripts of the current assignment\n+    all_scripts = TestScript.where(assignment_id: assignment.id)\n+\n+    list_run_scripts = Array.new\n+\n+    # If the test run is requested at collection (by Admin or TA),\n+    # All of the test scripts should be run.\n+    if call_on == 'collection'\n+      list_run_scripts = all_scripts\n+    else\n+      # If the test run is requested at submission or upon request,\n+      # verify the script is allowed to run.\n+      all_scripts.each do |script|\n+        if call_on == 'submission' && script.run_on_submission\n+          list_run_scripts.insert(list_run_scripts.length, script)\n+        elsif call_on == 'request' && script.run_on_request\n+          list_run_scripts.insert(list_run_scripts.length, script)\n+        end\n+      end\n+    end\n+\n+    # sort list_run_scripts using ruby's in place sorting method\n+    list_run_scripts.sort_by! &:seq_num\n+    list_run_scripts\n+  end\n+\n+  # Request an automated test. Ask Resque to enqueue a job.\n+  def self.async_test_request(grouping_id, call_on)\n+    if files_available? &&\n+      Resque.enqueue(AutomatedTestsHelper, grouping_id, call_on)\n+    end\n+  end\n+\n+","path":"app/helpers/automated_tests_helper.rb","position":93,"original_position":93,"commit_id":"919f55f05e09ad0ee3482f71aa02b2250ac56c44","original_commit_id":"919f55f05e09ad0ee3482f71aa02b2250ac56c44","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Extra blank line detected.","created_at":"2015-11-19T16:46:05Z","updated_at":"2015-11-19T16:46:05Z","html_url":"https://github.com/MarkUsProject/Markus/pull/2348#discussion_r45366137","pull_request_url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348","_links":{"self":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/comments/45366137"},"html":{"href":"https://github.com/MarkUsProject/Markus/pull/2348#discussion_r45366137"},"pull_request":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348"}}},"pull_request":{"url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348","id":50222020,"html_url":"https://github.com/MarkUsProject/Markus/pull/2348","diff_url":"https://github.com/MarkUsProject/Markus/pull/2348.diff","patch_url":"https://github.com/MarkUsProject/Markus/pull/2348.patch","issue_url":"https://api.github.com/repos/MarkUsProject/Markus/issues/2348","number":2348,"state":"open","locked":false,"title":"Test framework student test run","user":{"login":"jeremygoh","id":4348811,"avatar_url":"https://avatars.githubusercontent.com/u/4348811?v=3","gravatar_id":"","url":"https://api.github.com/users/jeremygoh","html_url":"https://github.com/jeremygoh","followers_url":"https://api.github.com/users/jeremygoh/followers","following_url":"https://api.github.com/users/jeremygoh/following{/other_user}","gists_url":"https://api.github.com/users/jeremygoh/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremygoh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremygoh/subscriptions","organizations_url":"https://api.github.com/users/jeremygoh/orgs","repos_url":"https://api.github.com/users/jeremygoh/repos","events_url":"https://api.github.com/users/jeremygoh/events{/privacy}","received_events_url":"https://api.github.com/users/jeremygoh/received_events","type":"User","site_admin":false},"body":"Work in progress. This is a fairly big and verbose PR - it's mostly for visibility @david-yz-liu @reidka  into what I've been working on recently. As you'll see from the below description, there is a significant amount to be fixed. On the bright side, I was able to get a test to run and save + display its results (after a page refresh - the js is broken).\r\n\r\n\r\nWork done\r\n- re-worked a lot of the test helper code. \r\n- lots of debugging. Got rid of variables that did nothing, non-existent method calls that caused runtime errors etc\r\n- now able to execute a test script and save it\r\n\r\n\r\nOutstanding issues\r\n- there is a terrible hack on line `app/helpers/automated_tests_helper.rb` to get past the validation requiring a submission association for a test script result. There are lots of references and uses of submissions in the code it is never passed in. If this is an association we need (which I think it is), then this will need to be fixed - either in this PR or the next one\r\n\r\n- can't merge this automatically. I checked out test-framework branch and it currently doesn't work for file uploading, there's an error with calling testfiles.each ... where testfiles is nil. @WilsonChiang - is this a known issue. Once this is addressed, I'll merge test-framework here so that this PR can be automatically merged\r\n\r\n- names of test scripts uploaded are not being saved properly, should be of the form \"hello.rb\"\r\n\r\n- need to verify that options for test scripts such as \"run on request\" are being saved correctly (this can be looked into at the same time as the test scripts upload issue)\r\n\r\n- javascript for the display of test results after a student runs them is missing. I haven't yet dug into the extent of this problem.\r\n\r\n![test_results](https://cloud.githubusercontent.com/assets/4348811/11056622/a569534c-8738-11e5-825e-1c739135933f.png)\r\n![livepipe js is missing](https://cloud.githubusercontent.com/assets/4348811/11056620/a552ff84-8738-11e5-966a-32a4ac4365cf.jpg)\r\n![test script upload error](https://cloud.githubusercontent.com/assets/4348811/11056621/a55612fa-8738-11e5-964d-f6ae546658e9.jpg)\r\n","created_at":"2015-11-10T07:23:50Z","updated_at":"2015-11-19T16:46:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b64173085b9c3668e57493a15bb2494386c09bd7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348/commits","review_comments_url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348/comments","review_comment_url":"https://api.github.com/repos/MarkUsProject/Markus/pulls/comments{/number}","comments_url":"https://api.github.com/repos/MarkUsProject/Markus/issues/2348/comments","statuses_url":"https://api.github.com/repos/MarkUsProject/Markus/statuses/919f55f05e09ad0ee3482f71aa02b2250ac56c44","head":{"label":"jeremygoh:test-framework-student-test-run","ref":"test-framework-student-test-run","sha":"919f55f05e09ad0ee3482f71aa02b2250ac56c44","user":{"login":"jeremygoh","id":4348811,"avatar_url":"https://avatars.githubusercontent.com/u/4348811?v=3","gravatar_id":"","url":"https://api.github.com/users/jeremygoh","html_url":"https://github.com/jeremygoh","followers_url":"https://api.github.com/users/jeremygoh/followers","following_url":"https://api.github.com/users/jeremygoh/following{/other_user}","gists_url":"https://api.github.com/users/jeremygoh/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremygoh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremygoh/subscriptions","organizations_url":"https://api.github.com/users/jeremygoh/orgs","repos_url":"https://api.github.com/users/jeremygoh/repos","events_url":"https://api.github.com/users/jeremygoh/events{/privacy}","received_events_url":"https://api.github.com/users/jeremygoh/received_events","type":"User","site_admin":false},"repo":{"id":42196454,"name":"Markus","full_name":"jeremygoh/Markus","owner":{"login":"jeremygoh","id":4348811,"avatar_url":"https://avatars.githubusercontent.com/u/4348811?v=3","gravatar_id":"","url":"https://api.github.com/users/jeremygoh","html_url":"https://github.com/jeremygoh","followers_url":"https://api.github.com/users/jeremygoh/followers","following_url":"https://api.github.com/users/jeremygoh/following{/other_user}","gists_url":"https://api.github.com/users/jeremygoh/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremygoh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremygoh/subscriptions","organizations_url":"https://api.github.com/users/jeremygoh/orgs","repos_url":"https://api.github.com/users/jeremygoh/repos","events_url":"https://api.github.com/users/jeremygoh/events{/privacy}","received_events_url":"https://api.github.com/users/jeremygoh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jeremygoh/Markus","description":"Git repository of MarkUs","fork":true,"url":"https://api.github.com/repos/jeremygoh/Markus","forks_url":"https://api.github.com/repos/jeremygoh/Markus/forks","keys_url":"https://api.github.com/repos/jeremygoh/Markus/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jeremygoh/Markus/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jeremygoh/Markus/teams","hooks_url":"https://api.github.com/repos/jeremygoh/Markus/hooks","issue_events_url":"https://api.github.com/repos/jeremygoh/Markus/issues/events{/number}","events_url":"https://api.github.com/repos/jeremygoh/Markus/events","assignees_url":"https://api.github.com/repos/jeremygoh/Markus/assignees{/user}","branches_url":"https://api.github.com/repos/jeremygoh/Markus/branches{/branch}","tags_url":"https://api.github.com/repos/jeremygoh/Markus/tags","blobs_url":"https://api.github.com/repos/jeremygoh/Markus/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jeremygoh/Markus/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jeremygoh/Markus/git/refs{/sha}","trees_url":"https://api.github.com/repos/jeremygoh/Markus/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jeremygoh/Markus/statuses/{sha}","languages_url":"https://api.github.com/repos/jeremygoh/Markus/languages","stargazers_url":"https://api.github.com/repos/jeremygoh/Markus/stargazers","contributors_url":"https://api.github.com/repos/jeremygoh/Markus/contributors","subscribers_url":"https://api.github.com/repos/jeremygoh/Markus/subscribers","subscription_url":"https://api.github.com/repos/jeremygoh/Markus/subscription","commits_url":"https://api.github.com/repos/jeremygoh/Markus/commits{/sha}","git_commits_url":"https://api.github.com/repos/jeremygoh/Markus/git/commits{/sha}","comments_url":"https://api.github.com/repos/jeremygoh/Markus/comments{/number}","issue_comment_url":"https://api.github.com/repos/jeremygoh/Markus/issues/comments{/number}","contents_url":"https://api.github.com/repos/jeremygoh/Markus/contents/{+path}","compare_url":"https://api.github.com/repos/jeremygoh/Markus/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jeremygoh/Markus/merges","archive_url":"https://api.github.com/repos/jeremygoh/Markus/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jeremygoh/Markus/downloads","issues_url":"https://api.github.com/repos/jeremygoh/Markus/issues{/number}","pulls_url":"https://api.github.com/repos/jeremygoh/Markus/pulls{/number}","milestones_url":"https://api.github.com/repos/jeremygoh/Markus/milestones{/number}","notifications_url":"https://api.github.com/repos/jeremygoh/Markus/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jeremygoh/Markus/labels{/name}","releases_url":"https://api.github.com/repos/jeremygoh/Markus/releases{/id}","created_at":"2015-09-09T18:23:50Z","updated_at":"2015-09-09T18:23:53Z","pushed_at":"2015-11-19T16:45:44Z","git_url":"git://github.com/jeremygoh/Markus.git","ssh_url":"git@github.com:jeremygoh/Markus.git","clone_url":"https://github.com/jeremygoh/Markus.git","svn_url":"https://github.com/jeremygoh/Markus","homepage":"http://www.markusproject.org","size":23543,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"MarkUsProject:test-framework","ref":"test-framework","sha":"3e4801a278ce1eeafea78b6950e32016f06039aa","user":{"login":"MarkUsProject","id":415874,"avatar_url":"https://avatars.githubusercontent.com/u/415874?v=3","gravatar_id":"","url":"https://api.github.com/users/MarkUsProject","html_url":"https://github.com/MarkUsProject","followers_url":"https://api.github.com/users/MarkUsProject/followers","following_url":"https://api.github.com/users/MarkUsProject/following{/other_user}","gists_url":"https://api.github.com/users/MarkUsProject/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkUsProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkUsProject/subscriptions","organizations_url":"https://api.github.com/users/MarkUsProject/orgs","repos_url":"https://api.github.com/users/MarkUsProject/repos","events_url":"https://api.github.com/users/MarkUsProject/events{/privacy}","received_events_url":"https://api.github.com/users/MarkUsProject/received_events","type":"Organization","site_admin":false},"repo":{"id":940538,"name":"Markus","full_name":"MarkUsProject/Markus","owner":{"login":"MarkUsProject","id":415874,"avatar_url":"https://avatars.githubusercontent.com/u/415874?v=3","gravatar_id":"","url":"https://api.github.com/users/MarkUsProject","html_url":"https://github.com/MarkUsProject","followers_url":"https://api.github.com/users/MarkUsProject/followers","following_url":"https://api.github.com/users/MarkUsProject/following{/other_user}","gists_url":"https://api.github.com/users/MarkUsProject/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkUsProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkUsProject/subscriptions","organizations_url":"https://api.github.com/users/MarkUsProject/orgs","repos_url":"https://api.github.com/users/MarkUsProject/repos","events_url":"https://api.github.com/users/MarkUsProject/events{/privacy}","received_events_url":"https://api.github.com/users/MarkUsProject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MarkUsProject/Markus","description":"Git repository of MarkUs","fork":false,"url":"https://api.github.com/repos/MarkUsProject/Markus","forks_url":"https://api.github.com/repos/MarkUsProject/Markus/forks","keys_url":"https://api.github.com/repos/MarkUsProject/Markus/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MarkUsProject/Markus/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MarkUsProject/Markus/teams","hooks_url":"https://api.github.com/repos/MarkUsProject/Markus/hooks","issue_events_url":"https://api.github.com/repos/MarkUsProject/Markus/issues/events{/number}","events_url":"https://api.github.com/repos/MarkUsProject/Markus/events","assignees_url":"https://api.github.com/repos/MarkUsProject/Markus/assignees{/user}","branches_url":"https://api.github.com/repos/MarkUsProject/Markus/branches{/branch}","tags_url":"https://api.github.com/repos/MarkUsProject/Markus/tags","blobs_url":"https://api.github.com/repos/MarkUsProject/Markus/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MarkUsProject/Markus/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MarkUsProject/Markus/git/refs{/sha}","trees_url":"https://api.github.com/repos/MarkUsProject/Markus/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MarkUsProject/Markus/statuses/{sha}","languages_url":"https://api.github.com/repos/MarkUsProject/Markus/languages","stargazers_url":"https://api.github.com/repos/MarkUsProject/Markus/stargazers","contributors_url":"https://api.github.com/repos/MarkUsProject/Markus/contributors","subscribers_url":"https://api.github.com/repos/MarkUsProject/Markus/subscribers","subscription_url":"https://api.github.com/repos/MarkUsProject/Markus/subscription","commits_url":"https://api.github.com/repos/MarkUsProject/Markus/commits{/sha}","git_commits_url":"https://api.github.com/repos/MarkUsProject/Markus/git/commits{/sha}","comments_url":"https://api.github.com/repos/MarkUsProject/Markus/comments{/number}","issue_comment_url":"https://api.github.com/repos/MarkUsProject/Markus/issues/comments{/number}","contents_url":"https://api.github.com/repos/MarkUsProject/Markus/contents/{+path}","compare_url":"https://api.github.com/repos/MarkUsProject/Markus/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MarkUsProject/Markus/merges","archive_url":"https://api.github.com/repos/MarkUsProject/Markus/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MarkUsProject/Markus/downloads","issues_url":"https://api.github.com/repos/MarkUsProject/Markus/issues{/number}","pulls_url":"https://api.github.com/repos/MarkUsProject/Markus/pulls{/number}","milestones_url":"https://api.github.com/repos/MarkUsProject/Markus/milestones{/number}","notifications_url":"https://api.github.com/repos/MarkUsProject/Markus/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MarkUsProject/Markus/labels{/name}","releases_url":"https://api.github.com/repos/MarkUsProject/Markus/releases{/id}","created_at":"2010-09-26T16:18:08Z","updated_at":"2015-11-11T22:26:37Z","pushed_at":"2015-11-19T16:45:46Z","git_url":"git://github.com/MarkUsProject/Markus.git","ssh_url":"git@github.com:MarkUsProject/Markus.git","clone_url":"https://github.com/MarkUsProject/Markus.git","svn_url":"https://github.com/MarkUsProject/Markus","homepage":"http://www.markusproject.org","size":32064,"stargazers_count":130,"watchers_count":130,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":162,"mirror_url":null,"open_issues_count":103,"forks":162,"open_issues":103,"watchers":130,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348"},"html":{"href":"https://github.com/MarkUsProject/Markus/pull/2348"},"issue":{"href":"https://api.github.com/repos/MarkUsProject/Markus/issues/2348"},"comments":{"href":"https://api.github.com/repos/MarkUsProject/Markus/issues/2348/comments"},"review_comments":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348/comments"},"review_comment":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/MarkUsProject/Markus/pulls/2348/commits"},"statuses":{"href":"https://api.github.com/repos/MarkUsProject/Markus/statuses/919f55f05e09ad0ee3482f71aa02b2250ac56c44"}}}}