require 'test_helper'
class CollectionsControllerTest < ActionController::TestCase
+ # These tests don't do state-changing API calls. Save some time by
+ # skipping the database reset.
+ reset_api_fixtures :after_each_test, false
+ reset_api_fixtures :after_suite, true
+
include PipelineInstancesHelper
+ NONEXISTENT_COLLECTION = "ffffffffffffffffffffffffffffffff+0"
+
+ def stub_file_content
+ # For the duration of the current test case, stub file download
+ # content with a randomized (but recognizable) string. Return the
+ # string, the test case can use it in assertions.
+ txt = 'the quick brown fox ' + rand(2**32).to_s
+ @controller.stubs(:file_enumerator).returns([txt])
+ txt
+ end
+
+ def collection_params(collection_name, file_name=nil)
+ uuid = api_fixture('collections')[collection_name.to_s]['uuid']
+ params = {uuid: uuid, id: uuid}
+ params[:file] = file_name if file_name
+ params
+ end
+
+ def assert_hash_includes(actual_hash, expected_hash, msg=nil)
+ expected_hash.each do |key, value|
+ assert_equal(value, actual_hash[key], msg)
+ end
+ end
+
+ def assert_no_session
+ assert_hash_includes(session, {arvados_api_token: nil},
+ "session includes unexpected API token")
+ end
+
+ def assert_session_for_auth(client_auth)
+ api_token =
+ api_fixture('api_client_authorizations')[client_auth.to_s]['api_token']
+ assert_hash_includes(session, {arvados_api_token: api_token},
+ "session token does not belong to #{client_auth}")
+ end
+
+ def show_collection(params, session={}, response=:success)
+ params = collection_params(params) if not params.is_a? Hash
+ session = session_for(session) if not session.is_a? Hash
+ get(:show, params, session)
+ assert_response response
+ end
+
+ test "viewing a collection" do
+ show_collection(:foo_file, :active)
+ assert_equal([['.', 'foo', 3]], assigns(:object).files)
+ end
+
+ test "viewing a collection fetches related projects" do
+ show_collection({id: api_fixture('collections')["foo_file"]['portable_data_hash']}, :active)
+ assert_includes(assigns(:same_pdh).map(&:owner_uuid),
+ api_fixture('groups')['aproject']['uuid'],
+ "controller did not find linked project")
+ end
+
+ test "viewing a collection fetches related permissions" do
+ show_collection(:bar_file, :active)
+ assert_includes(assigns(:permissions).map(&:uuid),
+ api_fixture('links')['bar_file_readable_by_active']['uuid'],
+ "controller did not find permission link")
+ end
+
+ test "viewing a collection fetches jobs that output it" do
+ show_collection(:bar_file, :active)
+ assert_includes(assigns(:output_of).map(&:uuid),
+ api_fixture('jobs')['foobar']['uuid'],
+ "controller did not find output job")
+ end
+
+ test "viewing a collection fetches jobs that logged it" do
+ show_collection(:baz_file, :active)
+ assert_includes(assigns(:log_of).map(&:uuid),
+ api_fixture('jobs')['foobar']['uuid'],
+ "controller did not find logger job")
+ end
+
+ test "viewing a collection fetches logs about it" do
+ show_collection(:foo_file, :active)
+ assert_includes(assigns(:logs).map(&:uuid),
+ api_fixture('logs')['log4']['uuid'],
+ "controller did not find related log")
+ end
+
+ test "viewing collection files with a reader token" do
+ params = collection_params(:foo_file)
+ params[:reader_token] = api_fixture("api_client_authorizations",
+ "active_all_collections", "api_token")
+ get(:show_file_links, params)
+ assert_response :success
+ assert_equal([['.', 'foo', 3]], assigns(:object).files)
+ assert_no_session
+ end
+
+ test "fetching collection file with reader token" do
+ expected = stub_file_content
+ params = collection_params(:foo_file, "foo")
+ params[:reader_token] = api_fixture("api_client_authorizations",
+ "active_all_collections", "api_token")
+ get(:show_file, params)
+ assert_response :success
+ assert_equal(expected, @response.body,
+ "failed to fetch a Collection file with a reader token")
+ assert_no_session
+ end
+
+ test "reader token Collection links end with trailing slash" do
+ # Testing the fix for #2937.
+ session = session_for(:active_trustedclient)
+ post(:share, collection_params(:foo_file), session)
+ assert(@controller.download_link.ends_with? '/',
+ "Collection share link does not end with slash for wget")
+ end
+
+ test "getting a file from Keep" do
+ params = collection_params(:foo_file, 'foo')
+ sess = session_for(:active)
+ expect_content = stub_file_content
+ get(:show_file, params, sess)
+ assert_response :success
+ assert_equal(expect_content, @response.body,
+ "failed to get a correct file from Keep")
+ end
+
+ test "can't get a file from Keep without permission" do
+ params = collection_params(:foo_file, 'foo')
+ sess = session_for(:spectator)
+ get(:show_file, params, sess)
+ assert_response 404
+ end
+
+ test "trying to get a nonexistent file from Keep returns a 404" do
+ params = collection_params(:foo_file, 'gone')
+ sess = session_for(:admin)
+ get(:show_file, params, sess)
+ assert_response 404
+ end
+
+ test "getting a file from Keep with a good reader token" do
+ params = collection_params(:foo_file, 'foo')
+ read_token = api_fixture('api_client_authorizations')['active']['api_token']
+ params[:reader_token] = read_token
+ expect_content = stub_file_content
+ get(:show_file, params)
+ assert_response :success
+ assert_equal(expect_content, @response.body,
+ "failed to get a correct file from Keep using a reader token")
+ assert_not_equal(read_token, session[:arvados_api_token],
+ "using a reader token set the session's API token")
+ end
+
+ test "trying to get from Keep with an unscoped reader token prompts login" do
+ params = collection_params(:foo_file, 'foo')
+ params[:reader_token] =
+ api_fixture('api_client_authorizations')['active_noscope']['api_token']
+ get(:show_file, params)
+ assert_response :redirect
+ end
+
+ test "can get a file with an unpermissioned auth but in-scope reader token" do
+ params = collection_params(:foo_file, 'foo')
+ sess = session_for(:expired)
+ read_token = api_fixture('api_client_authorizations')['active']['api_token']
+ params[:reader_token] = read_token
+ expect_content = stub_file_content
+ get(:show_file, params, sess)
+ assert_response :success
+ assert_equal(expect_content, @response.body,
+ "failed to get a correct file from Keep using a reader token")
+ assert_not_equal(read_token, session[:arvados_api_token],
+ "using a reader token set the session's API token")
+ end
+
+ test "inactive user can retrieve user agreement" do
+ ua_collection = api_fixture('collections')['user_agreement']
+ # Here we don't test whether the agreement can be retrieved from
+ # Keep. We only test that show_file decides to send file content,
+ # so we use the file content stub.
+ stub_file_content
+ get :show_file, {
+ uuid: ua_collection['uuid'],
+ file: ua_collection['manifest_text'].match(/ \d+:\d+:(\S+)/)[1]
+ }, session_for(:inactive)
+ assert_nil(assigns(:unsigned_user_agreements),
+ "Did not skip check_user_agreements filter " +
+ "when showing the user agreement.")
+ assert_response :success
+ end
+
+ test "requesting nonexistent Collection returns 404" do
+ show_collection({uuid: NONEXISTENT_COLLECTION, id: NONEXISTENT_COLLECTION},
+ :active, 404)
+ end
+
+ test "use a reasonable read buffer even if client requests a huge range" do
+ fakefiledata = mock
+ IO.expects(:popen).returns(fakefiledata)
+ fakefiledata.expects(:read).twice.with() do |length|
+ # Fail the test if read() is called with length>1MiB:
+ length < 2**20
+ ## Force the ActionController::Live thread to lose the race to
+ ## verify that @response.body.length actually waits for the
+ ## response (see below):
+ # sleep 3
+ end.returns("foo\n", nil)
+ fakefiledata.expects(:close)
+ foo_file = api_fixture('collections')['foo_file']
+ @request.headers['Range'] = 'bytes=0-4294967296/*'
+ get :show_file, {
+ uuid: foo_file['uuid'],
+ file: foo_file['manifest_text'].match(/ \d+:\d+:(\S+)/)[1]
+ }, session_for(:active)
+ # Wait for the whole response to arrive before deciding whether
+ # mocks' expectations were met. Otherwise, Mocha will fail the
+ # test depending on how slowly the ActionController::Live thread
+ # runs.
+ @response.body.length
+ end
+
+ test "show file in a subdirectory of a collection" do
+ params = collection_params(:collection_with_files_in_subdir, 'subdir2/subdir3/subdir4/file1_in_subdir4.txt')
+ expect_content = stub_file_content
+ get(:show_file, params, session_for(:user1_with_load))
+ assert_response :success
+ assert_equal(expect_content, @response.body, "failed to get a correct file from Keep")
+ end
+
test 'provenance graph' do
use_token 'admin'
class PipelineInstancesControllerTest < ActionController::TestCase
include PipelineInstancesHelper
- test "one" do
- r = [{started_at: 1, finished_at: 3}]
- assert_equal 2, determine_wallclock_runtime(r)
-
- r = [{started_at: 1, finished_at: 5}]
- assert_equal 4, determine_wallclock_runtime(r)
-
- r = [{started_at: 1, finished_at: 2}, {started_at: 3, finished_at: 5}]
- assert_equal 3, determine_wallclock_runtime(r)
+ def create_instance_long_enough_to(instance_attrs={})
+ # create 'two_part' pipeline with the given instance attributes
+ pt_fixture = api_fixture('pipeline_templates')['two_part']
+ post :create, {
+ pipeline_instance: instance_attrs.merge({
+ pipeline_template_uuid: pt_fixture['uuid']
+ }),
+ format: :json
+ }, session_for(:active)
+ assert_response :success
+ pi_uuid = assigns(:object).uuid
+ assert_not_nil assigns(:object)
+
+ # yield
+ yield pi_uuid, pt_fixture
+
+ # delete the pipeline instance
+ use_token :active
+ PipelineInstance.where(uuid: pi_uuid).first.destroy
+ end
- r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2}]
- assert_equal 3, determine_wallclock_runtime(r)
+ test "pipeline instance components populated after create" do
+ create_instance_long_enough_to do |new_instance_uuid, template_fixture|
+ assert_equal(template_fixture['components'].to_json,
+ assigns(:object).components.to_json)
+ end
+ end
- r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2},
- {started_at: 2, finished_at: 4}]
- assert_equal 4, determine_wallclock_runtime(r)
+ test "can render pipeline instance with tagged collections" do
+ # Make sure to pass in a tagged collection to test that part of the rendering behavior.
+ get(:show,
+ {id: api_fixture("pipeline_instances")["pipeline_with_tagged_collection_input"]["uuid"]},
+ session_for(:active))
+ assert_response :success
+ end
- r = [{started_at: 1, finished_at: 5}, {started_at: 2, finished_at: 3}]
- assert_equal 4, determine_wallclock_runtime(r)
+ test "update script_parameters one at a time using merge param" do
+ template_fixture = api_fixture('pipeline_templates')['two_part']
+ post :update, {
+ id: api_fixture("pipeline_instances")["pipeline_to_merge_params"]["uuid"],
+ pipeline_instance: {
+ components: {
+ "part-two" => {
+ script_parameters: {
+ integer_with_value: {
+ value: 9
+ },
+ plain_string: {
+ value: 'quux'
+ },
+ }
+ }
+ }
+ },
+ merge: true,
+ format: :json
+ }, session_for(:active)
+ assert_response :success
+ assert_not_nil assigns(:object)
+ orig_params = template_fixture['components']['part-two']['script_parameters']
+ new_params = assigns(:object).components[:'part-two'][:script_parameters]
+ orig_params.keys.each do |k|
+ unless %w(integer_with_value plain_string).index(k)
+ assert_equal orig_params[k].to_json, new_params[k.to_sym].to_json
+ end
+ end
+ end
- r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 4}]
- assert_equal 4, determine_wallclock_runtime(r)
+ test "component rendering copes with unexpected components format" do
+ get(:show,
+ {id: api_fixture("pipeline_instances")["components_is_jobspec"]["uuid"]},
+ session_for(:active))
+ assert_response :success
+ end
- r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5}]
- assert_equal 4, determine_wallclock_runtime(r)
+ test "dates in JSON components are parsed" do
+ get(:show,
+ {id: api_fixture('pipeline_instances')['has_component_with_completed_jobs']['uuid']},
+ session_for(:active))
+ assert_response :success
+ assert_not_nil assigns(:object)
+ assert_not_nil assigns(:object).components[:foo][:job]
+ assert assigns(:object).components[:foo][:job][:started_at].is_a? Time
+ assert assigns(:object).components[:foo][:job][:finished_at].is_a? Time
+ end
- r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
- {started_at: 5, finished_at: 8}]
- assert_equal 7, determine_wallclock_runtime(r)
+ # The next two tests ensure that a pipeline instance can be copied
+ # when the template has components that do not exist in the
+ # instance (ticket #4000).
+
+ test "copy pipeline instance with components=use_latest" do
+ post(:copy,
+ {
+ id: api_fixture('pipeline_instances')['pipeline_with_newer_template']['uuid'],
+ components: 'use_latest',
+ script: 'use_latest',
+ pipeline_instance: {
+ state: 'RunningOnServer'
+ }
+ },
+ session_for(:active))
+ assert_response 302
+ assert_not_nil assigns(:object)
+
+ # Component 'foo' has script parameters only in the pipeline instance.
+ # Component 'bar' is present only in the pipeline_template.
+ # Test that the copied pipeline instance includes parameters for
+ # component 'foo' from the source instance, and parameters for
+ # component 'bar' from the source template.
+ #
+ assert_not_nil assigns(:object).components[:foo]
+ foo = assigns(:object).components[:foo]
+ assert_not_nil foo[:script_parameters]
+ assert_not_nil foo[:script_parameters][:input]
+ assert_equal 'foo instance input', foo[:script_parameters][:input][:title]
+
+ assert_not_nil assigns(:object).components[:bar]
+ bar = assigns(:object).components[:bar]
+ assert_not_nil bar[:script_parameters]
+ assert_not_nil bar[:script_parameters][:input]
+ assert_equal 'bar template input', bar[:script_parameters][:input][:title]
+ end
- r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
- {started_at: 6, finished_at: 8}]
- assert_equal 6, determine_wallclock_runtime(r)
+ test "copy pipeline instance on newer template works with script=use_same" do
+ post(:copy,
+ {
+ id: api_fixture('pipeline_instances')['pipeline_with_newer_template']['uuid'],
+ components: 'use_latest',
+ script: 'use_same',
+ pipeline_instance: {
+ state: 'RunningOnServer'
+ }
+ },
+ session_for(:active))
+ assert_response 302
+ assert_not_nil assigns(:object)
+
+ # Test that relevant component parameters were copied from both
+ # the source instance and source template, respectively (see
+ # previous test)
+ #
+ assert_not_nil assigns(:object).components[:foo]
+ foo = assigns(:object).components[:foo]
+ assert_not_nil foo[:script_parameters]
+ assert_not_nil foo[:script_parameters][:input]
+ assert_equal 'foo instance input', foo[:script_parameters][:input][:title]
+
+ assert_not_nil assigns(:object).components[:bar]
+ bar = assigns(:object).components[:bar]
+ assert_not_nil bar[:script_parameters]
+ assert_not_nil bar[:script_parameters][:input]
+ assert_equal 'bar template input', bar[:script_parameters][:input][:title]
end
test "generate graph" do
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
- test "valid token works in functional test" do
+ test "valid token works in controller test" do
get :index, {}, session_for(:active)
assert_response :success
end
+++ /dev/null
-require 'test_helper'
-
-class CollectionsControllerTest < ActionController::TestCase
- # These tests don't do state-changing API calls. Save some time by
- # skipping the database reset.
- reset_api_fixtures :after_each_test, false
- reset_api_fixtures :after_suite, true
-
- NONEXISTENT_COLLECTION = "ffffffffffffffffffffffffffffffff+0"
-
- def stub_file_content
- # For the duration of the current test case, stub file download
- # content with a randomized (but recognizable) string. Return the
- # string, the test case can use it in assertions.
- txt = 'the quick brown fox ' + rand(2**32).to_s
- @controller.stubs(:file_enumerator).returns([txt])
- txt
- end
-
- def collection_params(collection_name, file_name=nil)
- uuid = api_fixture('collections')[collection_name.to_s]['uuid']
- params = {uuid: uuid, id: uuid}
- params[:file] = file_name if file_name
- params
- end
-
- def assert_hash_includes(actual_hash, expected_hash, msg=nil)
- expected_hash.each do |key, value|
- assert_equal(value, actual_hash[key], msg)
- end
- end
-
- def assert_no_session
- assert_hash_includes(session, {arvados_api_token: nil},
- "session includes unexpected API token")
- end
-
- def assert_session_for_auth(client_auth)
- api_token =
- api_fixture('api_client_authorizations')[client_auth.to_s]['api_token']
- assert_hash_includes(session, {arvados_api_token: api_token},
- "session token does not belong to #{client_auth}")
- end
-
- def show_collection(params, session={}, response=:success)
- params = collection_params(params) if not params.is_a? Hash
- session = session_for(session) if not session.is_a? Hash
- get(:show, params, session)
- assert_response response
- end
-
- test "viewing a collection" do
- show_collection(:foo_file, :active)
- assert_equal([['.', 'foo', 3]], assigns(:object).files)
- end
-
- test "viewing a collection fetches related projects" do
- show_collection({id: api_fixture('collections')["foo_file"]['portable_data_hash']}, :active)
- assert_includes(assigns(:same_pdh).map(&:owner_uuid),
- api_fixture('groups')['aproject']['uuid'],
- "controller did not find linked project")
- end
-
- test "viewing a collection fetches related permissions" do
- show_collection(:bar_file, :active)
- assert_includes(assigns(:permissions).map(&:uuid),
- api_fixture('links')['bar_file_readable_by_active']['uuid'],
- "controller did not find permission link")
- end
-
- test "viewing a collection fetches jobs that output it" do
- show_collection(:bar_file, :active)
- assert_includes(assigns(:output_of).map(&:uuid),
- api_fixture('jobs')['foobar']['uuid'],
- "controller did not find output job")
- end
-
- test "viewing a collection fetches jobs that logged it" do
- show_collection(:baz_file, :active)
- assert_includes(assigns(:log_of).map(&:uuid),
- api_fixture('jobs')['foobar']['uuid'],
- "controller did not find logger job")
- end
-
- test "viewing a collection fetches logs about it" do
- show_collection(:foo_file, :active)
- assert_includes(assigns(:logs).map(&:uuid),
- api_fixture('logs')['log4']['uuid'],
- "controller did not find related log")
- end
-
- test "viewing collection files with a reader token" do
- params = collection_params(:foo_file)
- params[:reader_token] = api_fixture("api_client_authorizations",
- "active_all_collections", "api_token")
- get(:show_file_links, params)
- assert_response :success
- assert_equal([['.', 'foo', 3]], assigns(:object).files)
- assert_no_session
- end
-
- test "fetching collection file with reader token" do
- expected = stub_file_content
- params = collection_params(:foo_file, "foo")
- params[:reader_token] = api_fixture("api_client_authorizations",
- "active_all_collections", "api_token")
- get(:show_file, params)
- assert_response :success
- assert_equal(expected, @response.body,
- "failed to fetch a Collection file with a reader token")
- assert_no_session
- end
-
- test "reader token Collection links end with trailing slash" do
- # Testing the fix for #2937.
- session = session_for(:active_trustedclient)
- post(:share, collection_params(:foo_file), session)
- assert(@controller.download_link.ends_with? '/',
- "Collection share link does not end with slash for wget")
- end
-
- test "getting a file from Keep" do
- params = collection_params(:foo_file, 'foo')
- sess = session_for(:active)
- expect_content = stub_file_content
- get(:show_file, params, sess)
- assert_response :success
- assert_equal(expect_content, @response.body,
- "failed to get a correct file from Keep")
- end
-
- test "can't get a file from Keep without permission" do
- params = collection_params(:foo_file, 'foo')
- sess = session_for(:spectator)
- get(:show_file, params, sess)
- assert_response 404
- end
-
- test "trying to get a nonexistent file from Keep returns a 404" do
- params = collection_params(:foo_file, 'gone')
- sess = session_for(:admin)
- get(:show_file, params, sess)
- assert_response 404
- end
-
- test "getting a file from Keep with a good reader token" do
- params = collection_params(:foo_file, 'foo')
- read_token = api_fixture('api_client_authorizations')['active']['api_token']
- params[:reader_token] = read_token
- expect_content = stub_file_content
- get(:show_file, params)
- assert_response :success
- assert_equal(expect_content, @response.body,
- "failed to get a correct file from Keep using a reader token")
- assert_not_equal(read_token, session[:arvados_api_token],
- "using a reader token set the session's API token")
- end
-
- test "trying to get from Keep with an unscoped reader token prompts login" do
- params = collection_params(:foo_file, 'foo')
- params[:reader_token] =
- api_fixture('api_client_authorizations')['active_noscope']['api_token']
- get(:show_file, params)
- assert_response :redirect
- end
-
- test "can get a file with an unpermissioned auth but in-scope reader token" do
- params = collection_params(:foo_file, 'foo')
- sess = session_for(:expired)
- read_token = api_fixture('api_client_authorizations')['active']['api_token']
- params[:reader_token] = read_token
- expect_content = stub_file_content
- get(:show_file, params, sess)
- assert_response :success
- assert_equal(expect_content, @response.body,
- "failed to get a correct file from Keep using a reader token")
- assert_not_equal(read_token, session[:arvados_api_token],
- "using a reader token set the session's API token")
- end
-
- test "inactive user can retrieve user agreement" do
- ua_collection = api_fixture('collections')['user_agreement']
- # Here we don't test whether the agreement can be retrieved from
- # Keep. We only test that show_file decides to send file content,
- # so we use the file content stub.
- stub_file_content
- get :show_file, {
- uuid: ua_collection['uuid'],
- file: ua_collection['manifest_text'].match(/ \d+:\d+:(\S+)/)[1]
- }, session_for(:inactive)
- assert_nil(assigns(:unsigned_user_agreements),
- "Did not skip check_user_agreements filter " +
- "when showing the user agreement.")
- assert_response :success
- end
-
- test "requesting nonexistent Collection returns 404" do
- show_collection({uuid: NONEXISTENT_COLLECTION, id: NONEXISTENT_COLLECTION},
- :active, 404)
- end
-
- test "use a reasonable read buffer even if client requests a huge range" do
- fakefiledata = mock
- IO.expects(:popen).returns(fakefiledata)
- fakefiledata.expects(:read).twice.with() do |length|
- # Fail the test if read() is called with length>1MiB:
- length < 2**20
- ## Force the ActionController::Live thread to lose the race to
- ## verify that @response.body.length actually waits for the
- ## response (see below):
- # sleep 3
- end.returns("foo\n", nil)
- fakefiledata.expects(:close)
- foo_file = api_fixture('collections')['foo_file']
- @request.headers['Range'] = 'bytes=0-4294967296/*'
- get :show_file, {
- uuid: foo_file['uuid'],
- file: foo_file['manifest_text'].match(/ \d+:\d+:(\S+)/)[1]
- }, session_for(:active)
- # Wait for the whole response to arrive before deciding whether
- # mocks' expectations were met. Otherwise, Mocha will fail the
- # test depending on how slowly the ActionController::Live thread
- # runs.
- @response.body.length
- end
-
- test "show file in a subdirectory of a collection" do
- params = collection_params(:collection_with_files_in_subdir, 'subdir2/subdir3/subdir4/file1_in_subdir4.txt')
- expect_content = stub_file_content
- get(:show_file, params, session_for(:user1_with_load))
- assert_response :success
- assert_equal(expect_content, @response.body, "failed to get a correct file from Keep")
- end
-end
+++ /dev/null
-require 'test_helper'
-
-class PipelineInstancesControllerTest < ActionController::TestCase
- def create_instance_long_enough_to(instance_attrs={})
- # create 'two_part' pipeline with the given instance attributes
- pt_fixture = api_fixture('pipeline_templates')['two_part']
- post :create, {
- pipeline_instance: instance_attrs.merge({
- pipeline_template_uuid: pt_fixture['uuid']
- }),
- format: :json
- }, session_for(:active)
- assert_response :success
- pi_uuid = assigns(:object).uuid
- assert_not_nil assigns(:object)
-
- # yield
- yield pi_uuid, pt_fixture
-
- # delete the pipeline instance
- use_token :active
- PipelineInstance.where(uuid: pi_uuid).first.destroy
- end
-
- test "pipeline instance components populated after create" do
- create_instance_long_enough_to do |new_instance_uuid, template_fixture|
- assert_equal(template_fixture['components'].to_json,
- assigns(:object).components.to_json)
- end
- end
-
- test "can render pipeline instance with tagged collections" do
- # Make sure to pass in a tagged collection to test that part of the rendering behavior.
- get(:show,
- {id: api_fixture("pipeline_instances")["pipeline_with_tagged_collection_input"]["uuid"]},
- session_for(:active))
- assert_response :success
- end
-
- test "update script_parameters one at a time using merge param" do
- template_fixture = api_fixture('pipeline_templates')['two_part']
- post :update, {
- id: api_fixture("pipeline_instances")["pipeline_to_merge_params"]["uuid"],
- pipeline_instance: {
- components: {
- "part-two" => {
- script_parameters: {
- integer_with_value: {
- value: 9
- },
- plain_string: {
- value: 'quux'
- },
- }
- }
- }
- },
- merge: true,
- format: :json
- }, session_for(:active)
- assert_response :success
- assert_not_nil assigns(:object)
- orig_params = template_fixture['components']['part-two']['script_parameters']
- new_params = assigns(:object).components[:'part-two'][:script_parameters]
- orig_params.keys.each do |k|
- unless %w(integer_with_value plain_string).index(k)
- assert_equal orig_params[k].to_json, new_params[k.to_sym].to_json
- end
- end
- end
-
- test "component rendering copes with unexpected components format" do
- get(:show,
- {id: api_fixture("pipeline_instances")["components_is_jobspec"]["uuid"]},
- session_for(:active))
- assert_response :success
- end
-
- test "dates in JSON components are parsed" do
- get(:show,
- {id: api_fixture('pipeline_instances')['has_component_with_completed_jobs']['uuid']},
- session_for(:active))
- assert_response :success
- assert_not_nil assigns(:object)
- assert_not_nil assigns(:object).components[:foo][:job]
- assert assigns(:object).components[:foo][:job][:started_at].is_a? Time
- assert assigns(:object).components[:foo][:job][:finished_at].is_a? Time
- end
-
- # The next two tests ensure that a pipeline instance can be copied
- # when the template has components that do not exist in the
- # instance (ticket #4000).
-
- test "copy pipeline instance with components=use_latest" do
- post(:copy,
- {
- id: api_fixture('pipeline_instances')['pipeline_with_newer_template']['uuid'],
- components: 'use_latest',
- script: 'use_latest',
- pipeline_instance: {
- state: 'RunningOnServer'
- }
- },
- session_for(:active))
- assert_response 302
- assert_not_nil assigns(:object)
-
- # Component 'foo' has script parameters only in the pipeline instance.
- # Component 'bar' is present only in the pipeline_template.
- # Test that the copied pipeline instance includes parameters for
- # component 'foo' from the source instance, and parameters for
- # component 'bar' from the source template.
- #
- assert_not_nil assigns(:object).components[:foo]
- foo = assigns(:object).components[:foo]
- assert_not_nil foo[:script_parameters]
- assert_not_nil foo[:script_parameters][:input]
- assert_equal 'foo instance input', foo[:script_parameters][:input][:title]
-
- assert_not_nil assigns(:object).components[:bar]
- bar = assigns(:object).components[:bar]
- assert_not_nil bar[:script_parameters]
- assert_not_nil bar[:script_parameters][:input]
- assert_equal 'bar template input', bar[:script_parameters][:input][:title]
- end
-
- test "copy pipeline instance on newer template works with script=use_same" do
- post(:copy,
- {
- id: api_fixture('pipeline_instances')['pipeline_with_newer_template']['uuid'],
- components: 'use_latest',
- script: 'use_same',
- pipeline_instance: {
- state: 'RunningOnServer'
- }
- },
- session_for(:active))
- assert_response 302
- assert_not_nil assigns(:object)
-
- # Test that relevant component parameters were copied from both
- # the source instance and source template, respectively (see
- # previous test)
- #
- assert_not_nil assigns(:object).components[:foo]
- foo = assigns(:object).components[:foo]
- assert_not_nil foo[:script_parameters]
- assert_not_nil foo[:script_parameters][:input]
- assert_equal 'foo instance input', foo[:script_parameters][:input][:title]
-
- assert_not_nil assigns(:object).components[:bar]
- bar = assigns(:object).components[:bar]
- assert_not_nil bar[:script_parameters]
- assert_not_nil bar[:script_parameters][:input]
- assert_equal 'bar template input', bar[:script_parameters][:input][:title]
- end
-end
--- /dev/null
+require 'test_helper'
+
+class PipelineInstancesHelperTest < ActionView::TestCase
+ test "one" do
+ r = [{started_at: 1, finished_at: 3}]
+ assert_equal 2, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 5}]
+ assert_equal 4, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 2}, {started_at: 3, finished_at: 5}]
+ assert_equal 3, determine_wallclock_runtime(r)
+
+ r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2}]
+ assert_equal 3, determine_wallclock_runtime(r)
+
+ r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2},
+ {started_at: 2, finished_at: 4}]
+ assert_equal 4, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 5}, {started_at: 2, finished_at: 3}]
+ assert_equal 4, determine_wallclock_runtime(r)
+
+ r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 4}]
+ assert_equal 4, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5}]
+ assert_equal 4, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
+ {started_at: 5, finished_at: 8}]
+ assert_equal 7, determine_wallclock_runtime(r)
+
+ r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
+ {started_at: 6, finished_at: 8}]
+ assert_equal 6, determine_wallclock_runtime(r)
+ end
+end
def check_counter action
@counter += 1
if @counter == 2
- assert_equal 1, 2, "Multiple actions in functional test"
+ assert_equal 1, 2, "Multiple actions in controller test"
end
end