diff --git a/kitchen.yml b/kitchen.yml index f383422..50e2b56 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -21,6 +21,7 @@ provisioner: product_name: <%= ENV['CHEF_PRODUCT_NAME'] || 'chef' %> product_version: 17 deprecations_as_errors: true + multiple_converge: 2 # Copy secret to /tmp/kitchen on test VM. Kitchen tries to gather secrets # before any recipes had a chance to run -> we cannot use a recipe to put the # secrets file in place. @@ -74,6 +75,7 @@ suites: run_list: - recipe[openstack_test] - role[openstackclient] + - recipe[openstack_test::openstackclient] - name: ops-database run_list: - recipe[openstack_test] diff --git a/test/cookbooks/openstack_test/recipes/openstackclient.rb b/test/cookbooks/openstack_test/recipes/openstackclient.rb new file mode 100644 index 0000000..d3ccca2 --- /dev/null +++ b/test/cookbooks/openstack_test/recipes/openstackclient.rb @@ -0,0 +1,162 @@ +class ::Chef::Recipe + include ::Openstack +end + +identity_endpoint = internal_endpoint 'identity' +auth_url = identity_endpoint.to_s +admin_user = 'admin' +admin_pass = get_password 'user', admin_user +admin_project = 'admin' +admin_domain = 'default' + +connection_params = { + openstack_auth_url: auth_url, + openstack_username: admin_user, + openstack_api_key: admin_pass, + openstack_project_name: admin_project, + openstack_domain_name: admin_domain, +} + +%w( + test-domain-delete + test-project-delete + test-role-delete + test-user-delete + test-user-revoke + test-service-delete + test-endpoint-delete +).each do |r| + file "/tmp/#{r}" do + action :nothing + end +end + +# Create tests +openstack_domain 'test-domain' do + connection_params connection_params +end + +openstack_project 'test-project' do + domain_name 'test-domain' + connection_params connection_params +end + +openstack_role 'test-role' do + connection_params connection_params +end + +openstack_user 'test-user' do + role_name 'test-role' + project_name 'test-project' + domain_name 'test-domain' + connection_params connection_params + action [:create, :grant_role, :grant_domain] +end + +openstack_service 'test-service' do + type 'foobar' + connection_params connection_params +end + +openstack_endpoint 'test-endpoint' do + service_name 'test-service' + interface 'admin' + url 'http://127.0.0.1:9999/v1' + region 'RegionOne' + connection_params connection_params +end + +# Delete tests +openstack_domain 'test-domain-delete' do + connection_params connection_params + notifies :create, 'file[/tmp/test-domain-delete]' + not_if { ::File.exist?('/tmp/test-domain-delete') } +end + +openstack_domain 'test-domain-delete' do + connection_params connection_params + action :delete +end + +openstack_project 'test-project-delete' do + connection_params connection_params + notifies :create, 'file[/tmp/test-project-delete]' + not_if { ::File.exist?('/tmp/test-project-delete') } +end + +openstack_project 'test-project-delete' do + connection_params connection_params + action :delete +end + +openstack_role 'test-role-delete' do + connection_params connection_params + notifies :create, 'file[/tmp/test-role-delete]' + not_if { ::File.exist?('/tmp/test-role-delete') } +end + +openstack_user 'test-user-revoke' do + role_name 'test-role' + project_name 'test-project' + domain_name 'test-domain' + connection_params connection_params + notifies :create, 'file[/tmp/test-user-revoke]' + not_if { ::File.exist?('/tmp/test-user-revoke') } + action [:create, :grant_role, :grant_domain] +end + +openstack_user 'test-user-revoke' do + role_name 'test-role' + project_name 'test-project' + domain_name 'test-domain' + connection_params connection_params + action [:revoke_role, :revoke_domain] +end + +openstack_role 'test-role-delete' do + connection_params connection_params + action :delete +end + +openstack_user 'test-user-delete' do + connection_params connection_params + notifies :create, 'file[/tmp/test-user-delete]' + not_if { ::File.exist?('/tmp/test-user-delete') } +end + +openstack_user 'test-user-delete' do + connection_params connection_params + action :delete +end + +openstack_service 'test-service-delete' do + type 'foobar' + connection_params connection_params + notifies :create, 'file[/tmp/test-service-delete]' + not_if { ::File.exist?('/tmp/test-service-delete') } +end + +openstack_service 'test-service-delete' do + type 'foobar' + connection_params connection_params + action :delete +end + +openstack_endpoint 'test-endpoint-delete' do + service_name 'test-service' + interface 'public' + url 'http://127.0.0.1:9998/v1' + region 'RegionOne' + connection_params connection_params + notifies :create, 'file[/tmp/test-endpoint-delete]' + not_if { ::File.exist?('/tmp/test-endpoint-delete') } +end + +openstack_endpoint 'test-endpoint-delete' do + service_name 'test-service' + interface 'public' + url 'http://127.0.0.1:9998/v1' + region 'RegionOne' + connection_params connection_params + action :delete +end diff --git a/test/integration/openstackclient/inspec/openstackclient_spec.rb b/test/integration/openstackclient/inspec/openstackclient_spec.rb new file mode 100644 index 0000000..50ea3df --- /dev/null +++ b/test/integration/openstackclient/inspec/openstackclient_spec.rb @@ -0,0 +1,96 @@ +openrc = 'bash -c "source /root/openrc && ' + +domain_id = inspec.command("#{openrc} openstack domain show test-domain -f value -c id\"").stdout.chomp +project_id = inspec.command("#{openrc} openstack project show test-project -f value -c id\"").stdout.chomp +endpoint_id = inspec.command("#{openrc} openstack endpoint list --service test-service -f value -c ID\"").stdout.chomp +role_id = inspec.command("#{openrc} openstack role show test-role -f value -c id\"").stdout.chomp + +describe command "#{openrc} openstack domain show test-domain -f shell\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^enabled="True"$/ } + its('stdout') { should match /^name="test-domain"$/ } +end + +describe command "#{openrc} openstack project show test-project -f shell\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^enabled="True"$/ } + its('stdout') { should match /^name="test-project"$/ } + its('stdout') { should match /^domain_id="#{domain_id}"$/ } + its('stdout') { should match /^parent_id="#{domain_id}"$/ } +end + +describe command "#{openrc} openstack role assignment list --user test-user -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /#{role_id}/ } + its('stdout') { should match /#{domain_id}/ } +end + +describe command "#{openrc} openstack role assignment list --user test-user-revoke -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should_not match /#{role_id}/ } + its('stdout') { should_not match /#{domain_id}/ } +end + +describe command "#{openrc} openstack user show test-user -f shell\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^name="test-user"$/ } + its('stdout') { should match /^domain_id="#{domain_id}"$/ } + its('stdout') { should match /^enabled="True"$/ } + its('stdout') { should match /^default_project_id="#{project_id}"$/ } + its('stdout') { should match /^email="defaultmail"$/ } +end + +describe command "#{openrc} openstack service show test-service -f shell\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^name="test-service"$/ } + its('stdout') { should match /^enabled="True"$/ } + its('stdout') { should match /^type="foobar"$/ } +end + +describe command "#{openrc} openstack endpoint show #{endpoint_id} -f shell\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^name="test-endpoint"$/ } + its('stdout') { should match /^enabled="True"$/ } + its('stdout') { should match /^interface="admin"$/ } + its('stdout') { should match /^region="RegionOne"$/ } + its('stdout') { should match /^region_id="RegionOne"$/ } + its('stdout') { should match /^service_name="test-service"$/ } + its('stdout') { should match /^service_type="foobar"$/ } + its('stdout') { should match %r{^url="http://127\.0\.0\.1:9999/v1"$} } +end + +describe command "#{openrc} openstack domain list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /test-domain/ } + its('stdout') { should_not match /test-domain-delete/ } +end + +describe command "#{openrc} openstack project list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /test-project/ } + its('stdout') { should_not match /test-project-delete/ } +end + +describe command "#{openrc} openstack role list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /test-role/ } + its('stdout') { should_not match /test-role-delete/ } +end + +describe command "#{openrc} openstack user list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /test-user/ } + its('stdout') { should_not match /test-user-delete/ } +end + +describe command "#{openrc} openstack service list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /test-service/ } + its('stdout') { should_not match /test-service-delete/ } +end + +describe command "#{openrc} openstack endpoint list -f value\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{http://127.0.0.1:9999/v1} } + its('stdout') { should_not match %r{http://127.0.0.1:9998/v1} } +end