Exemplo n.º 1
0
  def testGetModelDataWithModelUIdAndAnomalyScore(self):
    """
    test GET /metricId/data?anomaly=testanomalyScore
    """
    getMetricDataWithAnomalyQueryResponse = self.app.get(
      "/%s/data?anomaly=%s" % (self.uid, self.testAnomalyScore),
      headers=self.headers)
    getMetricDataWithAnomalyQueryResult = utils.jsonDecode(
      getMetricDataWithAnomalyQueryResponse.body)

    assertions.assertSuccess(self, getMetricDataWithAnomalyQueryResponse)
    self.assertIsInstance(getMetricDataWithAnomalyQueryResult, dict)
    self.assertItemsEqual(getMetricDataWithAnomalyQueryResult.keys(),
     ["data", "names"])
    self.assertGreater(len(getMetricDataWithAnomalyQueryResult["data"]), 0)
    # we are parsing amomaly scores from reponse and chekcing if each of it
    # is satisfying value condition set with GET request.
    # If for some reason this parameter is not applied on DB query, we get
    # full response for this request
    # We are making sure each value for anomaly_score in result matches with
    # condition set in GET request, hence the assertion
    anomalyScores = \
      [row[2] for row in getMetricDataWithAnomalyQueryResult["data"]]
    failedScores = [a for a in anomalyScores if a < self.testAnomalyScore]
    self.assertEqual(failedScores, [])
Exemplo n.º 2
0
  def testCombinationQuota1(self):
    result = self.cloudwatchApp.get("/us-west-2/AWS/EC2",
                                    headers=self.headers)
    instances = json.loads(result.body)


    for i in range(0, 10, 5):
      instance = instances[i]
      instanceId = "us-west-2/AWS/EC2/%s" % (
        instance["dimensions"]["InstanceId"])
      postResponse = self.instancesApp.post("/%s" % instanceId,
                                            headers=self.headers)
      assertions.assertSuccess(self, postResponse)
      self.addCleanup(self.instancesApp.delete, "/", headers=self.headers,
                      params=json.dumps([instanceId]))

    sock = socket.socket()
    sock.connect(("localhost", self.plaintextPort))
    sock.sendall("CustomMetric1 5.0 1386201600\n")
    self.gracefullyCloseSocket(sock)
    self.addCleanup(self.customApp.delete,
                    "/CustomMetric1",
                    headers=self.headers)
    uid = self.checkMetricCreated("CustomMetric1")

    with self.assertRaises(AppError) as e:
      payload = {"uid": uid,
                 "datasource": "custom",
                 "min": 0.0,
                 "max": 100.0}
      self.modelApp.post("/", json.dumps(payload), headers=self.headers)

    self.assertIn("Server limit exceeded", e.exception.message)
Exemplo n.º 3
0
 def _deleteOneMetric(self):
   """
   Delete one metric from test EC2 instance
   """
   app = TestApp(models_api.app.wsgifunc())
   response = app.get("/", headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertIsInstance(result, list)
   app.delete("/" + result[0]['uid'], headers=self.headers)
Exemplo n.º 4
0
 def testGETDatasources(self):
   """
   Test for GET for '/_metrics/datasources'
   response is validated for appropriate headers and body
   """
   response = self.app.get('/datasources', headers=self.headers)
   assertions.assertSuccess(self, response)
   self.assertIsInstance(utils.jsonDecode(response.body), list)
   self.assertSetEqual(set(utils.jsonDecode(response.body)),
                    set(["autostack", "custom", "cloudwatch"]))
Exemplo n.º 5
0
 def testGetListRegionsEmptyResponse(self, adapterMock):
   """
   Test for Get '/_metrics/cloudwatch/regions'
   response is validated for appropriate headers, body and status
   """
   adapterMock.return_value.describeRegions.return_value = []
   response = self.app.get("/regions", headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertEqual(result, {})
Exemplo n.º 6
0
 def testDefaultGetSpecificSection(self):
   response = self.app.get("/aws", headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertIsInstance(result, dict)
   for key in set(self.configurable_options["aws"]):
     if key in settings_api.HIDDEN_SETTINGS["aws"]:
       self.assertNotIn(key, result)
     else:
       self.assertIn(key, result)
Exemplo n.º 7
0
 def _deleteInstance(self):
   """
   Delete test EC2 instance created by :py:meth:`_createEC2Instance`
   """
   app = TestApp(instances_api.app.wsgifunc())
   response = app.delete("/", params=json.dumps([self.instanceId]),
                         headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertIsInstance(result, dict)
   self.assertEqual(result, {"result": "success"})
Exemplo n.º 8
0
 def testGetModelDataWithModelUId(self):
   """
   test GET /metricId/data
   """
   getMetricDataResponse = self.app.get("/%s/data" % self.uid,
     headers=self.headers)
   assertions.assertSuccess(self, getMetricDataResponse)
   getMetricDataResult = utils.jsonDecode(getMetricDataResponse.body)
   self.assertIsInstance(getMetricDataResult, dict)
   self.assertItemsEqual(getMetricDataResult.keys(), ["data", "names"])
   self.assertGreater(len(getMetricDataResult["data"]), 0)
Exemplo n.º 9
0
 def testGetListNamespaceNoRegions(self, adapterMock):
   """
   Test for Get '/_metrics/cloudwatch/namespaces'
   response is validated for appropriate headers, body and status
   """
   adapterMock.return_value.describeRegions.return_value = []
   response = self.app.get("/namespaces", headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   # Added Autostacks namespaces to this list for now, to maintain API
   # backwards-compatibility during adapter refactor
   self.assertEqual(result, {'Autostacks': {'metrics': ['InstanceCount']}})
Exemplo n.º 10
0
 def testDefaultGetList(self):
   response = self.app.get("", headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertIsInstance(result, dict)
   for config in self.configurable_options:
     self.assertTrue(result.has_key(config))
     for key in self.configurable_options[config]:
       if key in settings_api.HIDDEN_SETTINGS[config]:
         self.assertNotIn(key, result[config])
       else:
         self.assertIn(key, result[config])
Exemplo n.º 11
0
  def _createEC2Instance(self):
    """
    Created EC2 instance to be used by the tests
    :return: Instance ID
    :rtype: str
    """
    app = TestApp(instances_api.app.wsgifunc())

    response = app.post("/" + self.instanceId, headers=self.headers)
    assertions.assertSuccess(self, response)
    result = app_utils.jsonDecode(response.body)
    self.assertIsInstance(result, dict)
    self.assertEqual(result, {"result": "success"})
Exemplo n.º 12
0
 def testGetMetricValidInputEmptyResponse(self, adapterMock):
   """
   Test for
   Get '/_metrics/cloudwatch/<region-name>/AWS/<namespace>/metricName'
   response is validated for appropriate headers, body and status
   """
   adapterMock.return_value.describeRegions.return_value = self.regions
   adapterMock.return_value.describeSupportedMetrics.return_value = (
     self.resources)
   adapterMock.return_value.describeResources.return_value = []
   response = self.app.get("/us-east-1/AWS/EC2/CPUUtilization",
     headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertEqual(result, [])
Exemplo n.º 13
0
  def testPostMultipleWithInvalidInstanceId(self):
    """
    Test for post '/_instances'
    response is validated for appropriate headers, body and status
    Invoke post with invalid instanceId

    Expect a 200 OK even when attempting to POST to an invalid instance,
    this saves the overhead of asking AWS if we're dealing with a valid
    instance every POST.

    We expect the CLI user to know what instance ID he/she is looking for.
    """
    params = ["abcd1234"]
    response = self.app.post("/us-west-2/AWS/EC2",
      params=app_utils.jsonEncode(params), headers=self.headers, status="*")
    assertions.assertSuccess(self, response)
Exemplo n.º 14
0
  def testPostMultipleWithInstanceToIncorrectNamespace(self):
    """
    Test for post'/_instances'
    response is validated for appropriate headers, body and status
    Invoke post with valid instance id to incorrect namespace

    Expect a 200 OK even when attempting to POST an instance to the wrong
    namespace, this saves the overhead of asking AWS if we're dealing with a
    valid instance in the given namespace with every POST request.

    We expect the CLI user to know what instance ID he/she is looking for.

    """
    params = ["htm-it-docs-elb"]
    response = self.app.post("/us-west-2/AWS/EC2",
      params=app_utils.jsonEncode(params), headers=self.headers, status="*")
    assertions.assertSuccess(self, response)
Exemplo n.º 15
0
  def testGetMetricDimensionWithResponse(self, adapterMock):
    """
    Test for
    Get '/_metrics/cloudwatch/<region-name>/AWS/<namespace>/metricName'
    response is validated for appropriate headers, body and status
    and response is validated with pre-defined responses
    """
    adapterMock.return_value.describeRegions.return_value = self.regions
    adapterMock.return_value.describeSupportedMetrics.return_value = (
      self.resources)
    adapterMock.return_value.describeResources.return_value = [
      {'grn': u'aws://us-west-2/Instance/i-d48ccaba',
       'name': u'Foo',
       'resID': u'i-d48ccaba'},
      {'grn': u'aws://us-west-2/Instance/i-548acc3a',
       'name': u'Bar',
       'resID': u'i-548acc3a'}]

    response = self.app.get("/us-east-1/AWS/EC2/CPUUtilization",
      headers=self.headers)
    assertions.assertSuccess(self, response)
    result = app_utils.jsonDecode(response.body)
    self.assertItemsEqual(result,
      [
        {'datasource': 'cloudwatch',
         'dimensions': {'InstanceId': 'i-d48ccaba'},
         'metric': 'CPUUtilization',
         'namespace': 'AWS/EC2',
         'region': 'us-east-1'},
        {'datasource': 'cloudwatch',
         'dimensions': {'InstanceId': 'i-548acc3a'},
         'metric': 'CPUUtilization',
         'namespace': 'AWS/EC2',
         'region': 'us-east-1'},
        {'datasource': 'cloudwatch',
         'dimensions': {'AutoScalingGroupName': 'i-d48ccaba'},
         'metric': 'CPUUtilization',
         'namespace': 'AWS/EC2',
         'region': 'us-east-1'},
        {'datasource': 'cloudwatch',
         'dimensions': {'AutoScalingGroupName': 'i-548acc3a'},
         'metric': 'CPUUtilization',
         'namespace': 'AWS/EC2',
         'region': 'us-east-1'}
      ])
Exemplo n.º 16
0
  def testPostWithInvalidInstanceId(self):
    """
    Test for post '/_instances/region/namespace/instanceId'
    response is validated for appropriate headers, body and status
    Invoke Api call with instanceId that does not exists

    Expect a 200 OK even when attempting to POST to an invalid instance,
    this saves the overhead of asking AWS if we're dealing with a valid
    instance every POST.

    We expect the CLI user to know what instance ID he/she is looking for.
    """
    region = "us-west-2"
    namespace = "EC2"
    instanceId = "abcd1234"
    response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId),
      headers=self.headers, status="*")
    assertions.assertSuccess(self, response)
Exemplo n.º 17
0
  def testPostInstanceIdToIncorrectNamespace(self):
    """
    Test for post '/_instances/region/namespace/instanceId'
    response is validated for appropriate headers, body and status
    Invoke Api call with instance to incorrect namespace.
    e.g post htm-it-docs-elb to AWS/EC2

    Expect a 200 OK even when attempting to POST an instance to the wrong
    namespace, this saves the overhead of asking AWS if we're dealing with a
    valid instance in the given namespace with every POST request.

    We expect the CLI user to know what instance ID he/she is looking for.
    """
    region = "us-west-2"
    namespace = "EC2"
    instanceId = "htm-it-docs-elb"
    response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId),
      headers=self.headers, status="*")
    assertions.assertSuccess(self, response)
Exemplo n.º 18
0
  def testGetAllModelData(self):
    """
    test GET /data
    """
    getAllMetricDataResponse = self.app.get("/%s/data" % self.uid,
      headers=self.headers)
    assertions.assertSuccess(self, getAllMetricDataResponse)
    getAllMetricDataResult = utils.jsonDecode(getAllMetricDataResponse.body)
    assertions.assertSuccess(self, getAllMetricDataResponse)
    self.assertIsInstance(getAllMetricDataResult, dict)
    self.assertItemsEqual(getAllMetricDataResult.keys(), ["data", "names"])

    # Compare http and https response
    https_response = requests.get("https://localhost/_models/%s/data"
                                  % self.uid,
                                  headers=self.headers,
                                  verify=False)

    httpsData = json.loads(https_response.text)
    self.assertIsInstance(httpsData, dict)
    self.assertItemsEqual(httpsData.keys(), ["data", "names"])
    self.assertItemsEqual(httpsData["names"], ["timestamp",
                                               "value",
                                               "anomaly_score",
                                               "rowid"])
    self.assertIsInstance(httpsData["data"], list)
    self.assertTrue(all(isinstance(row, list) and len(row) == 4
                        for row in httpsData["data"]))

    http_response = requests.get("http://localhost/_models/%s/data"
                                 % self.uid,
                                 headers=self.headers)
    httpData = json.loads(http_response.text)
    self.assertIsInstance(httpData, dict)
    self.assertItemsEqual(httpData.keys(), ["data", "names"])
    self.assertItemsEqual(httpData["names"], ["timestamp",
                                              "value",
                                              "anomaly_score",
                                              "rowid"])
    self.assertIsInstance(httpData["data"], list)
    self.assertTrue(all(isinstance(row, list) and len(row) == 4
                        for row in httpData["data"]))
Exemplo n.º 19
0
 def testGetModelDataWithModelUIdAndFromTimeStamp(self):
   """
   test GET /metricId/data?from=timeStamp
   """
   getMetricDataWithFromTimeStampResponse = self.app.get(
     "/%s/data?from=%s" % (self.uid, self.testTimeStamp),
     headers=self.headers)
   getMetricDataWithFromTimeStampResult = utils.jsonDecode(
     getMetricDataWithFromTimeStampResponse.body)
   assertions.assertSuccess(self, getMetricDataWithFromTimeStampResponse)
   self.assertGreater(len(getMetricDataWithFromTimeStampResult["data"]), 0)
   # We wait for minimum rows to be available for givem metric
   # We are using lower value for rowId  to get Non NULL value anomaly_score
   # We get all available metric data rows, if condition is
   # not applied on DB query and hence the GET call will return all data rows
   # Asserting following will make sure that we have received result with
   # applied condition.
   # ( In this case len(metricData) would be greater than result length)
   self.assertGreater(len(self.metricData),
     len(getMetricDataWithFromTimeStampResult["data"]))
Exemplo n.º 20
0
 def testGetNamespaceAWSType(self, adapterMock):
   """
   Test for Get '/_metrics/cloudwatch/AWS/<namespace>'
   response is validated for appropriate headers, body and status
   """
   adapterMock.return_value.describeRegions.return_value = self.regions
   adapterMock.return_value.describeSupportedMetrics.return_value = (
     self.resources)
   response = self.app.get("/AWS/EC2", headers=self.headers)
   #self.assertTrue(getMetrics.called)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertEqual(result,
                    {'AWS/EC2': {'dimensions': ['InstanceId',
                                                'AutoScalingGroupName'],
                                 'metrics': ['CPUUtilization',
                                             'NetworkIn',
                                             'DiskWriteBytes',
                                             'NetworkOut',
                                             'DiskReadBytes']}})
Exemplo n.º 21
0
  def testCloudwatchQuota(self):
    result = self.cloudwatchApp.get("/us-west-2/AWS/EC2",
                                    headers=self.headers)
    instances = json.loads(result.body)

    for i in range(0, 10, 5):
      instance = instances[i]
      instanceId = "us-west-2/AWS/EC2/%s" % (
        instance["dimensions"]["InstanceId"])
      postResponse = self.instancesApp.post("/%s" % instanceId,
                                            headers=self.headers)
      assertions.assertSuccess(self, postResponse)
      self.addCleanup(self.instancesApp.delete, "/", headers=self.headers,
                      params=json.dumps([instanceId]))

    with self.assertRaises(AppError) as e:
      instanceId = ("us-west-2/AWS/EC2/%s" %
                    (instances[10]["dimensions"]["InstanceId"]))
      postResponse = self.instancesApp.post("/%s" % instanceId,
                                            headers=self.headers)

    self.assertIn("Server limit exceeded", e.exception.message)
Exemplo n.º 22
0
  def testLifecycleForSingleInstance(self):
    """
    Test for Get '/_instances'
    response is validated for appropriate headers, body and status
    Make sure app returns empty list at initial step

    Test for post '/_instances/region/namespace/instanceId'
    response is validated for appropriate headers, body and status
    Invoke post with valid instanceId

    Test for get '/_instances/{instanceId}'
    response is validated for appropriate headers, body and status
    Check if you can invoke get on previously post'ed instance Instance

    Test for delete '/_instances/region/namespace/instanceId'
    response is validated for appropriate headers, body and status
    This invokes delete call on previously monitored instance

    Test for get '/_instances/{instanceId}'
    response is validated for appropriate headers, body and status
    This invokes get call with instanceId which is deleted from monitored list
    """

    # check initial empty response with get request
    initialGetResponse = self.app.get("", headers=self.headers)
    assertions.assertSuccess(self, initialGetResponse)
    initialGetResult = app_utils.jsonDecode(initialGetResponse.body)
    self.assertItemsEqual(initialGetResult, [])

    # Post single instance details to add under monitor
    region = VALID_EC2_INSTANCES["jenkins-master"]["region"]
    namespace = "EC2"
    instanceId = "%s/AWS/%s/%s" % (
      region, namespace, VALID_EC2_INSTANCES["jenkins-master"]["instanceId"])
    postResponse = self.app.post("/" + instanceId, headers=self.headers)
    assertions.assertSuccess(self, postResponse)
    postResult = app_utils.jsonDecode(postResponse.body)
    self.assertIsInstance(postResult, dict)
    self.assertEqual(postResult, {"result": "success"})

    # Verify that instance is successfully added under monitor
    getPostCheckResponse = self.app.get("", headers=self.headers)
    assertions.assertSuccess(self, getPostCheckResponse)
    getPostCheckResult = app_utils.jsonDecode(getPostCheckResponse.body)
    self.assertEqual(len(getPostCheckResult), 1)
    instanceResult = getPostCheckResult[0]
    self.assertEqual(region, instanceResult["location"])
    self.assertTrue(instanceId, instanceResult["server"])

    # Delete instance from monitor
    deleteResponse = self.app.delete("/", headers=self.headers,
                                     params=json.dumps([instanceId]))
    assertions.assertDeleteSuccessResponse(self, deleteResponse)

    # Check get reponse to confirm that instance has been deleted successfully
    getPostDeleteResponse = self.app.get("", headers=self.headers)
    postResult = app_utils.jsonDecode(getPostDeleteResponse.body)
    self.assertEqual(postResult, [])
Exemplo n.º 23
0
  def testGetInstanceWithDimension(self,adapterMock):
    """
    Test for Get
    '/_metrics/cloudwatch/<region-name>/AWS/<namespace>/\
    instances/<InstancdId>'
    with valid InstancceId
    response is validated for appropriate headers, body and status
    """
    adapterMock.return_value.describeRegions.return_value = self.regions
    adapterMock.return_value.describeSupportedMetrics.return_value = (
      self.resources)
    adapterMock.return_value.describeResources.return_value = [
      {'grn': u'aws://us-west-2/Instance/i-548acc3a',
       'name': u'Bar',
       'resID': u'i-548acc3a'}]

    response = self.app.get("/us-east-1/AWS/EC2/instances/i-548acc3a",
                            headers=self.headers)
    assertions.assertSuccess(self, response)
    result = app_utils.jsonDecode(response.body)
    self.assertTrue(all(metric["metric"]
                        in self.resources['AWS::EC2::Instance']
                        for metric in result))
Exemplo n.º 24
0
  def testGetInstanceWithDimensionNotFoundEmpty(self, adapterMock):
    """
    Test for Get
    '/_metrics/cloudwatch/<region-name>/AWS/<namespace>/\
    instances/<InstancdId>/Dimenion'
    with invalid InstancceId
    response is validated for appropriate headers, body and status
    Tests scenario when given instance name is not
    present in ouput from getDimensionsFromRegion
    """
    adapterMock.return_value.describeRegions.return_value = self.regions
    adapterMock.return_value.describeSupportedMetrics.return_value = (
      self.resources)
    adapterMock.return_value.describeResources.return_value = [
      {'grn': u'aws://us-west-2/Instance/i-548acc3a',
       'name': u'Bar',
       'resID': u'i-548acc3a'}]

    response = self.app.get("/us-east-1/AWS/EC2/instances/i-1234567a",
                                headers=self.headers)
    assertions.assertSuccess(self, response)
    result = app_utils.jsonDecode(response.body)
    self.assertEqual(result, [])
Exemplo n.º 25
0
  def testCompleteModelExportApiLifecycle(self):
    """
      Happy path testing for the route "/_models/export"
    """
    data = self.modelsTestData["create_data"]
    createResponse = self.app.put("/", utils.jsonEncode(data),
                       headers=self.headers)
    assertions.assertSuccess(self, createResponse, code=201)

    # NOTE: export uses a new format
    expectedExportSpec = {
      "datasource": data["datasource"],
      "metricSpec": {
        "region": data["region"],
        "namespace": data["namespace"],
        "metric": data["metric"],
        "dimensions": data["dimensions"]
      }
    }

    # Test export all data
    response = self.app.get("/export", headers=self.headers)
    assertions.assertSuccess(self, response)
    exportedData = utils.jsonDecode(response.body)
    self.assertIsInstance(exportedData, list)
    self.assertEqual(exportedData[0], expectedExportSpec)
    responseData = utils.jsonDecode(createResponse.body)
    uid = responseData[0]['uid']

    # Test for exporting single metric.
    response = self.app.get("/%s/export" % uid, headers=self.headers)
    assertions.assertSuccess(self, response)
    exportedData = utils.jsonDecode(response.body)
    self.assertIsInstance(exportedData, list)
    self.assertEqual(exportedData[0], expectedExportSpec)

    # Delete the model that was created earlier
    response = self.app.delete("/%s" % uid, headers=self.headers)
    assertions.assertDeleteSuccessResponse(self, response)

    # Import the model from exported data
    response = self.app.put("/", utils.jsonEncode(exportedData),
                            headers=self.headers)
    assertions.assertSuccess(self, response, code=201)
    responseData = utils.jsonDecode(response.body)
    uid = responseData[0]['uid']

    # Export the newly-imported model
    response = self.app.get("/%s/export" % uid, headers=self.headers)
    assertions.assertSuccess(self, response)
    exportedData = utils.jsonDecode(response.body)
    self.assertIsInstance(exportedData, list)
    self.assertEqual(exportedData[0], expectedExportSpec)

    # Delete the model that was created earlier
    response = self.app.delete("/%s" % uid, headers=self.headers)
    assertions.assertDeleteSuccessResponse(self, response)

    # Import the model using legacy format
    legacyImportSpec = dict(type="metric", **data)
    response = self.app.put("/", utils.jsonEncode(legacyImportSpec),
                            headers=self.headers)
    assertions.assertSuccess(self, response, code=201)
    responseData = utils.jsonDecode(response.body)
    uid = responseData[0]['uid']

    # Export the newly-imported model
    response = self.app.get("/%s/export" % uid, headers=self.headers)
    assertions.assertSuccess(self, response)
    exportedData = utils.jsonDecode(response.body)
    self.assertIsInstance(exportedData, list)
    self.assertEqual(exportedData[0], expectedExportSpec)
Exemplo n.º 26
0
  def testCompleteModelsApiLifecycle(self):
    """
      Happy path testing for the route "/_models"
    """
    # get all models in the system when there are no models
    # expected response is []
    response = self.app.get("/", headers=self.headers)
    assertions.assertSuccess(self, response)
    allModelsResult = utils.jsonDecode(response.body)
    self.assertEqual(len(allModelsResult), 0)
    self.assertIsInstance(allModelsResult, list)

    data = self.modelsTestData["create_data"]

    # create a model using PUT;
    # Any HTTP POST call is forwarded to HTTP PUT in the Model API.
    #   def POST(self):
    #      return self.PUT()
    # The tests are just calling PUT.
    # TODO: wouldn't POST be a better method to test in that case, since it
    #  would exercise both POST and PUT?
    response = self.app.put("/", utils.jsonEncode(data), headers=self.headers)
    assertions.assertSuccess(self, response, code=201)
    postResult = utils.jsonDecode(response.body)
    self.assertEqual(len(postResult), 1)
    self._checkCreateModelResult(postResult[0], data)

    # get model that was previously created
    uid = postResult[0]["uid"]
    response = self.app.get("/%s" % uid, headers=self.headers)
    assertions.assertSuccess(self, response)
    getModelResult = utils.jsonDecode(response.body)
    self.assertItemsEqual(getModelResult[0].keys(),
      self.modelsTestData["get_response"].keys())

    # get all models in the system
    response = self.app.get("/", headers=self.headers)
    assertions.assertSuccess(self, response)
    allModelsResult = utils.jsonDecode(response.body)
    self.assertItemsEqual(allModelsResult[0].keys(),
      self.modelsTestData["get_response"].keys())
    self.assertItemsEqual(allModelsResult[0].keys(),
      self.modelsTestData["get_response"].keys())
    self.assertEqual(len(allModelsResult), 1)

    # Repeat the request to monitor same metric and verify that it returns the
    # same model uid instead of creating a new one
    response = self.app.post("/", utils.jsonEncode(data), headers=self.headers)

    assertions.assertSuccess(self, response, code=201)
    postResult = utils.jsonDecode(response.body)
    self.assertEqual(postResult[0]["uid"], uid)
    self.assertEqual(len(postResult), 1)
    self._checkCreateModelResult(postResult[0], data)

    # Compare http and https responses for all models
    for x in range(3):
      https_response = requests.get("https://localhost/_models",
                                    headers=self.headers,
                                    verify=False)
      http_response = requests.get("http://localhost/_models",
                                   headers=self.headers)

      self.assertEqual(http_response.status_code, 200)
      self.assertEqual(https_response.status_code, 200)

      httpsData = json.loads(https_response.text)

      try:
        self.assertIsInstance(httpsData, list)
        self.assertTrue(httpsData)
        for item in httpsData:
          self.assertIn("status", item)
          self.assertIn("last_rowid", item)
          self.assertIn("display_name", item)
          self.assertIn("uid", item)
          self.assertIn("datasource", item)

        httpData = json.loads(http_response.text)
        self.assertIsInstance(httpData, list)
        self.assertTrue(httpData)
        for item in httpData:
          self.assertIn("status", item)
          self.assertIn("last_rowid", item)
          self.assertIn("display_name", item)
          self.assertIn("uid", item)
          self.assertIn("datasource", item)

        self.assertEqual(http_response.text, https_response.text)

        break
      except AssertionError:
        time.sleep(10)

    else:
      self.fail("Unable to synchronize http and https responses.")

    # Compare http and https response for all models data
    https_response = requests.get("https://localhost/_models/data",
                                  headers=self.headers,
                                  verify=False)
    http_response = requests.get("http://localhost/_models/data",
                                 headers=self.headers)

    self.assertEqual(http_response.status_code, 200)
    self.assertEqual(https_response.status_code, 200)

    httpData = json.loads(http_response.text)
    self.assertIsInstance(httpData, dict)
    self.assertItemsEqual(httpData.keys(), ["metrics", "names"])
    self.assertItemsEqual(httpData["names"], ["timestamp",
                                              "value",
                                              "anomaly_score",
                                              "rowid"])

    httpsData = json.loads(https_response.text)
    self.assertIsInstance(httpsData, dict)
    self.assertItemsEqual(httpsData.keys(), ["metrics", "names"])
    self.assertItemsEqual(httpsData["names"], ["timestamp",
                                               "value",
                                               "anomaly_score",
                                               "rowid"])

    # delete the model that was created earlier
    response = self.app.delete("/%s" % uid, headers=self.headers)
    assertions.assertDeleteSuccessResponse(self, response)
Exemplo n.º 27
0
  def testMonitorMetricViaModelSpec(self):
    """
      Happy path testing for the route "/_models" with new modelSpec format
    """
    modelSpec = {
      "datasource": "cloudwatch",

      "metricSpec": {
        "region": "us-west-2",
        "namespace": "AWS/EC2",
        "metric": "CPUUtilization",
        "dimensions": {
          "InstanceId": "i-12d67826"
        }
      },

      "modelParams": {
        "min": 0,  # optional
        "max": 100  # optional
      }
    }

    # create a model
    response = self.app.post("/", utils.jsonEncode(modelSpec),
                             headers=self.headers)
    assertions.assertSuccess(self, response, code=201)
    postResult = utils.jsonDecode(response.body)
    self.assertEqual(len(postResult), 1)
    self._checkCreateModelResult(postResult[0], modelSpec["metricSpec"])

    # get model that was previously created
    uid = postResult[0]["uid"]
    response = self.app.get("/%s" % uid, headers=self.headers)
    assertions.assertSuccess(self, response)
    getModelResult = utils.jsonDecode(response.body)
    self.assertItemsEqual(getModelResult[0].keys(),
      self.modelsTestData["get_response"].keys())

    # get all models in the system
    response = self.app.get("/", headers=self.headers)
    assertions.assertSuccess(self, response)
    allModelsResult = utils.jsonDecode(response.body)
    self.assertItemsEqual(allModelsResult[0].keys(),
      self.modelsTestData["get_response"].keys())
    self.assertItemsEqual(allModelsResult[0].keys(),
      self.modelsTestData["get_response"].keys())
    self.assertEqual(len(allModelsResult), 1)

    # Repeat the request to monitor same metric and verify that it returns the
    # same model uid instead of creating a new one
    response = self.app.post("/", utils.jsonEncode(modelSpec),
                             headers=self.headers)
    assertions.assertSuccess(self, response, code=201)
    postResult = utils.jsonDecode(response.body)
    self.assertEqual(postResult[0]["uid"], uid)
    self.assertEqual(len(postResult), 1)
    self._checkCreateModelResult(postResult[0], modelSpec["metricSpec"])

    # Unmonitor the metric
    response = self.app.delete("/%s" % uid, headers=self.headers)
    assertions.assertDeleteSuccessResponse(self, response)
Exemplo n.º 28
0
 def _getCloudWatchCommon(self, url, expectedResult):
   response = self.app.get(url, headers=self.headers)
   assertions.assertSuccess(self, response)
   result = app_utils.jsonDecode(response.body)
   self.assertIsInstance(result, dict)
   self.assertEqual(result, expectedResult)
Exemplo n.º 29
0
  def testLifecycleForMultipleInstances(self):
    """
    Test for Get '/_instances'
    response is validated for appropriate headers, body and status
    This expects response from application in initial stage when
    no instances are under monitor

    Test for post '/_instances'
    response is validated for appropriate headers, body and status
    post multiple instances

    Test for Get '/_instances'
    response is validated for appropriate headers, body and status
    This test check for listed monitored instances from previous step

    Test for delete '/_instances'
    response is validated for appropriate headers, body and status
    invoke delete with valid instanceId for listed monitored instances
    from previous step


    Test for Get '/_instances'
    response is validated for appropriate headers, body and status
    This invokes get call to assert that all instances which were
    under monitor have been deleted and we get empty response
    """
    # Check instance list at initial phase for empty response
    getIntialResponse = self.app.get("", headers=self.headers)
    assertions.assertSuccess(self, getIntialResponse)
    getIntialResult = app_utils.jsonDecode(getIntialResponse.body)
    self.assertItemsEqual(getIntialResult, [])


    # Test for post '/_instances'

    # TODO: Until MER-1172 is resolved
    # test will execute this as temporary. This will add expected instances
    # under monitor. Which will be used for further tests
    # here adding
    params = [VALID_EC2_INSTANCES["rpm-builder"]["instanceId"],
      VALID_EC2_INSTANCES["htm-it-docs"]["instanceId"]]
    region = "us-west-2"
    namespace = "EC2"
    for instance in params:
      postResponse = self.app.post("/%s/AWS/%s/%s" % (region,
       namespace, instance), headers=self.headers)
      assertions.assertSuccess(self, postResponse)
      postResult = app_utils.jsonDecode(postResponse.body)
      self.assertIsInstance(postResult, dict)
      self.assertEqual(postResult, {"result": "success"})

    # TODO Use Api calls below once MER-1172 is resolved

    #postResponse = self.app.post("/us-west-2/AWS/EC2",
    #  params=app_utils.jsonEncode(params), headers=self.headers, status="*")
    #assertions.assertSuccess(self, response)
    #postResult = app_utils.jsonDecode(postResponse.body)
    #self.assertIsInstance(postResult, dict)
    #self.assertEqual(postResult, {"result": "success"})

    # Test for Get '/_instances'
    getPostCheckResponse = self.app.get("", headers=self.headers)
    assertions.assertSuccess(self, getPostCheckResponse)
    getPostCheckResult = app_utils.jsonDecode(getPostCheckResponse.body)
    instanceIds = []
    self.assertIsInstance(getPostCheckResult, list)
    for instance in getPostCheckResult:
      instanceIds.append(instance["server"])
      self.assertEqual(instance["namespace"], "AWS/EC2")
      self.assertEqual(instance["location"], "us-west-2")
    self.assertItemsEqual([instanceId.rpartition("/")[2]
                           for instanceId in instanceIds], params)

    # Delete instances under monitor
    deleteResponse = self.app.delete("",
                                     params=app_utils.jsonEncode(instanceIds),
                                     headers=self.headers)
    assertions.assertDeleteSuccessResponse(self, deleteResponse)

    # check instances to confirm the delete action
    getPostDeleteCheckResponse = self.app.get("", headers=self.headers)
    assertions.assertSuccess(self, getPostDeleteCheckResponse)
    getPostDeleteResult = app_utils.jsonDecode(getPostDeleteCheckResponse.body)
    self.assertItemsEqual(getPostDeleteResult, [])