From e340b4bbcf07ed90d04d3af0d985910966fec598 Mon Sep 17 00:00:00 2001 From: Mark Maglana Date: Wed, 25 Sep 2013 12:04:40 -0700 Subject: [PATCH 1/5] [identity] Add tests for list_tenants (public) --- .../identity/v2/public/list_tenants_test.rb | 101 +++++++++++++ ...sponse_when_no_parameters_are_provided.yml | 143 ++++++++++++++++++ .../returns_the_correct_value_for_body_.yml | 62 ++++++++ ...returns_the_correct_value_for_headers_.yml | 62 ++++++++ ...rns_the_correct_value_for_http_method_.yml | 62 ++++++++ .../returns_the_correct_value_for_url_.yml | 62 ++++++++ 6 files changed, 492 insertions(+) create mode 100644 test/aviator/openstack/identity/v2/public/list_tenants_test.rb create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_no_parameters_are_provided.yml create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_body_.yml create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_headers_.yml create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_http_method_.yml create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_url_.yml diff --git a/test/aviator/openstack/identity/v2/public/list_tenants_test.rb b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb new file mode 100644 index 0000000..789efa7 --- /dev/null +++ b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb @@ -0,0 +1,101 @@ +require 'test_helper' + +class Aviator::Test + + describe 'aviator/openstack/identity/v2/public/list_tenants' do + + def create_request(session_data = get_session_data, &block) + klass.new(session_data, &block) + end + + + def get_session_data + session.send :auth_info + end + + + def helper + Aviator::Test::RequestHelper + end + + + def klass + @klass ||= helper.load_request('openstack', 'identity', 'v2', 'public', 'list_tenants.rb') + end + + + def session + unless @session + @session = Aviator::Session.new( + config_file: Environment.path, + environment: 'openstack_admin' + ) + @session.authenticate + end + + @session + end + + + validate_attr :anonymous? do + klass.anonymous?.must_equal false + end + + + validate_attr :api_version do + klass.api_version.must_equal :v2 + end + + + validate_attr :body do + klass.body?.must_equal false + create_request.body?.must_equal false + end + + + validate_attr :endpoint_type do + klass.endpoint_type.must_equal :public + end + + + validate_attr :headers do + session_data = get_session_data + + headers = { 'X-Auth-Token' => session_data[:access][:token][:id] } + + request = create_request(session_data) + + request.headers.must_equal headers + end + + + validate_attr :http_method do + create_request.http_method.must_equal :get + end + + + validate_attr :url do + session_data = get_session_data + service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'identity' } + url = "#{ service_spec[:endpoints][0][:publicURL] }/tenants" + request = klass.new(session_data) + + request.url.must_equal url + end + + + validate_response 'no parameters are provided' do + service = session.identity_service + + response = service.request :list_tenants + + response.status.must_equal 200 + response.body.wont_be_nil + response.body[:tenants].length.wont_equal 0 + response.headers.wont_be_nil + end + + + end + +end diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_no_parameters_are_provided.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_no_parameters_are_provided.yml new file mode 100644 index 0000000..7fad3c4 --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_no_parameters_are_provided.yml @@ -0,0 +1,143 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 19:00:22 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:00:22.822563", + "expires": "2013-09-26T01:00:22Z", "id": "9db5bd6b0022494f8bb97ceea0ce4b68", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:22 GMT +- request: + method: get + uri: :5000/v2.0/tenants + body: + encoding: US-ASCII + string: '' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + X-Auth-Token: + - 9db5bd6b0022494f8bb97ceea0ce4b68 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '4062' + date: + - Wed, 25 Sep 2013 19:00:23 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"tenants_links": [], "tenants": [{"description": "Description", + "enabled": true, "id": "1113967479ea4426a4c80a1b109daee2", "name": "Permanent + Project"}, {"description": "", "enabled": true, "id": "1b398a49e78448b3bdb7acf77e584fe5", + "name": "alvintest"}, {"description": "Tenant for the openstack services", + "enabled": true, "id": "1c386cddb0604535ba1f372a1c971550", "name": "services"}, + {"description": "My Project", "enabled": true, "id": "25f6138692a5497982e0a9185b6925eb", + "name": "Project"}, {"description": "", "enabled": true, "id": "27779ee35855440cbbed49e93bb068f5", + "name": "alvintest3"}, {"description": "Used for Aviator testing/development", + "enabled": true, "id": "291e43291289457da59d8f727c46147a", "name": ""}, + {"description": "asdf", "enabled": true, "id": "3abf2f47fb194ecc9977362e5d1a8c09", + "name": "mmaglana"}, {"description": "testing", "enabled": true, "id": "3ec6ecaff17a41a5bb105a15376c5566", + "name": "ninja"}, {"description": "This is a test", "enabled": true, "id": + "4170d3aef0ff4fdcb0287496f5eb3a61", "name": "Test Project Too"}, {"description": + "My Project", "enabled": true, "id": "47c27e66021546c8b39fe9a2cf0d0935", "name": + "Xample"}, {"description": "This is a test", "enabled": true, "id": "5a15648e5483474aa8d6fa13dbe37a4b", + "name": "Test Project"}, {"description": "sample", "enabled": true, "id": + "646fe18d914745eeae0122a24ea653cc", "name": "newprojtest"}, {"description": + "test", "enabled": true, "id": "6bad4d3fe00c43d3ad3c2dcca4ff3eb0", "name": + "elmer"}, {"description": "My Project", "enabled": true, "id": "6f2c8fc3dda7430c9c1adbdf8c769b9c", + "name": "WWProject"}, {"description": "Test Project", "enabled": true, "id": + "713e1b55039d4fd6b91bbeac8914028c", "name": "a_test_project"}, {"description": + "", "enabled": true, "id": "763d42422d914f0ca6eab905b85c65c5", "name": "Fonsy + Test 1"}, {"description": "lalala", "enabled": true, "id": "7dfb270af41245c4911cce903532cdde", + "name": "jason_test"}, {"description": "testing", "enabled": true, "id": "85ea75f214ca4d3f834ca37cc570a8fd", + "name": "ann"}, {"description": "test", "enabled": true, "id": "89b89207b57a4ac4a9e9d0be628a95b3", + "name": "projet"}, {"description": "admin tenant", "enabled": true, "id": + "8a42fc89e6fb41a0b676d7b502b35c81", "name": "admin"}, {"description": "My + Project", "enabled": true, "id": "8f6e20e1ad2a4ffb98da9450dc804891", "name": + "Aviator Project"}, {"description": "one instance in SUSPENDED state cannot + be \"resumed\" and deleted", "enabled": true, "id": "951659d798a14d5e98a94878760cfe39", + "name": "admgelProject"}, {"description": "sample", "enabled": true, "id": + "a0d20724cd2d475e99b01b2b9a03f71e", "name": "projecttest"}, {"description": + "lalala", "enabled": true, "id": "a0e37889b3eb4e319992c5b29ef8c5fe", "name": + "jason_testxxx"}, {"description": "lalala", "enabled": true, "id": "aadac34ef5f44c869151d9f62851ea1b", + "name": "jason_testxxxxx"}, {"description": "DELETEME", "enabled": true, "id": + "b7d51b17bbc144b3991d94d3a715fe7b", "name": "DELETEME"}, {"description": "test", + "enabled": true, "id": "bd57591e188f438ba53b19228e156358", "name": "test123"}, + {"description": "", "enabled": true, "id": "bfaebc8688fc48a2b227509173c934e3", + "name": "aviator_test"}, {"description": "sample", "enabled": true, "id": + "bfed1ed0079b4cb78abbbbb3257ddc21", "name": "another test project"}, {"description": + "My Project", "enabled": true, "id": "c764b14c998040d6ad1fb98831b31754", "name": + "Project 1377582007"}, {"description": "Used for Aviator testing/development + ", "enabled": true, "id": "d770443fc60a410c843dc12b98ac8135", "name": ""}, + {"description": "System account for Morphlabs mCloud administration", "enabled": + true, "id": "e7b1b62aa1474f758c4974b8be44cf6c", "name": "demo"}, {"description": + "", "enabled": true, "id": "ecc997fefbb24691b14ff16ebe900f17", "name": "alvintest2"}, + {"description": "", "enabled": true, "id": "f10664c00326466b98707ce4d5cff470", + "name": "alvintest4"}, {"description": "lalala", "enabled": true, "id": "f74461b5bd9e4740b2d4fb3df0e07b51", + "name": "jason_testxxxx"}]}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:23 GMT +recorded_with: VCR 2.5.0 diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_body_.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_body_.yml new file mode 100644 index 0000000..c905589 --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_body_.yml @@ -0,0 +1,62 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 19:00:19 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:00:19.111920", + "expires": "2013-09-26T01:00:19Z", "id": "f9433cbaa20849c9b6123d2f8d9efec6", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:19 GMT +recorded_with: VCR 2.5.0 diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_headers_.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_headers_.yml new file mode 100644 index 0000000..50328ac --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_headers_.yml @@ -0,0 +1,62 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 19:00:18 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:00:18.408332", + "expires": "2013-09-26T01:00:18Z", "id": "bdd80cf6e8bd44898e107f050fb879cb", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:18 GMT +recorded_with: VCR 2.5.0 diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_http_method_.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_http_method_.yml new file mode 100644 index 0000000..3a352bd --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_http_method_.yml @@ -0,0 +1,62 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 19:00:20 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:00:20.145845", + "expires": "2013-09-26T01:00:20Z", "id": "d95df57d5f424d0a996ed719bf4de115", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:20 GMT +recorded_with: VCR 2.5.0 diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_url_.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_url_.yml new file mode 100644 index 0000000..e5ae683 --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/returns_the_correct_value_for_url_.yml @@ -0,0 +1,62 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 19:00:21 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:00:21.745126", + "expires": "2013-09-26T01:00:21Z", "id": "eb587564e730436b8f55861fb77fa04e", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:00:21 GMT +recorded_with: VCR 2.5.0 From f1762c98a8dc587b80e4e5b0c4226506551beccf Mon Sep 17 00:00:00 2001 From: Mark Maglana Date: Wed, 25 Sep 2013 12:16:25 -0700 Subject: [PATCH 2/5] [identity] Add failing test that reproduces bug #65 This test shows that list_tenants will fail with a cryptic message when the user authenticates against keystone without a tenant name which results in an unscoped token that doesn't have a service catalog in place. --- .../identity/v2/public/list_tenants_test.rb | 20 ++++++++++ ..._when_session_is_using_a_default_token.yml | 39 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml diff --git a/test/aviator/openstack/identity/v2/public/list_tenants_test.rb b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb index 789efa7..520b263 100644 --- a/test/aviator/openstack/identity/v2/public/list_tenants_test.rb +++ b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb @@ -96,6 +96,26 @@ class Aviator::Test end + validate_response 'session is using a default token' do + s = Aviator::Session.new( + config_file: Environment.path, + environment: 'openstack_admin' + ) + + s.authenticate do |creds| + creds.username = Environment.openstack_member[:auth_credentials][:username] + creds.password = Environment.openstack_member[:auth_credentials][:password] + end + + response = s.identity_service.request :list_tenants + + response.status.must_equal 200 + response.body.wont_be_nil + response.body[:tenants].length.wont_equal 0 + response.headers.wont_be_nil + end + + end end diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml new file mode 100644 index 0000000..e4c3519 --- /dev/null +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml @@ -0,0 +1,39 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""}}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '355' + date: + - Wed, 25 Sep 2013 19:11:57 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:11:57.208475", + "expires": "2013-09-26T01:11:57Z", "id": "c81d9e4730e94b018147b80960120c56"}, + "serviceCatalog": [], "user": {"username": "", + "roles_links": [], "id": "447527294dae4a1788d36beb0db99c00", "roles": [], + "name": ""}, "metadata": {"is_admin": 0, "roles": + []}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 19:11:57 GMT +recorded_with: VCR 2.5.0 From cfece672558ec27fd1c30475d32d78bc613dfa26 Mon Sep 17 00:00:00 2001 From: Mark Maglana Date: Wed, 25 Sep 2013 15:37:04 -0700 Subject: [PATCH 3/5] [common] Add ability for base request to use base_url if provided. --- lib/aviator/core/service.rb | 17 +++ .../openstack/common/v2/public/base.rb | 10 +- .../openstack/common/v2/public/base_test.rb | 109 ++++++++++++++++++ ...returns_the_correct_value_for_headers_.yml | 62 ++++++++++ 4 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 test/aviator/openstack/common/v2/public/base_test.rb create mode 100644 test/cassettes/openstack/common/v2/public/base/returns_the_correct_value_for_headers_.yml diff --git a/lib/aviator/core/service.rb b/lib/aviator/core/service.rb index e182d4a..f46dd69 100644 --- a/lib/aviator/core/service.rb +++ b/lib/aviator/core/service.rb @@ -35,6 +35,23 @@ module Aviator end + class MissingServiceEndpointError < StandardError + def initialize(service_name, request_name) + request_name = request_name.to_s.split('::').last.underscore + super "The session's service catalog does not have an entry for the #{ service_name } "\ + "service. Therefore, I don't know to which base URL the request should be sent. "\ + "This may be because you are using a default or unscoped token. If this is not your "\ + "intention, please authenticate with a scoped token. If using a default token is your "\ + "intention, make sure to provide a base url when you call the request. For example: \n\n"\ + "session.#{ service_name }_service.request :#{ request_name }, base_url: 'http://myenv.com:9999/v2.0' do |params|\n"\ + " params[:example1] = 'example1'\n"\ + " params[:example2] = 'example2'\n"\ + "end\n\n" + end + end + + + class Logger < Faraday::Response::Logger def initialize(app, logger=nil) super(app) diff --git a/lib/aviator/openstack/common/v2/public/base.rb b/lib/aviator/openstack/common/v2/public/base.rb index 8843a51..16c73f2 100644 --- a/lib/aviator/openstack/common/v2/public/base.rb +++ b/lib/aviator/openstack/common/v2/public/base.rb @@ -16,9 +16,15 @@ module Aviator private + def base_url_for(endpoint_type) - service_spec = session_data[:access][:serviceCatalog].find { |s| s[:type] == service.to_s } - service_spec[:endpoints][0]["#{ endpoint_type }URL".to_sym] + if session_data[:base_url] + session_data[:base_url] + else + service_spec = session_data[:access][:serviceCatalog].find { |s| s[:type] == service.to_s } + raise Aviator::Service::MissingServiceEndpointError.new(service.to_s, self.class) unless service_spec + service_spec[:endpoints][0]["#{ endpoint_type }URL".to_sym] + end end diff --git a/test/aviator/openstack/common/v2/public/base_test.rb b/test/aviator/openstack/common/v2/public/base_test.rb new file mode 100644 index 0000000..3514c31 --- /dev/null +++ b/test/aviator/openstack/common/v2/public/base_test.rb @@ -0,0 +1,109 @@ +require 'test_helper' + +class Aviator::Test + + describe 'aviator/openstack/common/v2/public/base' do + + def create_request(session_data = get_session_data, &block) + block ||= lambda do |params| + params[:tenant_id] = 0 + params[:role_id] = 0 + params[:user_id] = 0 + end + + klass.new(session_data, &block) + end + + + def get_session_data + session.send :auth_info + end + + + def helper + Aviator::Test::RequestHelper + end + + + def klass + @klass ||= helper.load_request('openstack', 'common', 'v2', 'public', 'base.rb') + end + + + def session + unless @session + @session = Aviator::Session.new( + config_file: Environment.path, + environment: 'openstack_admin' + ) + @session.authenticate + end + + @session + end + + + validate_attr :anonymous? do + klass.anonymous?.must_equal false + end + + + validate_attr :api_version do + klass.api_version.must_equal :v2 + end + + + validate_attr :endpoint_type do + klass.endpoint_type.must_equal :public + end + + + validate_attr :headers do + headers = { 'X-Auth-Token' => get_session_data[:access][:token][:id] } + + request = create_request + + request.headers.must_equal headers + end + + + describe '::base_url_for' do + + it 'must throw a MissingServiceEndpointError when the service\'s endpoint can\'t be found' do + default_session_data = JSON.parse('{"access": {"token": {"issued_at": "2013-09-25T20:21:55.453783", + "expires": "2013-09-26T02:21:55Z", "id": "2f6bdec6cd0f49b4a60ede0cd4bf2c0d"}, + "serviceCatalog": [], "user": {"username": "bogus", + "roles_links": [], "id": "447527294dae4a1788d36beb0db99c00", "roles": [], + "name": "bogus"}, "metadata": {"is_admin": 0, "roles": + []}}}').with_indifferent_access + + request = klass.new(default_session_data) + + the_method = lambda { request.send(:base_url_for, :public) } + + the_method.must_raise Aviator::Service::MissingServiceEndpointError + end + + + it 'must use the base_url value if provided.' do + default_session_data = JSON.parse('{"access": {"token": {"issued_at": "2013-09-25T20:21:55.453783", + "expires": "2013-09-26T02:21:55Z", "id": "2f6bdec6cd0f49b4a60ede0cd4bf2c0d"}, + "serviceCatalog": [], "user": {"username": "bogus", + "roles_links": [], "id": "447527294dae4a1788d36beb0db99c00", "roles": [], + "name": "bogus"}, "metadata": {"is_admin": 0, "roles": + []}}}').with_indifferent_access + + base_url = 'http://sample' + + default_session_data.merge!({ base_url: base_url }) + + request = klass.new(default_session_data) + + request.send(:base_url_for, :public).must_equal base_url + end + + end + + end + +end diff --git a/test/cassettes/openstack/common/v2/public/base/returns_the_correct_value_for_headers_.yml b/test/cassettes/openstack/common/v2/public/base/returns_the_correct_value_for_headers_.yml new file mode 100644 index 0000000..33f6a33 --- /dev/null +++ b/test/cassettes/openstack/common/v2/public/base/returns_the_correct_value_for_headers_.yml @@ -0,0 +1,62 @@ +--- +http_interactions: +- request: + method: post + uri: :5000/v2.0/tokens + body: + encoding: UTF-8 + string: ! '{"auth":{"passwordCredentials":{"username":"","password":""},"tenantName":""}}' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '2649' + date: + - Wed, 25 Sep 2013 20:21:00 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"access": {"token": {"issued_at": "2013-09-25T20:21:00.599676", + "expires": "2013-09-26T02:21:00Z", "id": "695465ba44f34e32b008250b7a92e4e9", + "tenant": {"description": "Used for Aviator testing/development", "enabled": + true, "id": "291e43291289457da59d8f727c46147a", "name": ""}}, + "serviceCatalog": [{"endpoints": [{"adminURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8774/v2/291e43291289457da59d8f727c46147a", + "id": "6bb597a3738045f4b2c51a7702037cab", "publicURL": ":8774/v2/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": + ":9292", "region": "RegionOne", "internalURL": ":9292", + "id": "2985945e07b74103bb2dfef7e426cd43", "publicURL": ":9292"}], + "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": + ":8777", "region": "RegionOne", "internalURL": ":8777", + "id": "370119dd80e84894bfe83d766fd467dd", "publicURL": ":8777"}], + "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": + [{"adminURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "region": "RegionOne", "internalURL": ":8776/v1/291e43291289457da59d8f727c46147a", + "id": "2492a6f5fa80466d9312e51a8f79b638", "publicURL": ":8776/v1/291e43291289457da59d8f727c46147a"}], + "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": + [{"adminURL": ":8773/services/Admin", "region": + "RegionOne", "internalURL": ":8773/services/Cloud", + "id": "1f68f3ce931946c788e487443e772fb2", "publicURL": ":8773/services/Cloud"}], + "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": + ":35357/v2.0", "region": "RegionOne", "internalURL": + ":5000/v2.0", "id": "12c722e9b9fb471fbea83c6157c0123a", + "publicURL": ":5000/v2.0"}], "endpoints_links": + [], "type": "identity", "name": "keystone"}], "user": {"username": "", + "roles_links": [], "id": "3cb44449b3cb48519641864ca82d1911", "roles": [{"name": + "admin"}], "name": ""}, "metadata": {"is_admin": + 0, "roles": ["a0d6ba8f41b746b495a6d25c69962489"]}}}' + http_version: + recorded_at: Wed, 25 Sep 2013 20:21:00 GMT +recorded_with: VCR 2.5.0 From fc87081bb16f02dbf116d7c98954d2531eb103a9 Mon Sep 17 00:00:00 2001 From: Mark Maglana Date: Wed, 25 Sep 2013 15:38:13 -0700 Subject: [PATCH 4/5] [core] Add error check to Service for when token is not scoped. --- lib/aviator/core/service.rb | 1 + test/aviator/core/service_test.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/aviator/core/service.rb b/lib/aviator/core/service.rb index f46dd69..78dca84 100644 --- a/lib/aviator/core/service.rb +++ b/lib/aviator/core/service.rb @@ -166,6 +166,7 @@ module Aviator elsif session_data.has_key? :access service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == service } + raise MissingServiceEndpointError.new(service.to_s, request_name) unless service_spec version = service_spec[:endpoints][0][:publicURL].match(/(v\d+)\.?\d*/) version ? version[1].to_sym : :v1 end diff --git a/test/aviator/core/service_test.rb b/test/aviator/core/service_test.rb index 55366a3..21f5083 100644 --- a/test/aviator/core/service_test.rb +++ b/test/aviator/core/service_test.rb @@ -74,6 +74,24 @@ class Aviator::Test end + it 'raises an error if session data does not have the endpoint information' do + request_name = config[:auth_service][:request].to_sym + + bootstrap = JSON.parse('{"access": {"token": {"issued_at": "2013-09-25T20:21:55.453783", + "expires": "2013-09-26T02:21:55Z", "id": "2f6bdec6cd0f49b4a60ede0cd4bf2c0d"}, + "serviceCatalog": [], "user": {"username": "bogus", + "roles_links": [], "id": "447527294dae4a1788d36beb0db99c00", "roles": [], + "name": "bogus"}, "metadata": {"is_admin": 0, "roles": + []}}}').with_indifferent_access + + s = service(bootstrap) + + the_method = lambda { s.request request_name } + + the_method.must_raise Aviator::Service::MissingServiceEndpointError + end + + it 'can find the correct request based on non-bootstrapped session data' do session_data = do_auth_request.body From d0d1958cd776a8e4096f7b616a4064a7be56debd Mon Sep 17 00:00:00 2001 From: Mark Maglana Date: Wed, 25 Sep 2013 15:51:52 -0700 Subject: [PATCH 5/5] [core] Add ability to specify a base_url when Service#request is called The test is created in a specific request definition (list_tenants). --- lib/aviator/core/service.rb | 14 ++++-- .../identity/v2/public/list_tenants_test.rb | 12 +++++- ..._when_session_is_using_a_default_token.yml | 43 +++++++++++++++++-- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/lib/aviator/core/service.rb b/lib/aviator/core/service.rb index 78dca84..8553301 100644 --- a/lib/aviator/core/service.rb +++ b/lib/aviator/core/service.rb @@ -84,6 +84,10 @@ module Aviator session_data = options[:session_data] || default_session_data raise SessionDataNotProvidedError.new unless session_data + + [:base_url].each do |k| + session_data[k] = options[k] if options[k] + end request_class = find_request(request_name, session_data, options[:endpoint_type]) @@ -136,11 +140,11 @@ module Aviator namespace = Aviator.const_get(provider.camelize) .const_get(service.camelize) - version = infer_version(session_data).to_s.camelize + version = infer_version(session_data, name).to_s.camelize return nil unless version && namespace.const_defined?(version) - namespace = namespace.const_get(version) + namespace = namespace.const_get(version, name) endpoint_types.each do |endpoint_type| name = name.to_s.camelize @@ -156,7 +160,7 @@ module Aviator # Candidate for extraction to aviator/openstack - def infer_version(session_data) + def infer_version(session_data, request_name='sample_request') if session_data.has_key?(:auth_service) && session_data[:auth_service][:api_version] session_data[:auth_service][:api_version].to_sym @@ -164,6 +168,10 @@ module Aviator m = session_data[:auth_service][:host_uri].match(/(v\d+)\.?\d*/) return m[1].to_sym unless m.nil? + elsif session_data.has_key? :base_url + m = session_data[:base_url].match(/(v\d+)\.?\d*/) + return m[1].to_sym unless m.nil? + elsif session_data.has_key? :access service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == service } raise MissingServiceEndpointError.new(service.to_s, request_name) unless service_spec diff --git a/test/aviator/openstack/identity/v2/public/list_tenants_test.rb b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb index 520b263..088b77f 100644 --- a/test/aviator/openstack/identity/v2/public/list_tenants_test.rb +++ b/test/aviator/openstack/identity/v2/public/list_tenants_test.rb @@ -106,8 +106,18 @@ class Aviator::Test creds.username = Environment.openstack_member[:auth_credentials][:username] creds.password = Environment.openstack_member[:auth_credentials][:password] end + + base_url = URI(Environment.openstack_admin[:auth_service][:host_uri]) + + api_version = Environment.openstack_admin[:auth_service][:api_version] + + if api_version + base_url.path = (api_version == 'v2' ? '/v2.0' : "/#{ api_version }") + end - response = s.identity_service.request :list_tenants + # base_url should have the form 'https://:/' + + response = s.identity_service.request :list_tenants, base_url: base_url.to_s response.status.must_equal 200 response.body.wont_be_nil diff --git a/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml index e4c3519..75b261f 100644 --- a/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml +++ b/test/cassettes/openstack/identity/v2/public/list_tenants/leads_to_a_valid_response_when_session_is_using_a_default_token.yml @@ -23,17 +23,52 @@ http_interactions: content-length: - '355' date: - - Wed, 25 Sep 2013 19:11:57 GMT + - Wed, 25 Sep 2013 22:45:41 GMT connection: - close body: encoding: US-ASCII - string: ! '{"access": {"token": {"issued_at": "2013-09-25T19:11:57.208475", - "expires": "2013-09-26T01:11:57Z", "id": "c81d9e4730e94b018147b80960120c56"}, + string: ! '{"access": {"token": {"issued_at": "2013-09-25T22:45:41.760351", + "expires": "2013-09-26T04:45:41Z", "id": "922efc3fc21c4ffa86c280209f4aa9b8"}, "serviceCatalog": [], "user": {"username": "", "roles_links": [], "id": "447527294dae4a1788d36beb0db99c00", "roles": [], "name": ""}, "metadata": {"is_admin": 0, "roles": []}}}' http_version: - recorded_at: Wed, 25 Sep 2013 19:11:57 GMT + recorded_at: Wed, 25 Sep 2013 22:45:41 GMT +- request: + method: get + uri: :5000/v2.0/tenants + body: + encoding: US-ASCII + string: '' + headers: + Content-Type: + - application/json + User-Agent: + - Faraday v0.8.8 + X-Auth-Token: + - 922efc3fc21c4ffa86c280209f4aa9b8 + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - '189' + date: + - Wed, 25 Sep 2013 22:45:42 GMT + connection: + - close + body: + encoding: US-ASCII + string: ! '{"tenants_links": [], "tenants": [{"description": "Used for Aviator + testing/development ", "enabled": true, "id": "d770443fc60a410c843dc12b98ac8135", + "name": ""}]}' + http_version: + recorded_at: Wed, 25 Sep 2013 22:45:42 GMT recorded_with: VCR 2.5.0