Example #1
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, [])
  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, [])
    def testDeleteInstanceHandler(self, listMetricIDsMock, engineFactoryMock):
        """
    Test for Delete "/_instances/<instanceId>"
    response is validated for appropriate headers, body and status
    """
        listMetricIDsMock.return_value = ["2490fb7a9df5470fa3678530c4cb0a43", "b491ab2310ef4a799b14c08fa3e09f1c"]
        response = self.app.delete("", headers=self.headers, params=json.dumps(["i-cd660efb"]))

        assertions.assertDeleteSuccessResponse(self, response)
        self.assertTrue(listMetricIDsMock.called)
        listMetricIDsMock.assert_called_once_with(
            (engineFactoryMock.return_value.connect.return_value.__enter__.return_value), "i-cd660efb"
        )
 def testDeleteInstancesHandler(self, listMetricIDsMock, engineFactoryMock):
     """
 Test for Delete "/_instances"
 response is validated for appropriate headers, body and status
 """
     listMetricIDsMock.return_value = ["2490fb7a9df5470fa3678530c4cb0a43", "b491ab2310ef4a799b14c08fa3e09f1c"]
     params = ["grok-docs-elb", "i-e16bd2d5"]
     response = self.app.delete("", params=app_utils.jsonEncode(params), headers=self.headers)
     assertions.assertDeleteSuccessResponse(self, response)
     self.assertTrue(listMetricIDsMock.called)
     listMetricIDsMock.assert_called_with(
         (engineFactoryMock.return_value.connect.return_value.__enter__.return_value), params[1]
     )
 def testDeleteInstancesHandler(self, listMetricIDsMock, engineFactoryMock):
     """
 Test for Delete "/_instances"
 response is validated for appropriate headers, body and status
 """
     listMetricIDsMock.return_value = \
       ["2490fb7a9df5470fa3678530c4cb0a43", "b491ab2310ef4a799b14c08fa3e09f1c"]
     params = ["grok-docs-elb", "i-e16bd2d5"]
     response = self.app.delete("",
                                params=app_utils.jsonEncode(params),
                                headers=self.headers)
     assertions.assertDeleteSuccessResponse(self, response)
     self.assertTrue(listMetricIDsMock.called)
     listMetricIDsMock.assert_called_with(
         (engineFactoryMock.return_value.connect.return_value.__enter__.
          return_value), params[1])
Example #6
0
  def testDeleteInstanceHandler(self, listMetricIDsMock, engineFactoryMock):
    """
    Test for Delete "/_instances/<instanceId>"
    response is validated for appropriate headers, body and status
    """
    listMetricIDsMock.return_value = ["2490fb7a9df5470fa3678530c4cb0a43",
                                      "b491ab2310ef4a799b14c08fa3e09f1c"]
    response = self.app.delete("", headers=self.headers,
                               params=json.dumps(["i-cd660efb"]))

    assertions.assertDeleteSuccessResponse(self, response)
    self.assertTrue(listMetricIDsMock.called)
    listMetricIDsMock.assert_called_once_with(
      (engineFactoryMock.return_value.connect.return_value.__enter__
       .return_value),
      "i-cd660efb")
Example #7
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["grok-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, [])
  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["grok-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, [])
    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)
Example #10
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)
Example #11
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)
Example #12
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)
Example #13
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)
Example #14
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)