Moved gnocchi tempest tests under telemetry tempest plugin
* In order to achieve tempest plugin split goal, we have merged aodh, panko, ceilometer and gnocchi tempest plugin into telemetry tempest plugin * gnocchi/tempest -> telemetry_tempest_plugin/gnocchi * gnocchi/tests/functional_live -> telemetry_tempest_plugin/gnocchi Change-Id: Icf6789afc143db3206af409c62a36e56edefd142
This commit is contained in:
parent
547e356cd4
commit
d9a10fe680
|
@ -27,6 +27,10 @@ service_option = [cfg.BoolOpt('ceilometer',
|
|||
cfg.BoolOpt("aodh_plugin",
|
||||
default=True,
|
||||
help="Whether or not Aodh is expected to be"
|
||||
"available"),
|
||||
cfg.BoolOpt('gnocchi',
|
||||
default=True,
|
||||
help="Whether or not Gnocchi is expected to be"
|
||||
"available")]
|
||||
|
||||
telemetry_group = cfg.OptGroup(name='telemetry',
|
||||
|
@ -38,6 +42,9 @@ event_group = cfg.OptGroup(name='event',
|
|||
alarming_group = cfg.OptGroup(name='alarming_plugin',
|
||||
title='Alarming Service Options')
|
||||
|
||||
metric_group = cfg.OptGroup(name='metric',
|
||||
title='Metric Service Options')
|
||||
|
||||
TelemetryGroup = [
|
||||
cfg.IntOpt('notification_wait',
|
||||
default=120,
|
||||
|
@ -75,3 +82,14 @@ AlarmingGroup = [
|
|||
'publicURL', 'adminURL', 'internalURL'],
|
||||
help="The endpoint type to use for the alarming service."),
|
||||
]
|
||||
|
||||
metric_opts = [
|
||||
cfg.StrOpt('catalog_type',
|
||||
default='metric',
|
||||
help="Catalog type of the Metric service."),
|
||||
cfg.StrOpt('endpoint_type',
|
||||
default='publicURL',
|
||||
choices=['public', 'admin', 'internal',
|
||||
'publicURL', 'adminURL', 'internalURL'],
|
||||
help="The endpoint type to use for the metric service."),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,739 @@
|
|||
#
|
||||
# Confirmation tests to run against a live web server.
|
||||
#
|
||||
# These act as a very basic sanity check.
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: $ENVIRON['GNOCCHI_SERVICE_TOKEN']
|
||||
authorization: $ENVIRON['GNOCCHI_AUTHORIZATION']
|
||||
|
||||
tests:
|
||||
- name: check /
|
||||
GET: /
|
||||
|
||||
# Fail to create archive policy
|
||||
- name: wrong archive policy content type
|
||||
desc: attempt to create archive policy with invalid content-type
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: text/plain
|
||||
status: 415
|
||||
response_strings:
|
||||
- Unsupported Media Type
|
||||
|
||||
- name: wrong method
|
||||
desc: attempt to create archive policy with 'PUT' method
|
||||
PUT: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
status: 405
|
||||
|
||||
- name: invalid authZ
|
||||
desc: x-auth-token is invalid
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
x-auth-token: 'hello'
|
||||
authorization: 'basic hello:'
|
||||
data:
|
||||
name: medium
|
||||
definition:
|
||||
- granularity: 1 second
|
||||
status: 401
|
||||
|
||||
- name: bad archive policy body
|
||||
desc: archive policy contains invalid key 'cowsay'
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
cowsay: moo
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: extra keys not allowed"
|
||||
|
||||
- name: missing definition
|
||||
desc: archive policy is missing 'definition' keyword
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: medium
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: required key not provided"
|
||||
|
||||
- name: empty definition
|
||||
desc: empty definition for archive policy
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: medium
|
||||
definition: []
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: length of value must be at least 1"
|
||||
|
||||
- name: wrong value definition
|
||||
desc: invalid type of 'definition' key
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: somename
|
||||
definition: foobar
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: expected a list"
|
||||
|
||||
- name: useless definition
|
||||
desc: invalid archive policy definition
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: medium
|
||||
definition:
|
||||
- cowsay: moo
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: extra keys not allowed"
|
||||
|
||||
#
|
||||
# Create archive policy
|
||||
#
|
||||
|
||||
- name: create archive policy
|
||||
desc: create archve policy 'gabbilive' for live tests
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: gabbilive
|
||||
back_window: 0
|
||||
definition:
|
||||
- granularity: 1 second
|
||||
points: 60
|
||||
- granularity: 2 second
|
||||
timespan: 1 minute
|
||||
- points: 5
|
||||
timespan: 5 minute
|
||||
aggregation_methods:
|
||||
- mean
|
||||
- min
|
||||
- max
|
||||
response_headers:
|
||||
location: $SCHEME://$NETLOC/v1/archive_policy/gabbilive
|
||||
status: 201
|
||||
|
||||
# Retrieve it correctly and then poorly
|
||||
|
||||
- name: get archive policy
|
||||
desc: retrieve archive policy 'gabbilive' and asster its values
|
||||
GET: $LOCATION
|
||||
response_headers:
|
||||
content-type: /application/json/
|
||||
response_json_paths:
|
||||
$.name: gabbilive
|
||||
$.back_window: 0
|
||||
$.definition[0].granularity: "0:00:01"
|
||||
$.definition[0].points: 60
|
||||
$.definition[0].timespan: "0:01:00"
|
||||
$.definition[1].granularity: "0:00:02"
|
||||
$.definition[1].points: 30
|
||||
$.definition[1].timespan: "0:01:00"
|
||||
$.definition[2].granularity: "0:01:00"
|
||||
$.definition[2].points: 5
|
||||
$.definition[2].timespan: "0:05:00"
|
||||
response_json_paths:
|
||||
$.aggregation_methods.`sorted`: ["max", "mean", "min"]
|
||||
|
||||
- name: get wrong accept
|
||||
desc: invalid 'accept' header
|
||||
GET: /v1/archive_policy/medium
|
||||
request_headers:
|
||||
accept: text/plain
|
||||
status: 406
|
||||
|
||||
# Unexpected methods
|
||||
|
||||
- name: post single archive
|
||||
desc: unexpected 'POST' request to archive policy
|
||||
POST: /v1/archive_policy/gabbilive
|
||||
status: 405
|
||||
|
||||
- name: put single archive
|
||||
desc: unexpected 'PUT' request to archive policy
|
||||
PUT: /v1/archive_policy/gabbilive
|
||||
status: 405
|
||||
|
||||
# Duplicated archive policy names ain't allowed
|
||||
|
||||
- name: create duplicate archive policy
|
||||
desc: create archve policy 'gabbilive' for live tests
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: gabbilive
|
||||
definition:
|
||||
- granularity: 30 second
|
||||
points: 60
|
||||
status: 409
|
||||
response_strings:
|
||||
- Archive policy gabbilive already exists
|
||||
|
||||
# Create a unicode named policy
|
||||
|
||||
- name: post unicode policy name
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: ✔éñ☃
|
||||
definition:
|
||||
- granularity: 1 minute
|
||||
points: 20
|
||||
status: 201
|
||||
response_headers:
|
||||
location: $SCHEME://$NETLOC/v1/archive_policy/%E2%9C%94%C3%A9%C3%B1%E2%98%83
|
||||
response_json_paths:
|
||||
name: ✔éñ☃
|
||||
|
||||
- name: retrieve unicode policy name
|
||||
GET: $LOCATION
|
||||
response_json_paths:
|
||||
name: ✔éñ☃
|
||||
|
||||
- name: delete unicode archive policy
|
||||
DELETE: /v1/archive_policy/%E2%9C%94%C3%A9%C3%B1%E2%98%83
|
||||
status: 204
|
||||
|
||||
# It really is gone
|
||||
|
||||
- name: confirm delete
|
||||
desc: assert deleted unicode policy is not available
|
||||
GET: /v1/archive_policy/%E2%9C%94%C3%A9%C3%B1%E2%98%83
|
||||
status: 404
|
||||
|
||||
# Fail to delete one that does not exist
|
||||
|
||||
- name: delete missing archive
|
||||
desc: delete non-existent archive policy
|
||||
DELETE: /v1/archive_policy/grandiose
|
||||
status: 404
|
||||
response_strings:
|
||||
- Archive policy grandiose does not exist
|
||||
|
||||
# Attempt to create illogical policies
|
||||
|
||||
- name: create illogical policy
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: complex
|
||||
definition:
|
||||
- granularity: 1 second
|
||||
points: 60
|
||||
timespan: "0:01:01"
|
||||
status: 400
|
||||
response_strings:
|
||||
- timespan ≠ granularity × points
|
||||
|
||||
- name: create identical granularities policy
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: complex
|
||||
definition:
|
||||
- granularity: 1 second
|
||||
points: 60
|
||||
- granularity: 1 second
|
||||
points: 120
|
||||
status: 400
|
||||
response_strings:
|
||||
- "More than one archive policy uses granularity `1.0'"
|
||||
|
||||
- name: policy invalid unit
|
||||
desc: invalid unit for archive policy 'timespan' key
|
||||
POST: /v1/archive_policy
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: 227d0e1f-4295-4e4b-8515-c296c47d71d3
|
||||
definition:
|
||||
- granularity: 1 second
|
||||
timespan: "1 shenanigan"
|
||||
status: 400
|
||||
|
||||
#
|
||||
# Archive policy rules
|
||||
#
|
||||
|
||||
- name: create archive policy rule1
|
||||
POST: /v1/archive_policy_rule
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: gabbilive_rule
|
||||
metric_pattern: "live.*"
|
||||
archive_policy_name: gabbilive
|
||||
status: 201
|
||||
response_json_paths:
|
||||
$.metric_pattern: "live.*"
|
||||
$.archive_policy_name: gabbilive
|
||||
$.name: gabbilive_rule
|
||||
|
||||
- name: create invalid archive policy rule
|
||||
POST: /v1/archive_policy_rule
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: test_rule
|
||||
metric_pattern: "disk.foo.*"
|
||||
status: 400
|
||||
|
||||
- name: missing auth archive policy rule
|
||||
POST: /v1/archive_policy_rule
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
x-auth-token: 'hello'
|
||||
authorization: 'basic hello:'
|
||||
data:
|
||||
name: test_rule
|
||||
metric_pattern: "disk.foo.*"
|
||||
archive_policy_name: low
|
||||
status: 401
|
||||
|
||||
- name: wrong archive policy rule content type
|
||||
POST: /v1/archive_policy_rule
|
||||
request_headers:
|
||||
content-type: text/plain
|
||||
status: 415
|
||||
response_strings:
|
||||
- Unsupported Media Type
|
||||
|
||||
- name: bad archive policy rule body
|
||||
POST: /v1/archive_policy_rule
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
whaa: foobar
|
||||
status: 400
|
||||
response_strings:
|
||||
- "Invalid input: extra keys not allowed"
|
||||
|
||||
# get an archive policy rules
|
||||
|
||||
- name: get all archive policy rules
|
||||
GET: /v1/archive_policy_rule
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$[\name][0].name: "gabbilive_rule"
|
||||
$[\name][0].metric_pattern: "live.*"
|
||||
$[\name][0].archive_policy_name: "gabbilive"
|
||||
|
||||
- name: get unknown archive policy rule
|
||||
GET: /v1/archive_policy_rule/foo
|
||||
status: 404
|
||||
|
||||
|
||||
- name: get archive policy rule
|
||||
GET: /v1/archive_policy_rule/gabbilive_rule
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.metric_pattern: "live.*"
|
||||
$.archive_policy_name: "gabbilive"
|
||||
$.name: "gabbilive_rule"
|
||||
|
||||
- name: delete archive policy in use
|
||||
desc: fails due to https://bugs.launchpad.net/gnocchi/+bug/1569781
|
||||
DELETE: /v1/archive_policy/gabbilive
|
||||
status: 400
|
||||
|
||||
#
|
||||
# Metrics
|
||||
#
|
||||
|
||||
|
||||
- name: get all metrics
|
||||
GET: /v1/metric
|
||||
status: 200
|
||||
|
||||
- name: create metric with name and rule
|
||||
POST: /v1/metric
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: "live.io.rate"
|
||||
status: 201
|
||||
response_json_paths:
|
||||
$.archive_policy_name: gabbilive
|
||||
$.name: live.io.rate
|
||||
|
||||
- name: assert metric is present in listing
|
||||
GET: /v1/metric?id=$HISTORY['create metric with name and rule'].$RESPONSE['$.id']
|
||||
response_json_paths:
|
||||
$.`len`: 1
|
||||
|
||||
- name: assert metric is the only one with this policy
|
||||
GET: /v1/metric?archive_policy_name=gabbilive
|
||||
response_json_paths:
|
||||
$.`len`: 1
|
||||
|
||||
- name: delete metric
|
||||
DELETE: /v1/metric/$HISTORY['create metric with name and rule'].$RESPONSE['$.id']
|
||||
status: 204
|
||||
|
||||
- name: assert metric is expunged
|
||||
GET: $HISTORY['assert metric is present in listing'].$URL&status=delete
|
||||
poll:
|
||||
count: 360
|
||||
delay: 1
|
||||
response_json_paths:
|
||||
$.`len`: 0
|
||||
|
||||
- name: create metric with name and policy
|
||||
POST: /v1/metric
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: "aagabbi.live.metric"
|
||||
archive_policy_name: "gabbilive"
|
||||
status: 201
|
||||
response_json_paths:
|
||||
$.archive_policy_name: gabbilive
|
||||
$.name: "aagabbi.live.metric"
|
||||
|
||||
- name: get valid metric id
|
||||
GET: $LOCATION
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.archive_policy.name: gabbilive
|
||||
|
||||
- name: delete the metric
|
||||
DELETE: /v1/metric/$RESPONSE['$.id']
|
||||
status: 204
|
||||
|
||||
- name: ensure the metric is delete
|
||||
GET: /v1/metric/$HISTORY['get valid metric id'].$RESPONSE['$.id']
|
||||
status: 404
|
||||
|
||||
- name: create metric bad archive policy
|
||||
POST: /v1/metric
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
archive_policy_name: 2e2675aa-105e-4664-a30d-c407e6a0ea7f
|
||||
status: 400
|
||||
response_strings:
|
||||
- Archive policy 2e2675aa-105e-4664-a30d-c407e6a0ea7f does not exist
|
||||
|
||||
- name: create metric bad content-type
|
||||
POST: /v1/metric
|
||||
request_headers:
|
||||
content-type: plain/text
|
||||
data: '{"archive_policy_name": "cookies"}'
|
||||
status: 415
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
||||
- name: delete archive policy rule
|
||||
DELETE: /v1/archive_policy_rule/gabbilive_rule
|
||||
status: 204
|
||||
|
||||
- name: confirm delete archive policy rule
|
||||
DELETE: /v1/archive_policy_rule/gabbilive_rule
|
||||
status: 404
|
||||
|
||||
|
||||
#
|
||||
# Resources section
|
||||
#
|
||||
|
||||
- name: root of resource
|
||||
GET: /v1/resource
|
||||
response_json_paths:
|
||||
$.generic: $SCHEME://$NETLOC/v1/resource/generic
|
||||
|
||||
- name: typo of resource
|
||||
GET: /v1/resoue
|
||||
status: 404
|
||||
|
||||
- name: typo of resource extra
|
||||
GET: /v1/resource/foobar
|
||||
status: 404
|
||||
|
||||
- name: generic resource
|
||||
GET: /v1/resource/generic
|
||||
status: 200
|
||||
|
||||
- name: post resource type
|
||||
POST: /v1/resource_type
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: myresource
|
||||
attributes:
|
||||
display_name:
|
||||
type: string
|
||||
required: true
|
||||
max_length: 5
|
||||
min_length: 2
|
||||
status: 201
|
||||
response_headers:
|
||||
location: $SCHEME://$NETLOC/v1/resource_type/myresource
|
||||
|
||||
- name: add an attribute
|
||||
PATCH: /v1/resource_type/myresource
|
||||
request_headers:
|
||||
content-type: application/json-patch+json
|
||||
data:
|
||||
- op: "add"
|
||||
path: "/attributes/awesome-stuff"
|
||||
value: {"type": "bool", "required": false}
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.name: myresource
|
||||
$.attributes."awesome-stuff".type: bool
|
||||
$.attributes.[*].`len`: 2
|
||||
|
||||
- name: remove an attribute
|
||||
PATCH: /v1/resource_type/myresource
|
||||
request_headers:
|
||||
content-type: application/json-patch+json
|
||||
data:
|
||||
- op: "remove"
|
||||
path: "/attributes/awesome-stuff"
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.name: myresource
|
||||
$.attributes.display_name.type: string
|
||||
$.attributes.[*].`len`: 1
|
||||
|
||||
- name: myresource resource bad accept
|
||||
desc: Expect 406 on bad accept type
|
||||
request_headers:
|
||||
accept: text/plain
|
||||
GET: /v1/resource/myresource
|
||||
status: 406
|
||||
response_strings:
|
||||
- 406 Not Acceptable
|
||||
|
||||
- name: myresource resource complex accept
|
||||
desc: failover accept media type appropriately
|
||||
request_headers:
|
||||
accept: text/plain, application/json; q=0.8
|
||||
GET: /v1/resource/myresource
|
||||
status: 200
|
||||
|
||||
- name: post myresource resource
|
||||
POST: /v1/resource/myresource
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
id: 2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
user_id: 126204ef-989a-46fd-999b-ee45c8108f31
|
||||
project_id: 98e785d7-9487-4159-8ab8-8230ec37537a
|
||||
display_name: myvm
|
||||
metrics:
|
||||
vcpus:
|
||||
archive_policy_name: gabbilive
|
||||
status: 201
|
||||
response_json_paths:
|
||||
$.id: 2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
$.user_id: 126204ef-989a-46fd-999b-ee45c8108f31
|
||||
$.project_id: 98e785d7-9487-4159-8ab8-8230ec37537a
|
||||
$.display_name: "myvm"
|
||||
|
||||
- name: get myresource resource
|
||||
GET: $LOCATION
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.id: 2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
$.user_id: 126204ef-989a-46fd-999b-ee45c8108f31
|
||||
$.project_id: 98e785d7-9487-4159-8ab8-8230ec37537a
|
||||
$.display_name: "myvm"
|
||||
|
||||
- name: get vcpus metric
|
||||
GET: /v1/metric/$HISTORY['get myresource resource'].$RESPONSE['$.metrics.vcpus']
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.name: vcpus
|
||||
$.resource.id: 2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
|
||||
- name: search for myresource resource via user_id
|
||||
POST: /v1/search/resource/myresource
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
=:
|
||||
user_id: "126204ef-989a-46fd-999b-ee45c8108f31"
|
||||
response_json_paths:
|
||||
$..id: 2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
$..user_id: 126204ef-989a-46fd-999b-ee45c8108f31
|
||||
$..project_id: 98e785d7-9487-4159-8ab8-8230ec37537a
|
||||
$..display_name: myvm
|
||||
|
||||
- name: search for myresource resource via user_id and 'generic' type
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
=:
|
||||
id: "2ae35573-7f9f-4bb1-aae8-dad8dff5706e"
|
||||
response_strings:
|
||||
- '"user_id": "126204ef-989a-46fd-999b-ee45c8108f31"'
|
||||
|
||||
- name: search for myresource resource via user_id and project_id
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
and:
|
||||
- =:
|
||||
user_id: "126204ef-989a-46fd-999b-ee45c8108f31"
|
||||
- =:
|
||||
project_id: "98e785d7-9487-4159-8ab8-8230ec37537a"
|
||||
response_strings:
|
||||
- '"id": "2ae35573-7f9f-4bb1-aae8-dad8dff5706e"'
|
||||
|
||||
- name: patch myresource resource
|
||||
PATCH: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
display_name: myvm2
|
||||
status: 200
|
||||
response_json_paths:
|
||||
display_name: myvm2
|
||||
|
||||
- name: post some measures to the metric on myresource
|
||||
POST: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e/metric/vcpus/measures
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
- timestamp: "2015-03-06T14:33:57"
|
||||
value: 2
|
||||
- timestamp: "2015-03-06T14:34:12"
|
||||
value: 2
|
||||
status: 202
|
||||
|
||||
- name: get myresource measures with poll
|
||||
GET: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e/metric/vcpus/measures
|
||||
# wait up to 60 seconds before policy is deleted
|
||||
poll:
|
||||
count: 60
|
||||
delay: 1
|
||||
response_json_paths:
|
||||
$[0][2]: 2
|
||||
$[1][2]: 2
|
||||
|
||||
- name: post some more measures to the metric on myresource
|
||||
POST: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e/metric/vcpus/measures
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
- timestamp: "2015-03-06T14:34:15"
|
||||
value: 5
|
||||
- timestamp: "2015-03-06T14:34:20"
|
||||
value: 5
|
||||
status: 202
|
||||
|
||||
- name: get myresource measures with refresh
|
||||
GET: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e/metric/vcpus/measures?refresh=true
|
||||
response_json_paths:
|
||||
$[0][2]: 2
|
||||
$[1][2]: 4
|
||||
$[2][2]: 2
|
||||
$[3][2]: 2
|
||||
$[4][2]: 5
|
||||
$[5][2]: 5
|
||||
|
||||
#
|
||||
# Search for resources
|
||||
#
|
||||
|
||||
- name: typo of search
|
||||
POST: /v1/search/notexists
|
||||
status: 404
|
||||
|
||||
- name: typo of search in resource
|
||||
POST: /v1/search/resource/foobar
|
||||
status: 404
|
||||
|
||||
- name: search with invalid uuid
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
=:
|
||||
id: "cd9eef"
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.`len`: 0
|
||||
|
||||
- name: assert vcpus metric exists in listing
|
||||
GET: /v1/metric?id=$HISTORY['get myresource resource'].$RESPONSE['$.metrics.vcpus']
|
||||
poll:
|
||||
count: 360
|
||||
delay: 1
|
||||
response_json_paths:
|
||||
$.`len`: 1
|
||||
|
||||
- name: delete myresource resource
|
||||
DELETE: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
status: 204
|
||||
|
||||
# assert resource is really deleted
|
||||
- name: assert resource resource is deleted
|
||||
GET: /v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e
|
||||
status: 404
|
||||
|
||||
- name: assert vcpus metric is really expurged
|
||||
GET: $HISTORY['assert vcpus metric exists in listing'].$URL&status=delete
|
||||
poll:
|
||||
count: 360
|
||||
delay: 1
|
||||
response_json_paths:
|
||||
$.`len`: 0
|
||||
|
||||
- name: post myresource resource no data
|
||||
POST: /v1/resource/myresource
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
status: 400
|
||||
|
||||
- name: assert no metrics have the gabbilive policy
|
||||
GET: $HISTORY['assert metric is the only one with this policy'].$URL
|
||||
response_json_paths:
|
||||
$.`len`: 0
|
||||
|
||||
- name: assert no delete metrics have the gabbilive policy
|
||||
GET: $HISTORY['assert metric is the only one with this policy'].$URL&status=delete
|
||||
response_json_paths:
|
||||
$.`len`: 0
|
||||
|
||||
- name: delete single archive policy cleanup
|
||||
DELETE: /v1/archive_policy/gabbilive
|
||||
poll:
|
||||
count: 360
|
||||
delay: 1
|
||||
status: 204
|
||||
|
||||
# It really is gone
|
||||
|
||||
- name: delete our resource type
|
||||
DELETE: /v1/resource_type/myresource
|
||||
status: 204
|
||||
|
||||
- name: confirm delete of cleanup
|
||||
GET: /v1/archive_policy/gabbilive
|
||||
status: 404
|
|
@ -0,0 +1,275 @@
|
|||
#
|
||||
# Tests to confirm resources are searchable. Run against a live setup.
|
||||
# URL: http://gnocchi.xyz/rest.html#searching-for-resources
|
||||
#
|
||||
# Instance-ResourceID-1: a64ca14f-bc7c-45b0-aa85-42cd2179e1e2
|
||||
# Instance-ResourceID-2: 7ccccfa0-92ce-4225-80ca-3ac9cb122d6a
|
||||
# Instance-ResourceID-3: c442a47c-eb33-46ce-9665-f3aa0bef54e7
|
||||
#
|
||||
# UserID-1: 33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07
|
||||
# UserID-2: 81d82ef3-4deb-499d-9270-9aeb5a3ec5fe
|
||||
#
|
||||
# ProjectID-1: c9a5f184-c0d0-4daa-83c3-af6fdc0879e6
|
||||
# ProjectID-2: 40eba01c-b348-49b8-803f-67123251a00a
|
||||
#
|
||||
# ImageID-1: 7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
|
||||
# ImageID-2: b01f2588-89dc-46b2-897b-fffae1e10975
|
||||
#
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: $ENVIRON['GNOCCHI_SERVICE_TOKEN']
|
||||
authorization: $ENVIRON['GNOCCHI_AUTHORIZATION']
|
||||
|
||||
tests:
|
||||
#
|
||||
# Setup resource types if don't exist
|
||||
#
|
||||
|
||||
- name: create new resource type 'instance-like'
|
||||
POST: /v1/resource_type
|
||||
status: 201
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: instance-like
|
||||
attributes:
|
||||
display_name:
|
||||
type: string
|
||||
required: True
|
||||
flavor_id:
|
||||
type: string
|
||||
required: True
|
||||
host:
|
||||
type: string
|
||||
required: True
|
||||
image_ref:
|
||||
type: string
|
||||
required: False
|
||||
server_group:
|
||||
type: string
|
||||
required: False
|
||||
|
||||
- name: create new resource type 'image-like'
|
||||
POST: /v1/resource_type
|
||||
status: 201
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: image-like
|
||||
attributes:
|
||||
name:
|
||||
type: string
|
||||
required: True
|
||||
disk_format:
|
||||
type: string
|
||||
required: True
|
||||
container_format:
|
||||
type: string
|
||||
required: True
|
||||
|
||||
#
|
||||
# Setup test resources
|
||||
#
|
||||
- name: helper. create instance-like resource-1
|
||||
POST: /v1/resource/instance-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
display_name: vm-gabbi-1
|
||||
id: a64ca14f-bc7c-45b0-aa85-42cd2179e1e2
|
||||
user_id: 33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07
|
||||
flavor_id: "1"
|
||||
image_ref: 7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
|
||||
host: compute-0-gabbi.localdomain
|
||||
project_id: c9a5f184-c0d0-4daa-83c3-af6fdc0879e6
|
||||
status: 201
|
||||
|
||||
- name: helper. create instance-like resource-2
|
||||
POST: /v1/resource/instance-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
display_name: vm-gabbi-2
|
||||
id: 7ccccfa0-92ce-4225-80ca-3ac9cb122d6a
|
||||
user_id: 33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07
|
||||
flavor_id: "2"
|
||||
image_ref: b01f2588-89dc-46b2-897b-fffae1e10975
|
||||
host: compute-1-gabbi.localdomain
|
||||
project_id: c9a5f184-c0d0-4daa-83c3-af6fdc0879e6
|
||||
status: 201
|
||||
|
||||
- name: helper. create instance-like resource-3
|
||||
POST: /v1/resource/instance-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
display_name: vm-gabbi-3
|
||||
id: c442a47c-eb33-46ce-9665-f3aa0bef54e7
|
||||
user_id: 81d82ef3-4deb-499d-9270-9aeb5a3ec5fe
|
||||
flavor_id: "2"
|
||||
image_ref: b01f2588-89dc-46b2-897b-fffae1e10975
|
||||
host: compute-1-gabbi.localdomain
|
||||
project_id: 40eba01c-b348-49b8-803f-67123251a00a
|
||||
status: 201
|
||||
|
||||
- name: helper. create image-like resource-1
|
||||
POST: /v1/resource/image-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
id: 7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
name: gabbi-image-1
|
||||
user_id: 81d82ef3-4deb-499d-9270-9aeb5a3ec5fe
|
||||
project_id: 40eba01c-b348-49b8-803f-67123251a00a
|
||||
status: 201
|
||||
|
||||
#
|
||||
# Actual tests
|
||||
#
|
||||
|
||||
- name: search for all resources with a specific user_id
|
||||
desc: search through all resource types
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
=:
|
||||
user_id: 81d82ef3-4deb-499d-9270-9aeb5a3ec5fe
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
response_json_paths:
|
||||
$.[0].type: instance-like
|
||||
$.[1].type: image-like
|
||||
$.[0].id: c442a47c-eb33-46ce-9665-f3aa0bef54e7
|
||||
$.[1].id: 7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
|
||||
|
||||
- name: search for all resources of instance-like type create by specific user_id
|
||||
desc: all instances created by a specified user
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
and:
|
||||
- =:
|
||||
type: instance-like
|
||||
- =:
|
||||
user_id: 33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
response_strings:
|
||||
- '"id": "a64ca14f-bc7c-45b0-aa85-42cd2179e1e2"'
|
||||
- '"id": "7ccccfa0-92ce-4225-80ca-3ac9cb122d6a"'
|
||||
response_json_paths:
|
||||
$.[0].id: a64ca14f-bc7c-45b0-aa85-42cd2179e1e2
|
||||
$.[1].id: 7ccccfa0-92ce-4225-80ca-3ac9cb122d6a
|
||||
$.[0].type: instance-like
|
||||
$.[1].type: instance-like
|
||||
$.[0].metrics.`len`: 0
|
||||
$.[1].metrics.`len`: 0
|
||||
|
||||
- name: search for all resources with a specific project_id
|
||||
desc: search for all resources in a specific project
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
=:
|
||||
project_id: c9a5f184-c0d0-4daa-83c3-af6fdc0879e6
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
|
||||
- name: search for intances on a specific compute using "like" keyword
|
||||
desc: search for vms hosted on a specific compute node
|
||||
POST: /v1/search/resource/instance-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
like:
|
||||
host: 'compute-1-gabbi%'
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
response_strings:
|
||||
- '"project_id": "40eba01c-b348-49b8-803f-67123251a00a"'
|
||||
- '"project_id": "c9a5f184-c0d0-4daa-83c3-af6fdc0879e6"'
|
||||
- '"user_id": "33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07"'
|
||||
- '"user_id": "81d82ef3-4deb-499d-9270-9aeb5a3ec5fe"'
|
||||
- '"display_name": "vm-gabbi-2"'
|
||||
- '"display_name": "vm-gabbi-3"'
|
||||
|
||||
- name: search for instances using complex search with "like" keyword and user_id
|
||||
desc: search for vms of specified user hosted on a specific compute node
|
||||
POST: /v1/search/resource/instance-like
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
and:
|
||||
- like:
|
||||
host: 'compute-%-gabbi%'
|
||||
- =:
|
||||
user_id: 33ba83ca-2f12-4ad6-8fa2-bc8b55d36e07
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
response_strings:
|
||||
- '"display_name": "vm-gabbi-1"'
|
||||
- '"display_name": "vm-gabbi-2"'
|
||||
- '"project_id": "c9a5f184-c0d0-4daa-83c3-af6fdc0879e6"'
|
||||
|
||||
- name: search for resources of instance-like or image-like type with specific user_id
|
||||
desc: search for all image-like or instance-like resources created by a specific user
|
||||
POST: /v1/search/resource/generic
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
and:
|
||||
- =:
|
||||
user_id: 81d82ef3-4deb-499d-9270-9aeb5a3ec5fe
|
||||
|
||||
- or:
|
||||
- =:
|
||||
type: instance-like
|
||||
|
||||
- =:
|
||||
type: image-like
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.`len`: 2
|
||||
response_strings:
|
||||
- '"type": "image-like"'
|
||||
- '"type": "instance-like"'
|
||||
- '"id": "7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d"'
|
||||
- '"id": "c442a47c-eb33-46ce-9665-f3aa0bef54e7"'
|
||||
|
||||
#
|
||||
# Tear down resources
|
||||
#
|
||||
|
||||
- name: helper. delete instance-like resource-1
|
||||
DELETE: /v1/resource/instance-like/a64ca14f-bc7c-45b0-aa85-42cd2179e1e2
|
||||
status: 204
|
||||
|
||||
- name: helper. delete instance-like resource-2
|
||||
DELETE: /v1/resource/instance-like/7ccccfa0-92ce-4225-80ca-3ac9cb122d6a
|
||||
status: 204
|
||||
|
||||
- name: helper. delete instance-like resource-3
|
||||
DELETE: /v1/resource/instance-like/c442a47c-eb33-46ce-9665-f3aa0bef54e7
|
||||
status: 204
|
||||
|
||||
- name: helper. delete image-like resource
|
||||
DELETE: /v1/resource/image-like/7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
|
||||
status: 204
|
||||
|
||||
- name: helper. delete resource-type instance-like
|
||||
DELETE: /v1/resource_type/instance-like
|
||||
status: 204
|
||||
|
||||
- name: helper. delete resource-type image-like
|
||||
DELETE: /v1/resource_type/image-like
|
||||
status: 204
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
# 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 __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from gabbi import runner
|
||||
from gabbi import suitemaker
|
||||
from gabbi import utils
|
||||
import six.moves.urllib.parse as urlparse
|
||||
from tempest import config
|
||||
import tempest.test
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
TEST_DIR = os.path.join(os.path.dirname(__file__), '..',
|
||||
'gnocchi', 'functional_live', 'gabbits')
|
||||
|
||||
|
||||
class GnocchiGabbiTest(tempest.test.BaseTestCase):
|
||||
credentials = ['admin']
|
||||
|
||||
TIMEOUT_SCALING_FACTOR = 5
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(GnocchiGabbiTest, cls).skip_checks()
|
||||
if not CONF.service_available.gnocchi:
|
||||
raise cls.skipException("Gnocchi support is required")
|
||||
|
||||
def _do_test(self, filename):
|
||||
token = self.os_admin.auth_provider.get_token()
|
||||
url = self.os_admin.auth_provider.base_url(
|
||||
{'service': CONF.metric.catalog_type,
|
||||
'endpoint_type': CONF.metric.endpoint_type})
|
||||
|
||||
parsed_url = urlparse.urlsplit(url)
|
||||
prefix = parsed_url.path.rstrip('/') # turn it into a prefix
|
||||
if parsed_url.scheme == 'https':
|
||||
port = 443
|
||||
require_ssl = True
|
||||
else:
|
||||
port = 80
|
||||
require_ssl = False
|
||||
host = parsed_url.hostname
|
||||
if parsed_url.port:
|
||||
port = parsed_url.port
|
||||
|
||||
os.environ["GNOCCHI_SERVICE_TOKEN"] = token
|
||||
os.environ["GNOCCHI_AUTHORIZATION"] = "not used"
|
||||
|
||||
with open(os.path.join(TEST_DIR, filename)) as f:
|
||||
suite_dict = utils.load_yaml(f)
|
||||
suite_dict.setdefault('defaults', {})['ssl'] = require_ssl
|
||||
test_suite = suitemaker.test_suite_from_dict(
|
||||
loader=unittest.defaultTestLoader,
|
||||
test_base_name="gabbi",
|
||||
suite_dict=suite_dict,
|
||||
test_directory=TEST_DIR,
|
||||
host=host, port=port,
|
||||
fixture_module=None,
|
||||
intercept=None,
|
||||
prefix=prefix,
|
||||
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(GnocchiGabbiTest, name,
|
||||
test_maker(name, filename))
|
|
@ -43,6 +43,9 @@ class TelemetryTempestPlugin(plugins.TempestPlugin):
|
|||
config.register_opt_group(
|
||||
conf, tempest_config.alarming_group,
|
||||
tempest_config.AlarmingGroup)
|
||||
config.register_opt_group(
|
||||
conf, tempest_config.metric_group,
|
||||
tempest_config.metric_opts)
|
||||
|
||||
def get_opt_lists(self):
|
||||
return [(tempest_config.telemetry_group.name,
|
||||
|
@ -52,4 +55,6 @@ class TelemetryTempestPlugin(plugins.TempestPlugin):
|
|||
(config.service_available_group.name,
|
||||
tempest_config.service_option),
|
||||
(tempest_config.alarming_group.name,
|
||||
tempest_config.AlarmingGroup)]
|
||||
tempest_config.AlarmingGroup),
|
||||
(tempest_config.metric_group.name,
|
||||
tempest_config.metric_opts)]
|
||||
|
|
Loading…
Reference in New Issue