diff --git a/devops-service/features/image.feature b/devops-service/features/image.feature new file mode 100644 index 0000000..b45e4bb --- /dev/null +++ b/devops-service/features/image.feature @@ -0,0 +1,35 @@ +Feature: Manage images + + Scenario: Get list of all images + When I send GET '/v2.0/images' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be an array + And response should be JSON, images list: + """ + [ + { + "provider": "foo_provider", + "name": "foo_name", + "remote_user": "foo_user", + "bootstrap_template": "foo_template", + "id": "foo_id" + } + ] + """ + + Scenario: Get info for single image + When I send GET '/v2.0/image/ami-83e4bcea' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be a hash + And response should be JSON, image object: + """ + { + "provider": "foo_provider", + "name": "foo_name", + "remote_user": "foo_user", + "bootstrap_template": "foo_template", + "id": "b79994de" + } + """ diff --git a/devops-service/features/project.feature b/devops-service/features/project.feature new file mode 100644 index 0000000..aac2746 --- /dev/null +++ b/devops-service/features/project.feature @@ -0,0 +1,7 @@ +Feature: Manage projects + Scenario: Get list of all projects + When I send GET '/v2.0/projects' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be an array + And the array elements should be strings diff --git a/devops-service/features/server.feature b/devops-service/features/server.feature new file mode 100644 index 0000000..2e07521 --- /dev/null +++ b/devops-service/features/server.feature @@ -0,0 +1,60 @@ +Feature: Create server for existing environment + Scenario: Get project 'test' + When I send GET '/v2.0/project/test' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be a hash + And the project should contains environment 'ec2' + + Scenario: Get servers list + When I send GET '/v2.0/servers' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be an array + And the list should be saved + + @ignore @long + Scenario: Create new server with bootstraping + When I send POST '/v2.0/server' query with params '{"project": "test", "deploy_env": "test"}' + Then response should be '200' + + Scenario: Create new server without bootstraping + When I send POST '/v2.0/server' query with params '{ "project": "test", "deploy_env": "test", "without_bootstrap": true }' + Then response should be '200' + + Scenario: Get new servers list + When I send GET '/v2.0/servers' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be an array + And the list should contains new server + + Scenario: reserve new server + When I reserve new server + Then response should be '201' + + @ignore + Scenario: get reserved servers list + When I send GET '/v2.0/servers?reserved=true' query + Then response should be '200' + And the Content-Type header should include 'application/json' + And the JSON response should be an array + And the list should contains reserved server + + Scenario: Pause server + When I pause new server + Then response should be '200' + And sleep '20' seconds + + Scenario: Unpause server + When I unpause new server + Then response should be '200' + And sleep '20' seconds + + Scenario: Deploy server + When I deploy new server + Then response should be '200' + + Scenario: Delete server + When I delete new server + Then response should be '200' diff --git a/devops-service/features/step_definitions/http_queries_steps.rb b/devops-service/features/step_definitions/http_queries_steps.rb new file mode 100644 index 0000000..9065a88 --- /dev/null +++ b/devops-service/features/step_definitions/http_queries_steps.rb @@ -0,0 +1,21 @@ +DEFAULT_HEADERS = { + "REMOTE_USER" => "user_for_testing", + 'Content-Type' => 'application/json', + 'Accept' => 'application/json' +} +When(/^I send GET '(.*)' query$/) do |path| + get(path, {}, DEFAULT_HEADERS) +end + +When(/^I send POST '(.*)' query with params '(.*)'$/) do |path, params| + if params == '' + p = Hash.new + else + p = JSON.parse params + end + res = post(path, p, DEFAULT_HEADERS) +end + +When(/^I send DELETE '(.*)' query$/) do |path| + delete(path, {}, DEFAULT_HEADERS) +end diff --git a/devops-service/features/step_definitions/image_steps.rb b/devops-service/features/step_definitions/image_steps.rb new file mode 100644 index 0000000..4f55b66 --- /dev/null +++ b/devops-service/features/step_definitions/image_steps.rb @@ -0,0 +1,40 @@ +Then(/^response should be '(\d+)'$/) do |code| + assert last_response.ok?, "Status is not #{code}, it is #{last_response.status}" +end + +Then(/^the Content\-Type header should include 'application\/json'$/) do + assert last_response.header.contenttype.include?("application/json"), "Response has no header 'Content-Type' with 'application/json'" +end + +Then(/^the JSON response should be an array$/) do + body = JSON.parse(last_response.body) + assert body.is_a?(Array), "Body is not an array" +end + +Then(/^the array elements should be strings$/) do + body = JSON.parse(last_response.body) + body.each do |e| + assert e.is_a?(String), "Array element is not a string" + end +end + +Then(/^the JSON response should be a hash$/) do + body = JSON.parse(last_response.body) + assert body.is_a?(Hash), "Body is not a hash" +end + +Then(/^response should be JSON, images list:$/) do |string| + src_image = JSON.parse(string).first + image = JSON.parse(last_response.body).first + src_image.each do |key, value| + assert image.key?(key), "Image has no key '#{key}'" + end +end + +Then(/^response should be JSON, image object:$/) do |string| + src_image = JSON.parse(string) + image = JSON.parse(last_response.body) + src_image.each do |key, value| + assert image.key?(key), "Image has no key '#{key}'" + end +end diff --git a/devops-service/features/step_definitions/server_steps.rb b/devops-service/features/step_definitions/server_steps.rb new file mode 100644 index 0000000..09483c6 --- /dev/null +++ b/devops-service/features/step_definitions/server_steps.rb @@ -0,0 +1,49 @@ +Then(/^the project should contains environment '(\w+)'$/) do |env| + body = JSON.parse(last_response.body) + assert !body["deploy_envs"].detect{|e| e["identifier"] == env}.nil?, "Project has no environment '#{env}'" +end + +Then(/^the list should be saved$/) do + body = JSON.parse(last_response.body) + $test_hash[:servers_list] = body +end + +Then(/^the list should contains new server$/) do + body = JSON.parse(last_response.body) + $test_hash[:new_server] = (body.map{|s| s["chef_node_name"]} - $test_hash[:servers_list].map{|s| s["chef_node_name"]}).first + assert !$test_hash[:new_server].nil?, "New element in servers list not found" +end + +When(/^I reserve new server$/) do + steps %{ + When I send POST '/v2.0/server/#{$test_hash[:new_server]}/reserve' query with params '' + } +end + +When(/^I pause new server$/) do + steps %{ + When I send POST '/v2.0/server/#{$test_hash[:new_server]}/pause' query with params '' + } +end + +When(/^I unpause new server$/) do + steps %{ + When I send POST '/v2.0/server/#{$test_hash[:new_server]}/unpause' query with params '' + } +end + +When(/^I deploy new server$/) do + steps %{ + When I send POST '/v2.0/deploy' query with params '{ "names": ["#{$test_hash[:new_server]}"] }' + } +end + +When(/^I delete new server$/) do + steps %{ + When I send POST '/v2.0/deploy' query with params '{ "names": ["#{$test_hash[:new_server]}"] }' + } +end + +Then(/^sleep '(\d+)' seconds$/) do |s| + sleep(s.to_i) +end diff --git a/devops-service/features/support/env.rb b/devops-service/features/support/env.rb new file mode 100644 index 0000000..ce51154 --- /dev/null +++ b/devops-service/features/support/env.rb @@ -0,0 +1,66 @@ +ENV["RACK_ENV"] = "test" +#require File.join(File.dirname(__FILE__), '..', '..', 'config.ru') + +require 'test/unit' +require 'rack/test' +require "json" +require 'httpclient' + + USERNAME = '' + PASSWORD = '' + HOST = '' + PORT = 7070 + +class MyWorld + + include Rack::Test::Methods + @@app = nil + def app + @@app ||= eval("Rack::Builder.new {( " + File.read(File.dirname(__FILE__) + '/../../config.ru') + "\n )}") + end +end + +class RequestSender + + @last_res = nil + $test_hash = Hash.new + + def host + "http://#{HOST}:#{PORT}" + end + + def last_response + @last_res + end + + def get path, query, headers + submit do |http| + http.get(host + path, query, headers) + end + end + + def post path, query, headers + submit do |http| + http.receive_timeout = 0 #!!! bring out to appropriate server step + http.post(host + path, JSON.pretty_generate(query), headers) + end + end + + def delete path, query, headers + submit do |http| + http.delete(host + path, JSON.pretty_generate(query), headers) + end + end + + def submit + http = HTTPClient.new + http.set_auth(host, USERNAME, PASSWORD) + res = yield http + @last_res = res + end +end + +World do + #MyWorld.new + RequestSender.new +end