private void testChargeAndRecommendForNoExceedNoForce() throws Exception {
    RestRequest restRequest =
        QuotaTestUtils.createRestRequest(ACCOUNT, ACCOUNT.getAllContainers().iterator().next(), RestMethod.GET);
    AmbryQuotaManager ambryQuotaManager = buildAmbryQuotaManagerWithNoEnforcers();
    ambryQuotaManager.init();

    // 1. test that chargeAndRecommend returns ALLOW with not enforcers.
    QuotaAction quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, null, false, false);
    Assert.assertEquals(QuotaAction.ALLOW, quotaAction);

    // 2. test that enforcers are called.
    ambryQuotaManager = buildAmbryQuotaManagerWithAmbryCUEnforcer();
    testAmbryCUQuotaEnforcer.resetDefaults();
    ambryQuotaManager.init();
    Map<QuotaName, Double> costMap = Collections.singletonMap(QuotaName.READ_CAPACITY_UNIT, 11.0);
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(QuotaAction.ALLOW, quotaAction);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer.recommendCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer.chargeCallCount);
    Assert.assertEquals(110, testAmbryCUQuotaEnforcer.getQuotaSource()
        .getUsage(QuotaResource.fromRestRequest(restRequest), QuotaName.READ_CAPACITY_UNIT), 0.0001);

    // 3. test that if one enforcer recommends delay then no charge is done and delay is returned.
    testAmbryCUQuotaEnforcer.resetDefaults();
    ambryQuotaManager.init();
    costMap = Collections.singletonMap(QuotaName.READ_CAPACITY_UNIT, 1.0);
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(expectedDelayRecommendationQuotaExceed, quotaAction);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer.recommendCallCount);
    Assert.assertEquals(isRequestThrottlingEnabled ? 0 : 1, testAmbryCUQuotaEnforcer.chargeCallCount);
    Assert.assertEquals(isRequestThrottlingEnabled ? 110 : 120, testAmbryCUQuotaEnforcer.getQuotaSource()
        .getUsage(QuotaResource.fromRestRequest(restRequest), QuotaName.READ_CAPACITY_UNIT), 0.0001);

    // 4. test that if one enforcer recommends reject then no charge is done and reject is returned.
    ambryQuotaManager = buildAmbryQuotaManager();
    List<QuotaEnforcer> quotaEnforcers = new ArrayList<>(ambryQuotaManager.quotaEnforcers);
    TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer testAmbryCUQuotaEnforcer1 =
        (TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer) quotaEnforcers.get(0);
    TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer testAmbryCUQuotaEnforcer2 =
        (TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer) quotaEnforcers.get(1);
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    ambryQuotaManager.init();

    testAmbryCUQuotaEnforcer1.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.REJECT_QUOTA_RECOMMENDATION;
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(QuotaAction.REJECT, quotaAction);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);

    // 4a. flip the enforcer that returns reject.
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    testAmbryCUQuotaEnforcer2.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.REJECT_QUOTA_RECOMMENDATION;
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(QuotaAction.REJECT, quotaAction);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);

    // 5. test that if one enforcer recommends reject and another returns delay then no charge is done and reject is returned.
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    testAmbryCUQuotaEnforcer1.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.REJECT_QUOTA_RECOMMENDATION;
    testAmbryCUQuotaEnforcer2.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.DELAY_QUOTA_RECOMMENDATION;
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(QuotaAction.REJECT, quotaAction);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);

    // 5a. flip the enforcer that returns reject.
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    testAmbryCUQuotaEnforcer1.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.DELAY_QUOTA_RECOMMENDATION;
    testAmbryCUQuotaEnforcer2.recommendReturnVal =
        TestCUQuotaEnforcerFactory.TestAmbryCUQuotaEnforcer.REJECT_QUOTA_RECOMMENDATION;
    quotaAction = ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
    Assert.assertEquals(QuotaAction.REJECT, quotaAction);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);

    // 6. test that if any enforcer's recommend throws exception, the exception is thrown from chargeAndRecommend.
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    testAmbryCUQuotaEnforcer1.throwException = true;
    try {
      ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
      Assert.fail("If any enforcer's recommend throws exception, then chargeAndRecommend should throw exception.");
    } catch (QuotaException ignored) {
    }
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);

    // 6a. flip the enforcer that throws exception
    testAmbryCUQuotaEnforcer1.resetDefaults();
    testAmbryCUQuotaEnforcer2.resetDefaults();
    testAmbryCUQuotaEnforcer2.throwException = true;
    try {
      ambryQuotaManager.chargeAndRecommend(restRequest, costMap, false, false);
      Assert.fail("If any enforcer's recommend throws exception, then chargeAndRecommend should throw exception.");
    } catch (QuotaException ignored) {
    }
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer1.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.initCallCount);
    Assert.assertEquals(1, testAmbryCUQuotaEnforcer2.recommendCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.chargeCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer1.isQuotaExceedAllowedCallCount);
    Assert.assertEquals(0, testAmbryCUQuotaEnforcer2.isQuotaExceedAllowedCallCount);
  }
Test {@link QuotaManager#chargeAndRecommend} when quota exceed check and force charge are set to false.
@throws Exception in case of any exception.
ambry-quota/src/test/java/com/github/ambry/quota/AmbryQuotaManagerTest.java