Reorganize scenario testing.

* This moves all scenarios in scenarios directory.
* factorized code between two scenarios in utils.py
* remove unused tempest-heat-plugin

Change-Id: Ifd2e1ad1453484e6af4ae09dedb6e96d96f42b52
diff --git a/telemetry_tempest_plugin/scenario/gnocchi_gabbits/live.yaml b/telemetry_tempest_plugin/scenario/gnocchi_gabbits/live.yaml
new file mode 100644
index 0000000..6d15d61
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/gnocchi_gabbits/live.yaml
@@ -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: $ENVIRON['GNOCCHI_SERVICE_URL']/
+
+    # Fail to create archive policy
+    - name: wrong archive policy content type
+      desc: attempt to create archive policy with invalid content-type
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy
+      request_headers:
+          content-type: application/json
+      status: 405
+
+    - name: invalid authZ
+      desc: x-auth-token is invalid
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/gabbilive
+      status: 405
+
+    - name: put single archive
+      desc: unexpected 'PUT' request to archive policy
+      PUT: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/grandiose
+      status: 404
+      response_strings:
+          - Archive policy grandiose does not exist
+
+    # Attempt to create illogical policies
+
+    - name: create illogical policy
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy_rule
+      request_headers:
+          content-type: text/plain
+      status: 415
+      response_strings:
+          - Unsupported Media Type
+
+    - name: bad archive policy rule body
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy_rule/foo
+      status: 404
+
+
+    - name: get archive policy rule
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/gabbilive
+      status: 400
+
+    #
+    # Metrics
+    #
+
+
+    - name: get all metrics
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/metric
+      status: 200
+
+    - name: create metric with name and rule
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/metric?archive_policy_name=gabbilive
+      response_json_paths:
+          $.`len`: 1
+
+    - name: delete metric
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/metric/$RESPONSE['$.id']
+      status: 204
+
+    - name: ensure the metric is delete
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/metric/$HISTORY['get valid metric id'].$RESPONSE['$.id']
+      status: 404
+
+    - name: create metric bad archive policy
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/metric
+      request_headers:
+          content-type: plain/text
+      data: '{"archive_policy_name": "cookies"}'
+      status: 415
+
+
+    #
+    # Cleanup
+    #
+
+    - name: delete archive policy rule
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy_rule/gabbilive_rule
+      status: 204
+
+    - name: confirm delete archive policy rule
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy_rule/gabbilive_rule
+      status: 404
+
+
+    #
+    # Resources section
+    #
+
+    - name: root of resource
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource
+      response_json_paths:
+          $.generic: $SCHEME://$NETLOC/v1/resource/generic
+
+    - name: typo of resource
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resoue
+      status: 404
+
+    - name: typo of resource extra
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/foobar
+      status: 404
+
+    - name: generic resource
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/generic
+      status: 200
+
+    - name: post resource type
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/myresource
+      status: 200
+
+    - name: post myresource resource
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/search/notexists
+      status: 404
+
+    - name: typo of search in resource
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/search/resource/foobar
+      status: 404
+
+    - name: search with invalid uuid
+      POST: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/myresource/2ae35573-7f9f-4bb1-aae8-dad8dff5706e
+      status: 204
+
+      # assert resource is really deleted
+    - name: assert resource resource is deleted
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/gabbilive
+      poll:
+          count: 360
+          delay: 1
+      status: 204
+
+    # It really is gone
+
+    - name: delete our resource type
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource_type/myresource
+      status: 204
+
+    - name: confirm delete of cleanup
+      GET: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/archive_policy/gabbilive
+      status: 404
diff --git a/telemetry_tempest_plugin/scenario/gnocchi_gabbits/search-resource.yaml b/telemetry_tempest_plugin/scenario/gnocchi_gabbits/search-resource.yaml
new file mode 100644
index 0000000..8febac6
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/gnocchi_gabbits/search-resource.yaml
@@ -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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/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: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/instance-like/a64ca14f-bc7c-45b0-aa85-42cd2179e1e2
+      status: 204
+
+    - name: helper. delete instance-like resource-2
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/instance-like/7ccccfa0-92ce-4225-80ca-3ac9cb122d6a
+      status: 204
+
+    - name: helper. delete instance-like resource-3
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/instance-like/c442a47c-eb33-46ce-9665-f3aa0bef54e7
+      status: 204
+
+    - name: helper. delete image-like resource
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource/image-like/7ab2f7ae-7af5-4469-bdc8-3c0f6dfab75d
+      status: 204
+
+    - name: helper. delete resource-type instance-like
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource_type/instance-like
+      status: 204
+
+    - name: helper. delete resource-type image-like
+      DELETE: $ENVIRON['GNOCCHI_SERVICE_URL']/v1/resource_type/image-like
+      status: 204
+
diff --git a/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/aodh-gnocchi-threshold-alarm.yaml b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/aodh-gnocchi-threshold-alarm.yaml
new file mode 100644
index 0000000..9349295
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/aodh-gnocchi-threshold-alarm.yaml
@@ -0,0 +1,309 @@
+#
+# 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: get alarm state for 'gabbi-gnocchi-threshold-resource-alarm'
+      desc: get state for alarm
+      GET: $URL
+      request_headers:
+          content-type: application/json
+      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
+
+    #
+    # 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
+
diff --git a/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/autoscaling.yaml b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/autoscaling.yaml
new file mode 100644
index 0000000..8eac9d0
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/autoscaling.yaml
@@ -0,0 +1,175 @@
+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:
+          - "[]"
diff --git a/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/create_stack.json b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/create_stack.json
new file mode 100644
index 0000000..57a6366
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/create_stack.json
@@ -0,0 +1,74 @@
+{
+    "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" }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/update_stack.json b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/update_stack.json
new file mode 100644
index 0000000..54f8e29
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/telemetry_integration_gabbits/update_stack.json
@@ -0,0 +1,73 @@
+{
+    "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" }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/telemetry_tempest_plugin/scenario/test_gnocchi.py b/telemetry_tempest_plugin/scenario/test_gnocchi.py
new file mode 100644
index 0000000..e283d2f
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/test_gnocchi.py
@@ -0,0 +1,52 @@
+#    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
+
+from tempest import config
+import tempest.test
+
+from telemetry_tempest_plugin.scenario import utils
+
+CONF = config.CONF
+
+TEST_DIR = os.path.join(os.path.dirname(__file__), 'gnocchi_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 _prep_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,
+             'region': CONF.identity.region})
+
+        os.environ.update({
+            "GNOCCHI_SERVICE_URL": url,
+            "GNOCCHI_SERVICE_TOKEN": token,
+            "GNOCCHI_AUTHORIZATION": "not used",
+        })
+
+
+utils.generate_tests(GnocchiGabbiTest, TEST_DIR)
diff --git a/telemetry_tempest_plugin/scenario/test_telemetry_integration.py b/telemetry_tempest_plugin/scenario/test_telemetry_integration.py
index df527c0..22155dd 100644
--- a/telemetry_tempest_plugin/scenario/test_telemetry_integration.py
+++ b/telemetry_tempest_plugin/scenario/test_telemetry_integration.py
@@ -11,16 +11,14 @@
 #    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')
+from telemetry_tempest_plugin.scenario import utils
+
+TEST_DIR = os.path.join(os.path.dirname(__file__),
+                        'telemetry_integration_gabbits')
 
 
 class TestTelemetryIntegration(manager.ScenarioTest):
@@ -75,7 +73,7 @@
                                 opt_section.catalog_type)
             return endpoints[0]['endpoints'][0][endpoint_type]
 
-    def _do_test(self, filename):
+    def _prep_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(
@@ -96,48 +94,5 @@
             "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="example.com", 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))
+utils.generate_tests(TestTelemetryIntegration, TEST_DIR)
diff --git a/telemetry_tempest_plugin/scenario/utils.py b/telemetry_tempest_plugin/scenario/utils.py
new file mode 100644
index 0000000..90b4d6b
--- /dev/null
+++ b/telemetry_tempest_plugin/scenario/utils.py
@@ -0,0 +1,78 @@
+#    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
+from oslo_log import log as logging
+
+LOG = logging.getLogger(__name__)
+
+
+def run_test(test_class_instance, test_dir, filename):
+    d = utils.load_yaml(yaml_file=os.path.join(test_dir, filename))
+    test_suite = suitemaker.test_suite_from_dict(
+        loader=unittest.defaultTestLoader,
+        test_base_name="gabbi",
+        suite_dict=d,
+        test_directory=test_dir,
+        host='example.com', 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 ittest_class.
+    with open(os.devnull, 'w') as stream:
+        result = unittest.TextTestRunner(
+            stream=stream, verbosity=0, failfast=True,
+        ).run(test_suite)
+
+    return
+
+    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)
+            test_class_instance.fail(msg)
+
+    test_class_instance.assertTrue(result.wasSuccessful())
+
+
+def test_maker(test_dir, filename, name):
+    def test(self):
+        self._prep_test(filename)
+        run_test(self, test_dir, filename)
+    test.__name__ = name
+    return test
+
+
+def generate_tests(test_class, test_dir):
+    # Create one scenario per yaml file
+    filenames = os.listdir(test_dir)
+    if not filenames:
+        raise RuntimeError("%s is empty" % test_dir)
+    for filename in filenames:
+        if not filename.endswith('.yaml'):
+            continue
+        name = "test_%s" % filename[:-5].lower().replace("-", "_")
+        setattr(test_class, name,
+                test_maker(test_dir, filename, name))