def checkQuotaForInstanceAndRaise(conn, instanceName): """ Perform instance quota check and raise QuotaError exception if request to create a model for `instanceName` would result in a new "instance" being created beyond quota. This function answers the question: Is there room to add a new model for a new, or existing instance? And raises an exception if the answer is no. :param conn: SQLAlchemy connection object :type conn: sqlalchemy.engine.Connection :param instanceName: Instance name :type instanceName str: :raises: grok.app.exceptions.QuotaError """ instanceCount = repository.getInstanceCount(conn) instanceQuota = Quota.getInstanceQuota() if instanceCount >= instanceQuota: if not repository.listMetricIDsForInstance(conn, instanceName): raise QuotaError( "Server limit exceeded; edition=%s; count=%i; limit=%i." % (product.get("edition", "type").title(), instanceCount, instanceQuota))
def testPOSTAutostacksQuota(self, adapterMock, quotaRepositoryMock, _repositoryMock): quotaRepositoryMock.getInstanceCount.return_value = 0 adapterMock.return_value.createAutostack.side_effect = QuotaError() with self.assertRaises(AppError) as e: self.app.post("/", self.jsonAutostack, headers=self.headers) self.assertIn("Bad response: 403 Forbidden", str(e.exception)) self.assertTrue(adapterMock.return_value.createAutostack.called)
class InstanceDefaultsHandlerTest(unittest.TestCase): """Unit tests for class InstanceDefaultsHandler from Instances API.""" def setUp(self): self.app = TestApp(instances_api.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(config) @patch.object(repository, "listMetricIDsForInstance", autospec=True) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel)) def testInstanceDefaultsHandlerPOST(self, listMetricIDsMock, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" response is validated for appropriate headers, body and status """ listMetricIDsMock.return_value = [] region = "us-west-2" # Currently we are not supporting certain namespaces # unsupportedNamespaces reflects such unsupported namespaces # These namespaces are currently validated for "400 Bad Request" # and expected error message. # Update this list with changes in namespace support unsupportedNamespaces = ("Billing", "StorageGateway") for namespace in unsupportedNamespaces: response = self.app.post("/%s/AWS/%s/abcd1234" % (region, namespace), headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") result = json.loads(response.body)["result"] self.assertTrue(result.startswith("Not supported.")) cwAdapter = datasource.createDatasourceAdapter("cloudwatch") supportedNamespaces = set() for resourceInfo in cwAdapter.describeSupportedMetrics().values(): for metricInfo in resourceInfo.values(): supportedNamespaces.add(metricInfo["namespace"]) for namespace in supportedNamespaces: response = self.app.post("/%s/%s/abcd1234" % (region, namespace), headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) self.assertEqual(result, {"result": "success"}) @patch.object(repository, "getMetricCountForServer", autospec=True) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel, side_effect=QuotaError("Server limit reached."))) def testInstanceDefaultsHandlerPOSTQuotaError(self, getMetricCountForServerMock, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" Test for QuotaError thrown when reached number of server limit reached """ getMetricCountForServerMock.return_value = 0 response = self.app.post("/us-west-2/AWS/EC2/abcd1234", headers=self.headers, status="*") assertions.assertForbiddenResponse(self, response) result = app_utils.jsonDecode(response.body) self.assertEqual(result, {"result": "Server limit reached."}) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel)) def testInstanceDefaultsHandlerPOSTWithoutInstanceId( self, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" without instanceId response is validated for appropriate headers, body and status """ response = self.app.post("/us-west-2/AWS/EC2/", headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Invalid request", response.body) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel)) def testInstanceDefaultsHandlerPOSTInvalidNamespace( self, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" with invalid namespace response is validated for appropriate headers, body and status """ response = self.app.post("/us-west-2/AWS/foo/abcd1234", headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel)) def testInstanceDefaultsHandlerPOSTInvalidNamespeceInsteadAWS( self, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" with invalid namespace. response is validated for appropriate headers, body and status """ response = self.app.post("/us-west-2/foo/EC2/abcd1234", headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body) @patch("grok.app.webservices.models_api.ModelHandler.createModel", new=Mock(spec_set=models_api.ModelHandler.createModel)) def testInstanceDefaultsHandlerPOSTInvalidRegion(self, _engineFactoryMock): """ Test for POST "/_instances/region/namespace/instanceId" with invalid region response is validated for appropriate headers, body and status """ response = self.app.post("/fake-region/AWS/EC2/abcd1234", headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body)