Merge "Remove bundled intree ceileometer tempest plugin"
This commit is contained in:
commit
d86651edc0
|
@ -1,309 +0,0 @@
|
||||||
#
|
|
||||||
# Tests for gnocchi-threshold-alarm
|
|
||||||
#
|
|
||||||
# user_id : c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
# project_id : 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
# alarm name : gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
# resource_id : gabbi-mock-resource
|
|
||||||
# archive policy : gabbiliveceph
|
|
||||||
#
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
request_headers:
|
|
||||||
x-auth-token: $ENVIRON['ADMIN_TOKEN']
|
|
||||||
|
|
||||||
tests:
|
|
||||||
#
|
|
||||||
# Setup gnocchi archive policy/resource type/resource/metrics
|
|
||||||
#
|
|
||||||
|
|
||||||
- name: SETUP. create archive policy gabbiliveceph
|
|
||||||
desc: create archve policy 'gabbiliveceph' for tests
|
|
||||||
POST: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy
|
|
||||||
status: 201
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
name: gabbiliveceph
|
|
||||||
back_window: 0
|
|
||||||
definition:
|
|
||||||
- granularity: 1 second
|
|
||||||
points: 60
|
|
||||||
- granularity: 20 second
|
|
||||||
timespan: 1 minute
|
|
||||||
- points: 5
|
|
||||||
timespan: 5 minute
|
|
||||||
aggregation_methods:
|
|
||||||
- mean
|
|
||||||
- min
|
|
||||||
- max
|
|
||||||
response_json_paths:
|
|
||||||
$.name: gabbiliveceph
|
|
||||||
$.back_window: 0
|
|
||||||
$.aggregation_methods.`len`: 3
|
|
||||||
|
|
||||||
- name: create resource type ceph_account
|
|
||||||
desc: needed to create a resource
|
|
||||||
POST: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource_type
|
|
||||||
status: 201 || 409
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
name: ceph_account
|
|
||||||
|
|
||||||
- name: create resource of ceph_account type
|
|
||||||
POST: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/ceph_account
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
id: 662e46f3-8c06-430c-8a9c-adcaedd1272c
|
|
||||||
user_id: 27e342e4-4489-424f-a7e4-ba8ed9ad729c
|
|
||||||
project_id: d6d32769-c351-4758-b0a2-458fa1a065a3
|
|
||||||
metrics:
|
|
||||||
radosgw.objects:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
radosgw.objects.size:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
radosgw.objects.containers:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
radosgw.api.request:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
radosgw.containers.objects:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
radosgw.containers.objects.size:
|
|
||||||
archive_policy_name: gabbiliveceph
|
|
||||||
status: 201
|
|
||||||
response_json_paths:
|
|
||||||
$.user_id: 27e342e4-4489-424f-a7e4-ba8ed9ad729c
|
|
||||||
$.project_id: d6d32769-c351-4758-b0a2-458fa1a065a3
|
|
||||||
$.metrics.`len`: 6
|
|
||||||
|
|
||||||
#
|
|
||||||
# Actual tests
|
|
||||||
#
|
|
||||||
|
|
||||||
- name: search 'gabbi-gnocchi-threshold-resource-alarm' alarm doesnt exist
|
|
||||||
desc: search for alarm using user_id, project_id, alarm_name
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
query_parameters:
|
|
||||||
q.field:
|
|
||||||
- user_id
|
|
||||||
- project_id
|
|
||||||
- name
|
|
||||||
q.op:
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
q.value:
|
|
||||||
- c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
- 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
- gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
method: GET
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 0
|
|
||||||
|
|
||||||
- name: create alarm 'gabbi-gnocchi-threshold-resource-alarm'
|
|
||||||
desc: create a threshold alarm gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
POST: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
alarm_actions:
|
|
||||||
- "http://site:8000/gnocchi-threshold-resource"
|
|
||||||
alarm_id: null
|
|
||||||
description: An gabbilive threshold based alarm
|
|
||||||
enabled: true
|
|
||||||
insufficient_data_actions:
|
|
||||||
- "http://site:8000/nodata-gnocchi-threshold-resource"
|
|
||||||
name: "gabbi-gnocchi-threshold-resource-alarm"
|
|
||||||
ok_actions:
|
|
||||||
- "http://site:8000/ok-gnocchi-threshold-resource"
|
|
||||||
project_id: 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
repeat_actions: false
|
|
||||||
severity: moderate
|
|
||||||
state: "insufficient data"
|
|
||||||
type: gnocchi_resources_threshold
|
|
||||||
gnocchi_resources_threshold_rule:
|
|
||||||
evaluation_periods: 3
|
|
||||||
metric: "radosgw.objects.size"
|
|
||||||
resource_id: "662e46f3-8c06-430c-8a9c-adcaedd1272c"
|
|
||||||
aggregation_method: "mean"
|
|
||||||
granularity: 60
|
|
||||||
threshold: 5.0
|
|
||||||
comparison_operator: "ge"
|
|
||||||
resource_type: ceph_account
|
|
||||||
user_id: c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
status: 201
|
|
||||||
response_json_paths:
|
|
||||||
$.name: gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
$.type: gnocchi_resources_threshold
|
|
||||||
$.user_id: c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
$.project_id: 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
$.severity: moderate
|
|
||||||
|
|
||||||
- name: retrieve history about 'gabbi-gnocchi-threshold-resource-alarm' creation
|
|
||||||
desc: get history about alarm creation
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.alarm_id']/history
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
poll:
|
|
||||||
count: 5
|
|
||||||
delay: 2
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 1
|
|
||||||
$.[0].type: creation
|
|
||||||
$.[0].alarm_id: $RESPONSE['$.alarm_id']
|
|
||||||
|
|
||||||
- name: update severity for alarm 'gabbi-gnocchi-threshold-resource-alarm'
|
|
||||||
desc: update severity for alarm gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
PUT: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.[0].alarm_id']
|
|
||||||
status: 200
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
alarm_actions:
|
|
||||||
- "http://site:8000/gnocchi-threshold-resource"
|
|
||||||
alarm_id: null
|
|
||||||
description: An gabbilive threshold based alarm
|
|
||||||
enabled: true
|
|
||||||
insufficient_data_actions:
|
|
||||||
- "http://site:8000/nodata-gnocchi-threshold-resource"
|
|
||||||
name: "gabbi-gnocchi-threshold-resource-alarm"
|
|
||||||
ok_actions:
|
|
||||||
- "http://site:8000/ok-gnocchi-threshold-resource"
|
|
||||||
project_id: 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
repeat_actions: false
|
|
||||||
severity: low
|
|
||||||
state: "insufficient data"
|
|
||||||
type: gnocchi_resources_threshold
|
|
||||||
gnocchi_resources_threshold_rule:
|
|
||||||
evaluation_periods: 3
|
|
||||||
metric: "radosgw.objects.size"
|
|
||||||
resource_id: "662e46f3-8c06-430c-8a9c-adcaedd1272c"
|
|
||||||
aggregation_method: "mean"
|
|
||||||
granularity: 60
|
|
||||||
threshold: 5.0
|
|
||||||
comparison_operator: "ge"
|
|
||||||
resource_type: ceph_account
|
|
||||||
user_id: c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
response_json_paths:
|
|
||||||
$.name: gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
$.type: gnocchi_resources_threshold
|
|
||||||
$.user_id: c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
$.project_id: 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
$.severity: low
|
|
||||||
$.state: "insufficient data"
|
|
||||||
|
|
||||||
- name: retrieve history for 'gabbi-gnocchi-threshold-resource-alarm'
|
|
||||||
desc: get history for rule_change
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.alarm_id']/history
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
poll:
|
|
||||||
count: 5
|
|
||||||
delay: 2
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 2
|
|
||||||
$.[0].type: rule change
|
|
||||||
$.[0].alarm_id: $RESPONSE['$.alarm_id']
|
|
||||||
$.[0].detail: '{"severity": "low"}'
|
|
||||||
|
|
||||||
- name: update alarm state for 'gabbi-gnocchi-threshold-resource-alarm'
|
|
||||||
desc: update state for alarm
|
|
||||||
PUT: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.[0].alarm_id']/state
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data: '"ok"'
|
|
||||||
status: 200
|
|
||||||
response_strings:
|
|
||||||
- "ok"
|
|
||||||
|
|
||||||
- name: search 'gabbi-gnocchi-threshold-resource-alarm' alarm exist
|
|
||||||
desc: search for alarm using user_id, project_id, alarm_name
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
query_parameters:
|
|
||||||
q.field:
|
|
||||||
- user_id
|
|
||||||
- project_id
|
|
||||||
- name
|
|
||||||
q.op:
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
q.value:
|
|
||||||
- c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
- 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
- gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
poll:
|
|
||||||
count: 5
|
|
||||||
delay: 2
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 1
|
|
||||||
|
|
||||||
- name: get info about 'gabbi-gnocchi-threshold-resource-alarm' alarm
|
|
||||||
desc: access alarm using its ID
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.[0].alarm_id']
|
|
||||||
response_json_paths:
|
|
||||||
$.alarm_id: $RESPONSE['$.[0].alarm_id']
|
|
||||||
$.alarm_actions: ["http://site:8000/gnocchi-threshold-resource"]
|
|
||||||
$.name: gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
$.gnocchi_resources_threshold_rule.resource_id: "662e46f3-8c06-430c-8a9c-adcaedd1272c"
|
|
||||||
$.gnocchi_resources_threshold_rule.metric: "radosgw.objects.size"
|
|
||||||
$.gnocchi_resources_threshold_rule.resource_type: "ceph_account"
|
|
||||||
$.user_id: c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
|
|
||||||
- name: get alarm state for 'gabbi-gnocchi-threshold-resource-alarm'
|
|
||||||
desc: get state for alarm
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.alarm_id']/state
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
status: 200
|
|
||||||
response_strings:
|
|
||||||
- "ok"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Teardown
|
|
||||||
#
|
|
||||||
|
|
||||||
- name: CLEANUP. search 'gabbi-gnocchi-threshold-resource' alarm exist
|
|
||||||
desc: Find alarm id using user_id, project_id, alarm_name
|
|
||||||
GET: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
query_parameters:
|
|
||||||
q.field:
|
|
||||||
- user_id
|
|
||||||
- project_id
|
|
||||||
- name
|
|
||||||
q.op:
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
- eq
|
|
||||||
q.value:
|
|
||||||
- c8ecb587-d38c-426f-a58d-22b8d4a9a1d3
|
|
||||||
- 709f6ed6-bfb3-4649-b303-0019a7f6aef2
|
|
||||||
- gabbi-gnocchi-threshold-resource-alarm
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 1
|
|
||||||
|
|
||||||
- name: CLEANUP. delete threshold alarm 'gabbi-gnocchi-threshold-resource'
|
|
||||||
DELETE: $ENVIRON['AODH_SERVICE_URL']/v2/alarms/$RESPONSE['$.[0].alarm_id']
|
|
||||||
status: 204
|
|
||||||
|
|
||||||
- name: CLEANUP. Get resource by name '662e46f3-8c06-430c-8a9c-adcaedd1272c'
|
|
||||||
desc: retrieve resource by 662e46f3-8c06-430c-8a9c-adcaedd1272c to get its ID
|
|
||||||
GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/generic/662e46f3-8c06-430c-8a9c-adcaedd1272c
|
|
||||||
status: 200
|
|
||||||
|
|
||||||
- name: CLEANUP. delete test ceph_resource '662e46f3-8c06-430c-8a9c-adcaedd1272c'
|
|
||||||
desc: delete ceph_account resource 662e46f3-8c06-430c-8a9c-adcaedd1272c
|
|
||||||
DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/generic/$RESPONSE['$.id']
|
|
||||||
status: 204
|
|
||||||
|
|
||||||
- name: CLEANUP. delete resource type ceph_account
|
|
||||||
DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource_type/ceph_account
|
|
||||||
status: 204
|
|
||||||
|
|
||||||
- name: CLEANUP. delete archive
|
|
||||||
DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/gabbiliveceph
|
|
||||||
status: 204
|
|
||||||
xfail: True
|
|
||||||
|
|
|
@ -1,175 +0,0 @@
|
||||||
defaults:
|
|
||||||
request_headers:
|
|
||||||
x-auth-token: $ENVIRON['USER_TOKEN']
|
|
||||||
|
|
||||||
tests:
|
|
||||||
- name: list alarms none
|
|
||||||
desc: Lists alarms, none yet exist
|
|
||||||
url: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
method: GET
|
|
||||||
response_strings:
|
|
||||||
- "[]"
|
|
||||||
|
|
||||||
- name: list servers none
|
|
||||||
desc: List servers, none yet exists
|
|
||||||
url: $ENVIRON['NOVA_SERVICE_URL']/servers
|
|
||||||
method: GET
|
|
||||||
response_strings:
|
|
||||||
- "[]"
|
|
||||||
|
|
||||||
- name: create stack
|
|
||||||
desc: Create an autoscaling stack
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks
|
|
||||||
method: POST
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data: <@create_stack.json
|
|
||||||
status: 201
|
|
||||||
|
|
||||||
- name: control stack status
|
|
||||||
desc: Checks the stack have been created successfully
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks/integration_test
|
|
||||||
redirects: true
|
|
||||||
method: GET
|
|
||||||
status: 200
|
|
||||||
poll:
|
|
||||||
count: 300
|
|
||||||
delay: 1
|
|
||||||
response_json_paths:
|
|
||||||
$.stack.stack_status: "CREATE_COMPLETE"
|
|
||||||
|
|
||||||
- name: list servers grow
|
|
||||||
desc: Wait the autoscaling stack grow to two servers
|
|
||||||
url: $ENVIRON['NOVA_SERVICE_URL']/servers/detail
|
|
||||||
method: GET
|
|
||||||
poll:
|
|
||||||
count: 600
|
|
||||||
delay: 1
|
|
||||||
response_json_paths:
|
|
||||||
$.servers[0].metadata.'metering.server_group': $RESPONSE['$.stack.id']
|
|
||||||
$.servers[1].metadata.'metering.server_group': $RESPONSE['$.stack.id']
|
|
||||||
$.servers[0].status: ACTIVE
|
|
||||||
$.servers[1].status: ACTIVE
|
|
||||||
$.servers.`len`: 2
|
|
||||||
|
|
||||||
- name: check gnocchi resources
|
|
||||||
desc: Check the gnocchi resources for this two servers exists
|
|
||||||
url: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/instance
|
|
||||||
method: GET
|
|
||||||
poll:
|
|
||||||
count: 30
|
|
||||||
delay: 1
|
|
||||||
response_strings:
|
|
||||||
- '"id": "$RESPONSE["$.servers[0].id"]"'
|
|
||||||
- '"id": "$RESPONSE["$.servers[1].id"]"'
|
|
||||||
|
|
||||||
- name: check event
|
|
||||||
desc: Check panko for new instance.create.end event
|
|
||||||
url: $ENVIRON['PANKO_SERVICE_URL']/v2/events
|
|
||||||
method: GET
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data:
|
|
||||||
q:
|
|
||||||
- field: event_type
|
|
||||||
op: eq
|
|
||||||
type: string
|
|
||||||
value: compute.instance.create.end
|
|
||||||
- field: resource_id
|
|
||||||
op: eq
|
|
||||||
type: string
|
|
||||||
value: $HISTORY['list servers grow'].$RESPONSE['$.servers[0].id']
|
|
||||||
poll:
|
|
||||||
count: 30
|
|
||||||
delay: 1
|
|
||||||
response_json_paths:
|
|
||||||
$.`len`: 1
|
|
||||||
$[0].event_type: compute.instance.create.end
|
|
||||||
$[0].traits[?(@.name='resource_id')].value: $HISTORY['list servers grow'].$RESPONSE['$.servers[0].id']
|
|
||||||
|
|
||||||
- name: check alarm
|
|
||||||
desc: Check the aodh alarm and its state
|
|
||||||
url: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
method: GET
|
|
||||||
poll:
|
|
||||||
count: 30
|
|
||||||
delay: 1
|
|
||||||
response_strings:
|
|
||||||
- "integration_test-cpu_alarm_high-"
|
|
||||||
response_json_paths:
|
|
||||||
$[0].state: alarm
|
|
||||||
|
|
||||||
- name: get stack location for update
|
|
||||||
desc: Get the stack location
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks/integration_test
|
|
||||||
method: GET
|
|
||||||
status: 302
|
|
||||||
|
|
||||||
- name: update stack
|
|
||||||
desc: Update an autoscaling stack
|
|
||||||
url: $LOCATION
|
|
||||||
method: PUT
|
|
||||||
request_headers:
|
|
||||||
content-type: application/json
|
|
||||||
data: <@update_stack.json
|
|
||||||
status: 202
|
|
||||||
|
|
||||||
- name: control stack status
|
|
||||||
desc: Checks the stack have been created successfully
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks/integration_test
|
|
||||||
redirects: true
|
|
||||||
method: GET
|
|
||||||
status: 200
|
|
||||||
poll:
|
|
||||||
count: 300
|
|
||||||
delay: 1
|
|
||||||
response_json_paths:
|
|
||||||
$.stack.stack_status: "UPDATE_COMPLETE"
|
|
||||||
|
|
||||||
- name: list servers shrink
|
|
||||||
desc: Wait the autoscaling stack shrink to one server
|
|
||||||
url: $ENVIRON['NOVA_SERVICE_URL']/servers/detail
|
|
||||||
method: GET
|
|
||||||
poll:
|
|
||||||
count: 600
|
|
||||||
delay: 1
|
|
||||||
response_json_paths:
|
|
||||||
$.servers[0].metadata.'metering.server_group': $RESPONSE['$.stack.id']
|
|
||||||
$.servers[0].status: ACTIVE
|
|
||||||
$.servers.`len`: 1
|
|
||||||
|
|
||||||
- name: get stack location
|
|
||||||
desc: Get the stack location
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks/integration_test
|
|
||||||
method: GET
|
|
||||||
status: 302
|
|
||||||
|
|
||||||
- name: delete stack
|
|
||||||
desc: Delete the stack
|
|
||||||
url: $LOCATION
|
|
||||||
method: DELETE
|
|
||||||
status: 204
|
|
||||||
|
|
||||||
- name: get deleted stack
|
|
||||||
desc: Check the stack have been deleted
|
|
||||||
url: $ENVIRON['HEAT_SERVICE_URL']/stacks/integration_test
|
|
||||||
redirects: true
|
|
||||||
method: GET
|
|
||||||
poll:
|
|
||||||
count: 300
|
|
||||||
delay: 1
|
|
||||||
status: 404
|
|
||||||
|
|
||||||
- name: list alarms deleted
|
|
||||||
desc: List alarms, no more exist
|
|
||||||
url: $ENVIRON['AODH_SERVICE_URL']/v2/alarms
|
|
||||||
method: GET
|
|
||||||
response_strings:
|
|
||||||
- "[]"
|
|
||||||
|
|
||||||
- name: list servers deleted
|
|
||||||
desc: List servers, no more exists
|
|
||||||
url: $ENVIRON['NOVA_SERVICE_URL']/servers
|
|
||||||
method: GET
|
|
||||||
response_strings:
|
|
||||||
- "[]"
|
|
|
@ -1,74 +0,0 @@
|
||||||
{
|
|
||||||
"stack_name": "integration_test",
|
|
||||||
"template": {
|
|
||||||
"heat_template_version": "2013-05-23",
|
|
||||||
"description": "Integration Test AutoScaling with heat+ceilometer+gnocchi+aodh",
|
|
||||||
"resources": {
|
|
||||||
"asg": {
|
|
||||||
"type": "OS::Heat::AutoScalingGroup",
|
|
||||||
"properties": {
|
|
||||||
"min_size": 1,
|
|
||||||
"max_size": 2,
|
|
||||||
"resource": {
|
|
||||||
"type": "OS::Nova::Server",
|
|
||||||
"properties": {
|
|
||||||
"networks": [{ "network": "$ENVIRON['NEUTRON_NETWORK']" }],
|
|
||||||
"flavor": "$ENVIRON['NOVA_FLAVOR_REF']",
|
|
||||||
"image": "$ENVIRON['GLANCE_IMAGE_NAME']",
|
|
||||||
"metadata": {
|
|
||||||
"metering.server_group": { "get_param": "OS::stack_id" }
|
|
||||||
},
|
|
||||||
"user_data_format": "RAW",
|
|
||||||
"user_data": {"Fn::Join": ["", [
|
|
||||||
"#!/bin/sh\n",
|
|
||||||
"echo 'Loading CPU'\n",
|
|
||||||
"set -v\n",
|
|
||||||
"cat /dev/urandom > /dev/null\n"
|
|
||||||
]]}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"web_server_scaleup_policy": {
|
|
||||||
"type": "OS::Heat::ScalingPolicy",
|
|
||||||
"properties": {
|
|
||||||
"adjustment_type": "change_in_capacity",
|
|
||||||
"auto_scaling_group_id": { "get_resource": "asg" },
|
|
||||||
"cooldown": 2,
|
|
||||||
"scaling_adjustment": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cpu_alarm_high": {
|
|
||||||
"type": "OS::Ceilometer::GnocchiAggregationByResourcesAlarm",
|
|
||||||
"properties": {
|
|
||||||
"description": "Scale-up if the mean CPU > 10% on 1 minute",
|
|
||||||
"metric": "cpu_util",
|
|
||||||
"aggregation_method": "mean",
|
|
||||||
"granularity": $ENVIRON["AODH_GRANULARITY"],
|
|
||||||
"evaluation_periods": 1,
|
|
||||||
"threshold": 10,
|
|
||||||
"comparison_operator": "gt",
|
|
||||||
"alarm_actions": [
|
|
||||||
{
|
|
||||||
"str_replace": {
|
|
||||||
"template": "trust+url",
|
|
||||||
"params": {
|
|
||||||
"url": { "get_attr": [ "web_server_scaleup_policy", "signal_url" ] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"resource_type": "instance",
|
|
||||||
"query": {
|
|
||||||
"str_replace": {
|
|
||||||
"template": "{\"and\": [{\"=\": {\"server_group\": \"stack_id\"}}, {\"=\": {\"ended_at\": null}}]}",
|
|
||||||
"params": {
|
|
||||||
"stack_id": { "get_param": "OS::stack_id" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
{
|
|
||||||
"template": {
|
|
||||||
"heat_template_version": "2013-05-23",
|
|
||||||
"description": "Integration Test AutoScaling with heat+ceilometer+gnocchi+aodh",
|
|
||||||
"resources": {
|
|
||||||
"asg": {
|
|
||||||
"type": "OS::Heat::AutoScalingGroup",
|
|
||||||
"properties": {
|
|
||||||
"min_size": 1,
|
|
||||||
"max_size": 2,
|
|
||||||
"resource": {
|
|
||||||
"type": "OS::Nova::Server",
|
|
||||||
"properties": {
|
|
||||||
"networks": [{ "network": "$ENVIRON['NEUTRON_NETWORK']" }],
|
|
||||||
"flavor": "$ENVIRON['NOVA_FLAVOR_REF']",
|
|
||||||
"image": "$ENVIRON['GLANCE_IMAGE_NAME']",
|
|
||||||
"metadata": {
|
|
||||||
"metering.server_group": { "get_param": "OS::stack_id" }
|
|
||||||
},
|
|
||||||
"user_data_format": "RAW",
|
|
||||||
"user_data": {"Fn::Join": ["", [
|
|
||||||
"#!/bin/sh\n",
|
|
||||||
"echo 'Loading CPU'\n",
|
|
||||||
"set -v\n",
|
|
||||||
"cat /dev/urandom > /dev/null\n"
|
|
||||||
]]}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"web_server_scaledown_policy": {
|
|
||||||
"type": "OS::Heat::ScalingPolicy",
|
|
||||||
"properties": {
|
|
||||||
"adjustment_type": "change_in_capacity",
|
|
||||||
"auto_scaling_group_id": { "get_resource": "asg" },
|
|
||||||
"cooldown": 2,
|
|
||||||
"scaling_adjustment": -1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cpu_alarm_high": {
|
|
||||||
"type": "OS::Ceilometer::GnocchiAggregationByResourcesAlarm",
|
|
||||||
"properties": {
|
|
||||||
"description": "Scale-down if the mean CPU > 10% on 1 minute",
|
|
||||||
"metric": "cpu_util",
|
|
||||||
"aggregation_method": "mean",
|
|
||||||
"granularity": $ENVIRON["AODH_GRANULARITY"],
|
|
||||||
"evaluation_periods": 1,
|
|
||||||
"threshold": 10,
|
|
||||||
"comparison_operator": "gt",
|
|
||||||
"alarm_actions": [
|
|
||||||
{
|
|
||||||
"str_replace": {
|
|
||||||
"template": "trust+url",
|
|
||||||
"params": {
|
|
||||||
"url": { "get_attr": [ "web_server_scaledown_policy", "signal_url" ] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"resource_type": "instance",
|
|
||||||
"query": {
|
|
||||||
"str_replace": {
|
|
||||||
"template": "{\"and\": [{\"=\": {\"server_group\": \"stack_id\"}}, {\"=\": {\"ended_at\": null}}]}",
|
|
||||||
"params": {
|
|
||||||
"stack_id": { "get_param": "OS::stack_id" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright 2015 Red Hat. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
"""A test module to exercise the Gnocchi API with gabbi."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from gabbi import driver
|
|
||||||
|
|
||||||
|
|
||||||
TESTS_DIR = 'gabbits-live'
|
|
||||||
|
|
||||||
|
|
||||||
def load_tests(loader, tests, pattern):
|
|
||||||
"""Provide a TestSuite to the discovery process."""
|
|
||||||
NEEDED_ENV = ["AODH_SERVICE_URL", "GNOCCHI_SERVICE_URL",
|
|
||||||
"HEAT_SERVICE_URL", "NOVA_SERVICE_URL", "PANKO_SERVICE_URL",
|
|
||||||
"GLANCE_IMAGE_NAME", "ADMIN_TOKEN"]
|
|
||||||
|
|
||||||
for env_variable in NEEDED_ENV:
|
|
||||||
if not os.getenv(env_variable):
|
|
||||||
if os.getenv("GABBI_LIVE_FAIL_IF_NO_TEST"):
|
|
||||||
raise RuntimeError('%s is not set' % env_variable)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
test_dir = os.path.join(os.path.dirname(__file__), TESTS_DIR)
|
|
||||||
return driver.build_tests(test_dir, loader, host="localhost", port=8041)
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from tempest import config
|
|
||||||
from tempest.lib.common.utils import data_utils
|
|
||||||
from tempest.lib import exceptions as lib_exc
|
|
||||||
import tempest.test
|
|
||||||
|
|
||||||
from ceilometer.tests.tempest.aodh.service import client
|
|
||||||
|
|
||||||
CONF = config.CONF
|
|
||||||
|
|
||||||
|
|
||||||
class BaseAlarmingTest(tempest.test.BaseTestCase):
|
|
||||||
"""Base test case class for all Alarming API tests."""
|
|
||||||
|
|
||||||
credentials = ['primary']
|
|
||||||
client_manager = client.Manager
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def skip_checks(cls):
|
|
||||||
super(BaseAlarmingTest, cls).skip_checks()
|
|
||||||
if not CONF.service_available.aodh_plugin:
|
|
||||||
raise cls.skipException("Aodh support is required")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setup_clients(cls):
|
|
||||||
super(BaseAlarmingTest, cls).setup_clients()
|
|
||||||
cls.alarming_client = cls.os_primary.alarming_client
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resource_setup(cls):
|
|
||||||
super(BaseAlarmingTest, cls).resource_setup()
|
|
||||||
cls.alarm_ids = []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def create_alarm(cls, **kwargs):
|
|
||||||
body = cls.alarming_client.create_alarm(
|
|
||||||
name=data_utils.rand_name('telemetry_alarm'),
|
|
||||||
type='gnocchi_aggregation_by_metrics_threshold', **kwargs)
|
|
||||||
cls.alarm_ids.append(body['alarm_id'])
|
|
||||||
return body
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def cleanup_resources(method, list_of_ids):
|
|
||||||
for resource_id in list_of_ids:
|
|
||||||
try:
|
|
||||||
method(resource_id)
|
|
||||||
except lib_exc.NotFound:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resource_cleanup(cls):
|
|
||||||
cls.cleanup_resources(cls.alarming_client.delete_alarm, cls.alarm_ids)
|
|
||||||
super(BaseAlarmingTest, cls).resource_cleanup()
|
|
|
@ -1,102 +0,0 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from tempest.lib.common.utils import data_utils
|
|
||||||
from tempest.lib import decorators
|
|
||||||
from tempest.lib import exceptions as lib_exc
|
|
||||||
|
|
||||||
from ceilometer.tests.tempest.aodh.api import base
|
|
||||||
|
|
||||||
|
|
||||||
class TelemetryAlarmingAPITest(base.BaseAlarmingTest):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def resource_setup(cls):
|
|
||||||
super(TelemetryAlarmingAPITest, cls).resource_setup()
|
|
||||||
cls.rule = {'metrics': ['c0d457b6-957e-41de-a384-d5eb0957de3b'],
|
|
||||||
'comparison_operator': 'gt',
|
|
||||||
'aggregation_method': 'mean',
|
|
||||||
'threshold': 80.0,
|
|
||||||
'granularity': 70}
|
|
||||||
for i in range(2):
|
|
||||||
cls.create_alarm(
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=cls.rule)
|
|
||||||
|
|
||||||
@decorators.idempotent_id('1c918e06-210b-41eb-bd45-14676dd77cd7')
|
|
||||||
def test_alarm_list(self):
|
|
||||||
# List alarms
|
|
||||||
alarm_list = self.alarming_client.list_alarms()
|
|
||||||
|
|
||||||
# Verify created alarm in the list
|
|
||||||
fetched_ids = [a['alarm_id'] for a in alarm_list]
|
|
||||||
missing_alarms = [a for a in self.alarm_ids if a not in fetched_ids]
|
|
||||||
self.assertEqual(0, len(missing_alarms),
|
|
||||||
"Failed to find the following created alarm(s)"
|
|
||||||
" in a fetched list: %s" %
|
|
||||||
', '.join(str(a) for a in missing_alarms))
|
|
||||||
|
|
||||||
@decorators.idempotent_id('1297b095-39c1-4e74-8a1f-4ae998cedd68')
|
|
||||||
def test_create_update_get_delete_alarm(self):
|
|
||||||
# Create an alarm
|
|
||||||
alarm_name = data_utils.rand_name('telemetry_alarm')
|
|
||||||
body = self.alarming_client.create_alarm(
|
|
||||||
name=alarm_name, type='gnocchi_aggregation_by_metrics_threshold',
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=self.rule)
|
|
||||||
self.assertEqual(alarm_name, body['name'])
|
|
||||||
alarm_id = body['alarm_id']
|
|
||||||
self.assertDictContainsSubset(self.rule, body[
|
|
||||||
'gnocchi_aggregation_by_metrics_threshold_rule'])
|
|
||||||
# Update alarm with new rule and new name
|
|
||||||
new_rule = {'metrics': ['c0d457b6-957e-41de-a384-d5eb0957de3b'],
|
|
||||||
'comparison_operator': 'eq',
|
|
||||||
'aggregation_method': 'mean',
|
|
||||||
'threshold': 70.0,
|
|
||||||
'granularity': 60}
|
|
||||||
alarm_name_updated = data_utils.rand_name('telemetry-alarm-update')
|
|
||||||
body = self.alarming_client.update_alarm(
|
|
||||||
alarm_id,
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=new_rule,
|
|
||||||
name=alarm_name_updated,
|
|
||||||
type='gnocchi_aggregation_by_metrics_threshold')
|
|
||||||
self.assertEqual(alarm_name_updated, body['name'])
|
|
||||||
self.assertDictContainsSubset(
|
|
||||||
new_rule, body['gnocchi_aggregation_by_metrics_threshold_rule'])
|
|
||||||
# Get and verify details of an alarm after update
|
|
||||||
body = self.alarming_client.show_alarm(alarm_id)
|
|
||||||
self.assertEqual(alarm_name_updated, body['name'])
|
|
||||||
self.assertDictContainsSubset(
|
|
||||||
new_rule, body['gnocchi_aggregation_by_metrics_threshold_rule'])
|
|
||||||
# Get history for the alarm and verify the same
|
|
||||||
body = self.alarming_client.show_alarm_history(alarm_id)
|
|
||||||
self.assertEqual("rule change", body[0]['type'])
|
|
||||||
self.assertIn(alarm_name_updated, body[0]['detail'])
|
|
||||||
self.assertEqual("creation", body[1]['type'])
|
|
||||||
self.assertIn(alarm_name, body[1]['detail'])
|
|
||||||
# Delete alarm and verify if deleted
|
|
||||||
self.alarming_client.delete_alarm(alarm_id)
|
|
||||||
self.assertRaises(lib_exc.NotFound,
|
|
||||||
self.alarming_client.show_alarm, alarm_id)
|
|
||||||
|
|
||||||
@decorators.idempotent_id('aca49486-70bb-4016-87e0-f6131374f742')
|
|
||||||
def test_set_get_alarm_state(self):
|
|
||||||
alarm_states = ['ok', 'alarm', 'insufficient data']
|
|
||||||
alarm = self.create_alarm(
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=self.rule)
|
|
||||||
# Set alarm state and verify
|
|
||||||
new_state =\
|
|
||||||
[elem for elem in alarm_states if elem != alarm['state']][0]
|
|
||||||
state = self.alarming_client.alarm_set_state(alarm['alarm_id'],
|
|
||||||
new_state)
|
|
||||||
self.assertEqual(new_state, state.data)
|
|
||||||
# Get alarm state and verify
|
|
||||||
state = self.alarming_client.show_alarm_state(alarm['alarm_id'])
|
|
||||||
self.assertEqual(new_state, state.data)
|
|
|
@ -1,75 +0,0 @@
|
||||||
# Copyright 2015 GlobalLogic. All rights reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from oslo_utils import uuidutils
|
|
||||||
from tempest.lib.common.utils import data_utils
|
|
||||||
from tempest.lib import decorators
|
|
||||||
from tempest.lib import exceptions as lib_exc
|
|
||||||
|
|
||||||
from ceilometer.tests.tempest.aodh.api import base
|
|
||||||
|
|
||||||
|
|
||||||
class TelemetryAlarmingNegativeTest(base.BaseAlarmingTest):
|
|
||||||
"""Negative tests for show_alarm, update_alarm, show_alarm_history tests
|
|
||||||
|
|
||||||
** show non-existent alarm
|
|
||||||
** show the deleted alarm
|
|
||||||
** delete deleted alarm
|
|
||||||
** update deleted alarm
|
|
||||||
"""
|
|
||||||
|
|
||||||
@decorators.attr(type=['negative'])
|
|
||||||
@decorators.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81e7e')
|
|
||||||
def test_get_non_existent_alarm(self):
|
|
||||||
# get the non-existent alarm
|
|
||||||
non_existent_id = uuidutils.generate_uuid()
|
|
||||||
self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm,
|
|
||||||
non_existent_id)
|
|
||||||
|
|
||||||
@decorators.attr(type=['negative'])
|
|
||||||
@decorators.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2582ae')
|
|
||||||
def test_get_update_show_history_delete_deleted_alarm(self):
|
|
||||||
# get, update and delete the deleted alarm
|
|
||||||
alarm_name = data_utils.rand_name('telemetry_alarm')
|
|
||||||
rule = {'metrics': ["c0d457b6-957e-41de-a384-d5eb0957de3b"],
|
|
||||||
'aggregation_method': 'mean',
|
|
||||||
'comparison_operator': 'eq',
|
|
||||||
'threshold': 100.0,
|
|
||||||
'granularity': 90}
|
|
||||||
body = self.alarming_client.create_alarm(
|
|
||||||
name=alarm_name,
|
|
||||||
type='gnocchi_aggregation_by_metrics_threshold',
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=rule)
|
|
||||||
alarm_id = body['alarm_id']
|
|
||||||
self.alarming_client.delete_alarm(alarm_id)
|
|
||||||
# get the deleted alarm
|
|
||||||
self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm,
|
|
||||||
alarm_id)
|
|
||||||
|
|
||||||
# update the deleted alarm
|
|
||||||
updated_alarm_name = data_utils.rand_name('telemetry_alarm_updated')
|
|
||||||
updated_rule = {'metrics': ["c0d457b6-957e-41de-a384-d5eb0957de3b"],
|
|
||||||
'comparison_operator': 'eq',
|
|
||||||
'aggregation_method': 'mean',
|
|
||||||
'threshold': 70,
|
|
||||||
'granularity': 50}
|
|
||||||
self.assertRaises(
|
|
||||||
lib_exc.NotFound, self.alarming_client.update_alarm,
|
|
||||||
alarm_id,
|
|
||||||
gnocchi_aggregation_by_metrics_threshold_rule=updated_rule,
|
|
||||||
name=updated_alarm_name,
|
|
||||||
type='gnocchi_aggregation_by_metrics_threshold')
|
|
||||||
# delete the deleted alarm
|
|
||||||
self.assertRaises(lib_exc.NotFound, self.alarming_client.delete_alarm,
|
|
||||||
alarm_id)
|
|
|
@ -1,127 +0,0 @@
|
||||||
# Copyright 2014 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from six.moves.urllib import parse as urllib
|
|
||||||
from tempest import config
|
|
||||||
from tempest.lib.common import rest_client
|
|
||||||
from tempest import manager
|
|
||||||
|
|
||||||
CONF = config.CONF
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmingClient(rest_client.RestClient):
|
|
||||||
|
|
||||||
version = '2'
|
|
||||||
uri_prefix = "v2"
|
|
||||||
|
|
||||||
def deserialize(self, body):
|
|
||||||
return json.loads(body.replace("\n", ""))
|
|
||||||
|
|
||||||
def serialize(self, body):
|
|
||||||
return json.dumps(body)
|
|
||||||
|
|
||||||
def list_alarms(self, query=None):
|
|
||||||
uri = '%s/alarms' % self.uri_prefix
|
|
||||||
uri_dict = {}
|
|
||||||
if query:
|
|
||||||
uri_dict = {'q.field': query[0],
|
|
||||||
'q.op': query[1],
|
|
||||||
'q.value': query[2]}
|
|
||||||
if uri_dict:
|
|
||||||
uri += "?%s" % urllib.urlencode(uri_dict)
|
|
||||||
resp, body = self.get(uri)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBodyList(resp, body)
|
|
||||||
|
|
||||||
def show_alarm(self, alarm_id):
|
|
||||||
uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
|
|
||||||
resp, body = self.get(uri)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBody(resp, body)
|
|
||||||
|
|
||||||
def show_alarm_history(self, alarm_id):
|
|
||||||
uri = "%s/alarms/%s/history" % (self.uri_prefix, alarm_id)
|
|
||||||
resp, body = self.get(uri)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBodyList(resp, body)
|
|
||||||
|
|
||||||
def delete_alarm(self, alarm_id):
|
|
||||||
uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
|
|
||||||
resp, body = self.delete(uri)
|
|
||||||
self.expected_success(204, resp.status)
|
|
||||||
if body:
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBody(resp, body)
|
|
||||||
|
|
||||||
def create_alarm(self, **kwargs):
|
|
||||||
uri = "%s/alarms" % self.uri_prefix
|
|
||||||
body = self.serialize(kwargs)
|
|
||||||
resp, body = self.post(uri, body)
|
|
||||||
self.expected_success(201, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBody(resp, body)
|
|
||||||
|
|
||||||
def update_alarm(self, alarm_id, **kwargs):
|
|
||||||
uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
|
|
||||||
body = self.serialize(kwargs)
|
|
||||||
resp, body = self.put(uri, body)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBody(resp, body)
|
|
||||||
|
|
||||||
def show_alarm_state(self, alarm_id):
|
|
||||||
uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
|
|
||||||
resp, body = self.get(uri)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBodyData(resp, body)
|
|
||||||
|
|
||||||
def alarm_set_state(self, alarm_id, state):
|
|
||||||
uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
|
|
||||||
body = self.serialize(state)
|
|
||||||
resp, body = self.put(uri, body)
|
|
||||||
self.expected_success(200, resp.status)
|
|
||||||
body = self.deserialize(body)
|
|
||||||
return rest_client.ResponseBodyData(resp, body)
|
|
||||||
|
|
||||||
|
|
||||||
class Manager(manager.Manager):
|
|
||||||
|
|
||||||
default_params = {
|
|
||||||
'disable_ssl_certificate_validation':
|
|
||||||
CONF.identity.disable_ssl_certificate_validation,
|
|
||||||
'ca_certs': CONF.identity.ca_certificates_file,
|
|
||||||
'trace_requests': CONF.debug.trace_requests
|
|
||||||
}
|
|
||||||
|
|
||||||
alarming_params = {
|
|
||||||
'service': CONF.alarming_plugin.catalog_type,
|
|
||||||
'region': CONF.identity.region,
|
|
||||||
'endpoint_type': CONF.alarming_plugin.endpoint_type,
|
|
||||||
}
|
|
||||||
alarming_params.update(default_params)
|
|
||||||
|
|
||||||
def __init__(self, credentials=None, service=None):
|
|
||||||
super(Manager, self).__init__(credentials)
|
|
||||||
self.set_alarming_client()
|
|
||||||
|
|
||||||
def set_alarming_client(self):
|
|
||||||
self.alarming_client = AlarmingClient(self.auth_provider,
|
|
||||||
**self.alarming_params)
|
|
|
@ -1,77 +0,0 @@
|
||||||
# Copyright 2012 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
|
||||||
|
|
||||||
|
|
||||||
service_option = [cfg.BoolOpt('ceilometer',
|
|
||||||
default=True,
|
|
||||||
help="Whether or not Ceilometer is expected to"
|
|
||||||
"be available"),
|
|
||||||
cfg.BoolOpt('panko',
|
|
||||||
default=True,
|
|
||||||
help="Whether or not Panko is expected to be"
|
|
||||||
"available"),
|
|
||||||
cfg.BoolOpt("aodh_plugin",
|
|
||||||
default=True,
|
|
||||||
help="Whether or not Aodh is expected to be"
|
|
||||||
"available")]
|
|
||||||
|
|
||||||
telemetry_group = cfg.OptGroup(name='telemetry',
|
|
||||||
title='Telemetry Service Options')
|
|
||||||
|
|
||||||
event_group = cfg.OptGroup(name='event',
|
|
||||||
title='Event Service Options')
|
|
||||||
|
|
||||||
alarming_group = cfg.OptGroup(name='alarming_plugin',
|
|
||||||
title='Alarming Service Options')
|
|
||||||
|
|
||||||
TelemetryGroup = [
|
|
||||||
cfg.IntOpt('notification_wait',
|
|
||||||
default=120,
|
|
||||||
help="The seconds to wait for notifications which "
|
|
||||||
"containers and objects sent to swift."),
|
|
||||||
cfg.IntOpt('notification_sleep',
|
|
||||||
default=1,
|
|
||||||
help="The seconds to sleep after an unsuccessful "
|
|
||||||
"notification received."),
|
|
||||||
cfg.IntOpt('alarm_granularity',
|
|
||||||
default=300,
|
|
||||||
help="Granularity to use for aodh alarms. This must match the "
|
|
||||||
"configured Gnocchi archive policy")
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
event_opts = [
|
|
||||||
cfg.StrOpt('catalog_type',
|
|
||||||
default='event',
|
|
||||||
help="Catalog type of the Event service."),
|
|
||||||
cfg.StrOpt('endpoint_type',
|
|
||||||
default='publicURL',
|
|
||||||
choices=['public', 'admin', 'internal',
|
|
||||||
'publicURL', 'adminURL', 'internalURL'],
|
|
||||||
help="The endpoint type to use for the event service."),
|
|
||||||
]
|
|
||||||
|
|
||||||
AlarmingGroup = [
|
|
||||||
cfg.StrOpt('catalog_type',
|
|
||||||
default='alarming',
|
|
||||||
help="Catalog type of the Alarming service."),
|
|
||||||
cfg.StrOpt('endpoint_type',
|
|
||||||
default='publicURL',
|
|
||||||
choices=['public', 'admin', 'internal',
|
|
||||||
'publicURL', 'adminURL', 'internalURL'],
|
|
||||||
help="The endpoint type to use for the alarming service."),
|
|
||||||
]
|
|
|
@ -1,169 +0,0 @@
|
||||||
# Copyright 2012 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import testtools
|
|
||||||
|
|
||||||
|
|
||||||
class TempestException(Exception):
|
|
||||||
"""Base Tempest Exception
|
|
||||||
|
|
||||||
To correctly use this class, inherit from it and define
|
|
||||||
a 'message' property. That message will get printf'd
|
|
||||||
with the keyword arguments provided to the constructor.
|
|
||||||
"""
|
|
||||||
message = "An unknown exception occurred"
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(TempestException, self).__init__()
|
|
||||||
try:
|
|
||||||
self._error_string = self.message % kwargs
|
|
||||||
except Exception:
|
|
||||||
# at least get the core message out if something happened
|
|
||||||
self._error_string = self.message
|
|
||||||
if len(args) > 0:
|
|
||||||
# If there is a non-kwarg parameter, assume it's the error
|
|
||||||
# message or reason description and tack it on to the end
|
|
||||||
# of the exception message
|
|
||||||
# Convert all arguments into their string representations...
|
|
||||||
args = ["%s" % arg for arg in args]
|
|
||||||
self._error_string = (self._error_string +
|
|
||||||
"\nDetails: %s" % '\n'.join(args))
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._error_string
|
|
||||||
|
|
||||||
|
|
||||||
class RestClientException(TempestException,
|
|
||||||
testtools.TestCase.failureException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidConfiguration(TempestException):
|
|
||||||
message = "Invalid Configuration"
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidCredentials(TempestException):
|
|
||||||
message = "Invalid Credentials"
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidServiceTag(TempestException):
|
|
||||||
message = "Invalid service tag"
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidIdentityVersion(TempestException):
|
|
||||||
message = "Invalid version %(identity_version)s of the identity service"
|
|
||||||
|
|
||||||
|
|
||||||
class TimeoutException(TempestException):
|
|
||||||
message = "Request timed out"
|
|
||||||
|
|
||||||
|
|
||||||
class BuildErrorException(TempestException):
|
|
||||||
message = "Server %(server_id)s failed to build and is in ERROR status"
|
|
||||||
|
|
||||||
|
|
||||||
class ImageKilledException(TempestException):
|
|
||||||
message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
|
|
||||||
|
|
||||||
|
|
||||||
class AddImageException(TempestException):
|
|
||||||
message = "Image %(image_id)s failed to become ACTIVE in the allotted time"
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeBuildErrorException(TempestException):
|
|
||||||
message = "Volume %(volume_id)s failed to build and is in ERROR status"
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeRestoreErrorException(TempestException):
|
|
||||||
message = "Volume %(volume_id)s failed to restore and is in ERROR status"
|
|
||||||
|
|
||||||
|
|
||||||
class SnapshotBuildErrorException(TempestException):
|
|
||||||
message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeBackupException(TempestException):
|
|
||||||
message = "Volume backup %(backup_id)s failed and is in ERROR status"
|
|
||||||
|
|
||||||
|
|
||||||
class StackBuildErrorException(TempestException):
|
|
||||||
message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
|
|
||||||
"due to '%(stack_status_reason)s'")
|
|
||||||
|
|
||||||
|
|
||||||
class EndpointNotFound(TempestException):
|
|
||||||
message = "Endpoint not found"
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityError(TempestException):
|
|
||||||
message = "Got identity error"
|
|
||||||
|
|
||||||
|
|
||||||
class ServerUnreachable(TempestException):
|
|
||||||
message = "The server is not reachable via the configured network"
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE(andreaf) This exception is added here to facilitate the migration
|
|
||||||
# of get_network_from_name and preprov_creds to tempest.lib, and it should
|
|
||||||
# be migrated along with them
|
|
||||||
class InvalidTestResource(TempestException):
|
|
||||||
message = "%(name)s is not a valid %(type)s, or the name is ambiguous"
|
|
||||||
|
|
||||||
|
|
||||||
class RFCViolation(RestClientException):
|
|
||||||
message = "RFC Violation"
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidHttpSuccessCode(RestClientException):
|
|
||||||
message = "The success code is different than the expected one"
|
|
||||||
|
|
||||||
|
|
||||||
class BadRequest(RestClientException):
|
|
||||||
message = "Bad request"
|
|
||||||
|
|
||||||
|
|
||||||
class ResponseWithNonEmptyBody(RFCViolation):
|
|
||||||
message = ("RFC Violation! Response with %(status)d HTTP Status Code "
|
|
||||||
"MUST NOT have a body")
|
|
||||||
|
|
||||||
|
|
||||||
class ResponseWithEntity(RFCViolation):
|
|
||||||
message = ("RFC Violation! Response with 205 HTTP Status Code "
|
|
||||||
"MUST NOT have an entity")
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidHTTPResponseHeader(RestClientException):
|
|
||||||
message = "HTTP response header is invalid"
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidStructure(TempestException):
|
|
||||||
message = "Invalid structure of table with details"
|
|
||||||
|
|
||||||
|
|
||||||
class CommandFailed(Exception):
|
|
||||||
def __init__(self, returncode, cmd, output, stderr):
|
|
||||||
super(CommandFailed, self).__init__()
|
|
||||||
self.returncode = returncode
|
|
||||||
self.cmd = cmd
|
|
||||||
self.stdout = output
|
|
||||||
self.stderr = stderr
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return ("Command '%s' returned non-zero exit status %d.\n"
|
|
||||||
"stdout:\n%s\n"
|
|
||||||
"stderr:\n%s" % (self.cmd,
|
|
||||||
self.returncode,
|
|
||||||
self.stdout,
|
|
||||||
self.stderr))
|
|
|
@ -1,56 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright 2015 NEC Corporation.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from tempest import config
|
|
||||||
from tempest.test_discover import plugins
|
|
||||||
|
|
||||||
import ceilometer
|
|
||||||
from ceilometer.tests.tempest import config as tempest_config
|
|
||||||
|
|
||||||
|
|
||||||
class CeilometerTempestPlugin(plugins.TempestPlugin):
|
|
||||||
|
|
||||||
def load_tests(self):
|
|
||||||
base_path = os.path.split(os.path.dirname(
|
|
||||||
os.path.abspath(ceilometer.__file__)))[0]
|
|
||||||
test_dir = "ceilometer/tests/tempest"
|
|
||||||
full_test_dir = os.path.join(base_path, test_dir)
|
|
||||||
return full_test_dir, base_path
|
|
||||||
|
|
||||||
def register_opts(self, conf):
|
|
||||||
config.register_opt_group(
|
|
||||||
conf, config.service_available_group,
|
|
||||||
tempest_config.service_option)
|
|
||||||
config.register_opt_group(
|
|
||||||
conf, tempest_config.telemetry_group,
|
|
||||||
tempest_config.TelemetryGroup)
|
|
||||||
config.register_opt_group(
|
|
||||||
conf, tempest_config.event_group,
|
|
||||||
tempest_config.event_opts)
|
|
||||||
config.register_opt_group(
|
|
||||||
conf, tempest_config.alarming_group,
|
|
||||||
tempest_config.AlarmingGroup)
|
|
||||||
|
|
||||||
def get_opt_lists(self):
|
|
||||||
return [(tempest_config.telemetry_group.name,
|
|
||||||
tempest_config.TelemetryGroup),
|
|
||||||
(tempest_config.event_group.name,
|
|
||||||
tempest_config.event_opts),
|
|
||||||
(config.service_available_group.name,
|
|
||||||
tempest_config.service_option),
|
|
||||||
(tempest_config.alarming_group.name,
|
|
||||||
tempest_config.AlarmingGroup)]
|
|
|
@ -1,143 +0,0 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from gabbi import runner
|
|
||||||
from gabbi import suitemaker
|
|
||||||
from gabbi import utils
|
|
||||||
from tempest import config
|
|
||||||
from tempest.scenario import manager
|
|
||||||
|
|
||||||
TEST_DIR = os.path.join(os.path.dirname(__file__), '..', '..',
|
|
||||||
'integration', 'gabbi', 'gabbits-live')
|
|
||||||
|
|
||||||
|
|
||||||
class TestTelemetryIntegration(manager.ScenarioTest):
|
|
||||||
credentials = ['admin', 'primary']
|
|
||||||
|
|
||||||
TIMEOUT_SCALING_FACTOR = 5
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def skip_checks(cls):
|
|
||||||
super(TestTelemetryIntegration, cls).skip_checks()
|
|
||||||
for name in ["aodh_plugin", "gnocchi", "nova", "heat", "panko",
|
|
||||||
"ceilometer", "glance"]:
|
|
||||||
cls._check_service(name)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _check_service(cls, name):
|
|
||||||
if not getattr(config.CONF.service_available, name, False):
|
|
||||||
raise cls.skipException("%s support is required" %
|
|
||||||
name.capitalize())
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _get_endpoint(auth, service):
|
|
||||||
opt_section = getattr(config.CONF, service)
|
|
||||||
endpoint_type = opt_section.endpoint_type
|
|
||||||
is_keystone_v3 = 'catalog' in auth[1]
|
|
||||||
|
|
||||||
if is_keystone_v3:
|
|
||||||
if endpoint_type.endswith("URL"):
|
|
||||||
endpoint_type = endpoint_type[:-3]
|
|
||||||
catalog = auth[1]['catalog']
|
|
||||||
endpoints = [e['endpoints'] for e in catalog
|
|
||||||
if e['type'] == opt_section.catalog_type]
|
|
||||||
if not endpoints:
|
|
||||||
raise Exception("%s endpoint not found" %
|
|
||||||
opt_section.catalog_type)
|
|
||||||
endpoints = [e['url'] for e in endpoints[0]
|
|
||||||
if e['interface'] == endpoint_type]
|
|
||||||
if not endpoints:
|
|
||||||
raise Exception("%s interface not found for endpoint %s" %
|
|
||||||
(endpoint_type,
|
|
||||||
opt_section.catalog_type))
|
|
||||||
return endpoints[0]
|
|
||||||
|
|
||||||
else:
|
|
||||||
if not endpoint_type.endswith("URL"):
|
|
||||||
endpoint_type += "URL"
|
|
||||||
catalog = auth[1]['serviceCatalog']
|
|
||||||
endpoints = [e for e in catalog
|
|
||||||
if e['type'] == opt_section.catalog_type]
|
|
||||||
if not endpoints:
|
|
||||||
raise Exception("%s endpoint not found" %
|
|
||||||
opt_section.catalog_type)
|
|
||||||
return endpoints[0]['endpoints'][0][endpoint_type]
|
|
||||||
|
|
||||||
def _do_test(self, filename):
|
|
||||||
admin_auth = self.os_admin.auth_provider.get_auth()
|
|
||||||
auth = self.os_primary.auth_provider.get_auth()
|
|
||||||
networks = self.os_primary.networks_client.list_networks(
|
|
||||||
**{'router:external': False, 'fields': 'id'})['networks']
|
|
||||||
|
|
||||||
os.environ.update({
|
|
||||||
"ADMIN_TOKEN": admin_auth[0],
|
|
||||||
"USER_TOKEN": auth[0],
|
|
||||||
"AODH_GRANULARITY": str(config.CONF.telemetry.alarm_granularity),
|
|
||||||
"AODH_SERVICE_URL": self._get_endpoint(auth, "alarming_plugin"),
|
|
||||||
"GNOCCHI_SERVICE_URL": self._get_endpoint(auth, "metric"),
|
|
||||||
"PANKO_SERVICE_URL": self._get_endpoint(auth, "event"),
|
|
||||||
"HEAT_SERVICE_URL": self._get_endpoint(auth, "orchestration"),
|
|
||||||
"NOVA_SERVICE_URL": self._get_endpoint(auth, "compute"),
|
|
||||||
"GLANCE_SERVICE_URL": self._get_endpoint(auth, "image"),
|
|
||||||
"GLANCE_IMAGE_NAME": self.glance_image_create(),
|
|
||||||
"NOVA_FLAVOR_REF": config.CONF.compute.flavor_ref,
|
|
||||||
"NEUTRON_NETWORK": networks[0].get('id'),
|
|
||||||
})
|
|
||||||
|
|
||||||
with open(os.path.join(TEST_DIR, filename)) as f:
|
|
||||||
test_suite = suitemaker.test_suite_from_dict(
|
|
||||||
loader=unittest.defaultTestLoader,
|
|
||||||
test_base_name="gabbi",
|
|
||||||
suite_dict=utils.load_yaml(f),
|
|
||||||
test_directory=TEST_DIR,
|
|
||||||
host=None, port=None,
|
|
||||||
fixture_module=None,
|
|
||||||
intercept=None,
|
|
||||||
handlers=runner.initialize_handlers([]),
|
|
||||||
test_loader_name="tempest")
|
|
||||||
|
|
||||||
# NOTE(sileht): We hide stdout/stderr and reraise the failure
|
|
||||||
# manually, tempest will print it itself.
|
|
||||||
with open(os.devnull, 'w') as stream:
|
|
||||||
result = unittest.TextTestRunner(
|
|
||||||
stream=stream, verbosity=0, failfast=True,
|
|
||||||
).run(test_suite)
|
|
||||||
|
|
||||||
if not result.wasSuccessful():
|
|
||||||
failures = (result.errors + result.failures +
|
|
||||||
result.unexpectedSuccesses)
|
|
||||||
if failures:
|
|
||||||
test, bt = failures[0]
|
|
||||||
name = test.test_data.get('name', test.id())
|
|
||||||
msg = 'From test "%s" :\n%s' % (name, bt)
|
|
||||||
self.fail(msg)
|
|
||||||
|
|
||||||
self.assertTrue(result.wasSuccessful())
|
|
||||||
|
|
||||||
|
|
||||||
def test_maker(name, filename):
|
|
||||||
def test(self):
|
|
||||||
self._do_test(filename)
|
|
||||||
test.__name__ = name
|
|
||||||
return test
|
|
||||||
|
|
||||||
|
|
||||||
# Create one scenario per yaml file
|
|
||||||
for filename in os.listdir(TEST_DIR):
|
|
||||||
if not filename.endswith('.yaml'):
|
|
||||||
continue
|
|
||||||
name = "test_%s" % filename[:-5].lower().replace("-", "_")
|
|
||||||
setattr(TestTelemetryIntegration, name,
|
|
||||||
test_maker(name, filename))
|
|
|
@ -275,9 +275,6 @@ oslo.config.opts =
|
||||||
ceilometer = ceilometer.opts:list_opts
|
ceilometer = ceilometer.opts:list_opts
|
||||||
ceilometer-auth = ceilometer.opts:list_keystoneauth_opts
|
ceilometer-auth = ceilometer.opts:list_keystoneauth_opts
|
||||||
|
|
||||||
tempest.test_plugins =
|
|
||||||
ceilometer_tests = ceilometer.tests.tempest.plugin:CeilometerTempestPlugin
|
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
all_files = 1
|
all_files = 1
|
||||||
build-dir = doc/build
|
build-dir = doc/build
|
||||||
|
|
|
@ -19,5 +19,4 @@ testtools>=1.4.0 # MIT
|
||||||
gabbi>=1.30.0 # Apache-2.0
|
gabbi>=1.30.0 # Apache-2.0
|
||||||
requests-aws>=0.1.4 # BSD License (3 clause)
|
requests-aws>=0.1.4 # BSD License (3 clause)
|
||||||
os-testr>=0.4.1 # Apache-2.0
|
os-testr>=0.4.1 # Apache-2.0
|
||||||
tempest>=14.0.0 # Apache-2.0
|
|
||||||
kafka-python>=1.3.2 # Apache-2.0
|
kafka-python>=1.3.2 # Apache-2.0
|
||||||
|
|
Loading…
Reference in New Issue