Commit 284cd594 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch '131-qa-test-geo-status-api' into 'master'

Test Geo Node API

Closes gitlab-qa#131

See merge request gitlab-org/gitlab-ee!3865
parents e79bebec 40970e31
......@@ -69,6 +69,8 @@ Example response:
Updates an existing Geo secondary node. The primary node cannot be edited.
_This can only be run against a primary Geo node._
```
PUT /geo_nodes/:id
```
......@@ -112,6 +114,8 @@ DELETE /geo_nodes/:id
To repair the OAuth authentication of a Geo node.
_This can only be run against a primary Geo node._
```
POST /geo_nodes/:id/repair
```
......@@ -131,7 +135,7 @@ Example response:
}
```
## Retrieve status about all secondary Geo nodes
## Retrieve status about all Geo nodes
```
GET /geo_nodes/status
......@@ -145,6 +149,62 @@ Example response:
```json
[
{
"geo_node_id": 1,
"healthy": true,
"health": "Healthy",
"health_status": "Healthy",
"missing_oauth_application": false,
"attachments_count": 1,
"attachments_synced_count": nil,
"attachments_failed_count": nil,
"attachments_synced_missing_on_primary_count": 0,
"attachments_synced_in_percentage": "0.00%",
"db_replication_lag_seconds": nil,
"lfs_objects_count": 0,
"lfs_objects_synced_count": nil,
"lfs_objects_failed_count": nil,
"lfs_objects_synced_missing_on_primary_count": 0,
"lfs_objects_synced_in_percentage": "0.00%",
"job_artifacts_count": 2,
"job_artifacts_synced_count": nil,
"job_artifacts_failed_count": nil,
"job_artifacts_synced_missing_on_primary_count": 0,
"job_artifacts_synced_in_percentage": "0.00%",
"repositories_count": 41,
"repositories_failed_count": nil,
"repositories_synced_count": nil,
"repositories_synced_in_percentage": "0.00%",
"wikis_count": 41,
"wikis_failed_count": nil,
"wikis_synced_count": nil,
"wikis_synced_in_percentage": "0.00%",
"replication_slots_count": 1,
"replication_slots_used_count": 1,
"replication_slots_used_in_percentage": "100.00%",
"replication_slots_max_retained_wal_bytes": 0,
"repositories_checksummed_count": 20,
"repositories_checksum_failed_count": 5,
"repositories_checksummed_in_percentage": "48.78%",
"wikis_checksummed_count": 10,
"wikis_checksum_failed_count": 3,
"wikis_checksummed_in_percentage": "24.39%",
"repositories_verified_count": 20,
"repositories_verification_failed_count": 5,
"repositories_verified_in_percentage": "48.78%",
"repositories_checksum_mismatch_count": 3,
"wikis_verified_count": 10,
"wikis_verification_failed_count": 3,
"wikis_verified_in_percentage": "24.39%",
"wikis_checksum_mismatch_count": 1,
"last_event_id": 23,
"last_event_timestamp": 1509681166,
"cursor_last_event_id": nil,
"cursor_last_event_timestamp": 0,
"last_successful_status_check_timestamp": 1510125024,
"version": "10.3.0",
"revision": "33d33a096a",
},
{
"geo_node_id": 2,
"healthy": true,
......@@ -175,6 +235,10 @@ Example response:
"wikis_failed_count": 0,
"wikis_synced_count": 41,
"wikis_synced_in_percentage": "100.00%",
"replication_slots_count": nil,
"replication_slots_used_count": nil,
"replication_slots_used_in_percentage": "0.00%",
"replication_slots_max_retained_wal_bytes": nil,
"repositories_checksummed_count": 20,
"repositories_checksum_failed_count": 5,
"repositories_checksummed_in_percentage": "48.78%",
......@@ -200,7 +264,7 @@ Example response:
]
```
## Retrieve status about a specific secondary Geo node
## Retrieve status about a specific Geo node
```
GET /geo_nodes/:id/status
......@@ -239,6 +303,14 @@ Example response:
"repositories_failed_count": 1,
"repositories_synced_count": 40,
"repositories_synced_in_percentage": "97.56%",
"wikis_count": 41,
"wikis_failed_count": 0,
"wikis_synced_count": 41,
"wikis_synced_in_percentage": "100.00%",
"replication_slots_count": nil,
"replication_slots_used_count": nil,
"replication_slots_used_in_percentage": "0.00%",
"replication_slots_max_retained_wal_bytes": nil,
"last_event_id": 23,
"last_event_timestamp": 1509681166,
"cursor_last_event_id": 23,
......
---
title: Add missing fields to the API documentation for the status of Geo Nodes
merge_request: 3865
author:
type: fixed
......@@ -48,7 +48,7 @@ module API
get '/current/failures' do
geo_node = Gitlab::Geo.current_node
not_found('Geo node not found') unless geo_node
not_found!('Geo node not found') unless geo_node
finder = ::Geo::ProjectRegistryFinder.new(current_node: geo_node)
project_registries = paginate(finder.find_failed_project_registries(params[:type]))
......
......@@ -11,7 +11,7 @@ module QA
attribute :geo_secondary_name, '--secondary-name SECONDARY_NAME'
attribute :geo_skip_setup?, '--without-setup'
def perform(options, *files)
def perform(options, *rspec_options)
unless options[:geo_skip_setup?]
Geo::Primary.act do
add_license
......@@ -27,6 +27,7 @@ module QA
Specs::Runner.perform do |specs|
specs.tty = true
specs.tags = %w[geo]
specs.options = rspec_options.any? ? rspec_options : 'qa/specs/features'
end
end
......
......@@ -6,8 +6,9 @@ module QA
class Client
attr_reader :address
def initialize(address = :gitlab)
def initialize(address = :gitlab, personal_access_token = nil)
@address = address
@personal_access_token = personal_access_token
end
def personal_access_token
......
module QA
describe 'Geo Nodes API' do
before(:all) do
get_personal_access_token
end
shared_examples 'retrieving configuration about Geo nodes' do
scenario 'GET /geo_nodes' do
get api_endpoint('/geo_nodes')
expect_status(200)
expect(json_body.size).to be >= 2
expect_json('?', primary: true)
expect_json_types('*', primary: :boolean, current: :boolean,
files_max_capacity: :integer, repos_max_capacity: :integer,
clone_protocol: :string, _links: :object)
end
scenario 'GET /geo_nodes/:id' do
get api_endpoint("/geo_nodes/#{geo_node[:id]}")
expect_status(200)
expect(json_body).to eq geo_node
end
end
shared_examples 'retrieving status about all Geo nodes' do
scenario 'GET /geo_nodes/status' do
get api_endpoint('/geo_nodes/status')
expect_status(200)
expect(json_body.size).to be >= 2
# only need to check that some of the key values are there
expect_json_types('*', health: :string,
attachments_count: :integer,
db_replication_lag_seconds: :integer_or_null,
lfs_objects_count: :integer,
job_artifacts_count: :integer,
repositories_count: :integer,
wikis_count: :integer,
replication_slots_count: :integer_or_null,
version: :string_or_null)
end
end
shared_examples 'retrieving status about a specific Geo node' do
scenario 'GET /geo_nodes/:id/status of primary node' do
get api_endpoint("/geo_nodes/#{@primary_node[:id]}/status")
expect_status(200)
expect_json(geo_node_id: @primary_node[:id])
end
scenario 'GET /geo_nodes/:id/status of secondary node' do
get api_endpoint("/geo_nodes/#{@secondary_node[:id]}/status")
expect_status(200)
expect_json(geo_node_id: @secondary_node[:id])
end
scenario 'GET /geo_nodes/:id/status of an invalid node' do
get api_endpoint("/geo_nodes/1000/status")
expect_status(404)
end
end
shared_examples 'retrieving project sync failures ocurred on the current node' do
scenario 'GET /geo_nodes/current/failures' do
get api_endpoint("/geo_nodes/current/failures")
expect_status(200)
expect(json_body).to be_an Array
end
end
feature 'Geo Nodes API on primary node', :geo do
before(:context) do
fetch_nodes(:geo_primary)
end
include_examples 'retrieving configuration about Geo nodes' do
let(:geo_node) { @primary_node }
end
include_examples 'retrieving status about all Geo nodes'
include_examples 'retrieving status about a specific Geo node'
feature 'editing a Geo node' do
scenario 'PUT /geo_nodes/:id for primary node' do
put api_endpoint("/geo_nodes/#{@primary_node[:id]}"),
{ params: { files_max_capacity: 1000 } }
expect_status(403)
end
scenario 'PUT /geo_nodes/:id for secondary node' do
endpoint = api_endpoint("/geo_nodes/#{@secondary_node[:id]}")
new_attributes = { enabled: false, files_max_capacity: 1000, repos_max_capacity: 2000 }
put endpoint, new_attributes
expect_status(200)
expect_json(new_attributes)
# restore the original values
put endpoint, { enabled: @secondary_node[:enabled],
files_max_capacity: @secondary_node[:files_max_capacity],
repos_max_capacity: @secondary_node[:repos_max_capacity] }
expect_status(200)
end
scenario 'PUT /geo_nodes/:id for an invalid node' do
put api_endpoint("/geo_nodes/1000"),
{ params: { files_max_capacity: 1000 } }
expect_status(404)
end
end
feature 'repairing a Geo node' do
scenario 'POST /geo_nodes/:id/repair for primary node' do
post api_endpoint("/geo_nodes/#{@primary_node[:id]}/repair")
expect_status(200)
expect_json(geo_node_id: @primary_node[:id])
end
scenario 'POST /geo_nodes/:id/repair for secondary node' do
post api_endpoint("/geo_nodes/#{@secondary_node[:id]}/repair")
expect_status(200)
expect_json(geo_node_id: @secondary_node[:id])
end
scenario 'POST /geo_nodes/:id/repair for an invalid node' do
post api_endpoint("/geo_nodes/1000/repair")
expect_status(404)
end
end
end
feature 'Geo Nodes API on secondary node', :geo do
before(:context) do
fetch_nodes(:geo_secondary)
end
include_examples 'retrieving configuration about Geo nodes' do
let(:geo_node) { @nodes.first }
end
include_examples 'retrieving status about all Geo nodes'
include_examples 'retrieving status about a specific Geo node'
include_examples 'retrieving project sync failures ocurred on the current node'
scenario 'GET /geo_nodes is not current' do
get api_endpoint('/geo_nodes')
expect_status(200)
expect_json('?', current: false)
end
feature 'editing a Geo node' do
scenario 'PUT /geo_nodes/:id for primary node' do
put api_endpoint("/geo_nodes/#{@primary_node[:id]}"),
{ params: { files_max_capacity: 1000 } }
expect_status(403)
end
scenario 'PUT /geo_nodes/:id for secondary node' do
put api_endpoint("/geo_nodes/#{@secondary_node[:id]}"),
{ params: { files_max_capacity: 1000 } }
expect_status(403)
end
scenario 'PUT /geo_nodes/:id for an invalid node' do
put api_endpoint('/geo_nodes/1000'),
{ params: { files_max_capacity: 1000 } }
expect_status(403)
end
end
feature 'repairing a Geo node' do
scenario 'POST /geo_nodes/:id/repair for primary node' do
post api_endpoint("/geo_nodes/#{@primary_node[:id]}/repair")
expect_status(403)
end
scenario 'POST /geo_nodes/:id/repair for secondary node' do
post api_endpoint("/geo_nodes/#{@secondary_node[:id]}/repair")
expect_status(403)
end
scenario 'POST /geo_nodes/:id/repair for an invalid node' do
post api_endpoint('/geo_nodes/1000/repair')
expect_status(403)
end
end
end
def api_endpoint(endpoint)
QA::Runtime::API::Request.new(@api_client, endpoint).url
end
def fetch_nodes(node_type)
@api_client = Runtime::API::Client.new(node_type, @personal_access_token)
get api_endpoint('/geo_nodes')
@nodes = json_body
@primary_node = @nodes.detect { |node| node[:primary] == true }
@secondary_node = @nodes.detect { |node| node[:primary] == false }
end
# go to the primary and create a personal_access_token, which will be used
# for accessing both the primary and secondary
def get_personal_access_token
api_client = Runtime::API::Client.new(:geo_primary)
@personal_access_token = api_client.personal_access_token
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment