@Test
  public void testHandleEvent_withContext_withRule_strictMaximum() throws Exception {

    Mockito.when(
            this.preferencesMngr.get(
                IPreferencesMngr.AUTONOMIC_MAX_VM_NUMBER, "" + Integer.MAX_VALUE))
        .thenReturn("4");
    Mockito.when(this.preferencesMngr.get(IPreferencesMngr.AUTONOMIC_STRICT_MAX_VM_NUMBER, "true"))
        .thenReturn("true");

    ManagedApplication ma = factorizeConfiguration();
    this.autonomicMngr.handleEvent(ma, new MsgNotifAutonomic("app", "/root", "event", null));

    Mockito.verify(this.preferencesMngr, Mockito.times(1))
        .get(IPreferencesMngr.AUTONOMIC_MAX_VM_NUMBER, "" + Integer.MAX_VALUE);
    Mockito.verify(this.preferencesMngr, Mockito.times(1))
        .get(IPreferencesMngr.AUTONOMIC_STRICT_MAX_VM_NUMBER, "true");

    ArgumentCaptor<CommandExecutionContext> execCtx =
        ArgumentCaptor.forClass(CommandExecutionContext.class);
    Mockito.verify(this.commandsMngr, Mockito.times(3))
        .execute(Mockito.any(Application.class), Mockito.anyString(), execCtx.capture());

    for (CommandExecutionContext c : execCtx.getAllValues()) {
      Assert.assertEquals(4, c.getMaxVm());
      Assert.assertTrue(c.isStrictMaxVm());
    }
  }
  @Test
  public void testHandleEvent_withContext_withRule() throws Exception {

    Mockito.when(this.preferencesMngr.get(Mockito.anyString(), Mockito.anyString()))
        .thenReturn("5");

    Rule rule1 = Mockito.mock(Rule.class);
    Mockito.when(rule1.getCommandsToInvoke()).thenReturn(Arrays.asList("cmd1"));

    Rule rule2 = Mockito.mock(Rule.class);
    Mockito.when(rule2.getCommandsToInvoke()).thenReturn(Arrays.asList("cmd2", "cmd3"));

    Application app = new Application("app", new TestApplicationTemplate());
    AutonomicApplicationContext ctx = Mockito.spy(new AutonomicApplicationContext(app));
    Mockito.when(ctx.findRulesToExecute()).thenReturn(Arrays.asList(rule1, rule2));
    this.autonomicMngr.appNameToContext.put("app", ctx);

    ManagedApplication ma = new ManagedApplication(app);
    this.autonomicMngr.handleEvent(ma, new MsgNotifAutonomic("app", "/root", "event", null));

    Mockito.verify(this.preferencesMngr, Mockito.times(2))
        .get(Mockito.anyString(), Mockito.anyString());

    Map<?, ?> eventNameToLastRecordTime =
        TestUtils.getInternalField(ctx, "eventNameToLastRecordTime", Map.class);
    Assert.assertEquals(1, eventNameToLastRecordTime.size());
    Assert.assertNotNull(eventNameToLastRecordTime.get("event"));

    Mockito.verify(rule1, Mockito.times(1)).getCommandsToInvoke();
    Mockito.verify(rule2, Mockito.times(1)).getCommandsToInvoke();

    ArgumentCaptor<CommandExecutionContext> execCtx =
        ArgumentCaptor.forClass(CommandExecutionContext.class);
    Mockito.verify(this.commandsMngr, Mockito.times(3))
        .execute(
            Mockito.any(Application.class),
            Mockito.anyString(),
            Mockito.any(CommandExecutionContext.class));

    for (CommandExecutionContext c : execCtx.getAllValues()) {
      Assert.assertEquals(5, c.getMaxVm());
      Assert.assertFalse(c.isStrictMaxVm());
    }
  }
  @Test
  public void testHandleEvent_withContext_withRule_negativeMaxVmNumber() throws Exception {

    Mockito.when(this.preferencesMngr.get(Mockito.anyString(), Mockito.anyString()))
        .thenReturn("-1");

    ManagedApplication ma = factorizeConfiguration();
    this.autonomicMngr.handleEvent(ma, new MsgNotifAutonomic("app", "/root", "event", null));

    ArgumentCaptor<CommandExecutionContext> execCtx =
        ArgumentCaptor.forClass(CommandExecutionContext.class);
    Mockito.verify(this.commandsMngr, Mockito.times(3))
        .execute(Mockito.any(Application.class), Mockito.anyString(), execCtx.capture());

    for (CommandExecutionContext c : execCtx.getAllValues()) {
      Assert.assertEquals(Integer.MAX_VALUE, c.getMaxVm());
      Assert.assertFalse(c.isStrictMaxVm());
    }
  }
  @Test
  public void testHandleEvent_withContext_withRule_strictMaximumEnabledAutomatically()
      throws Exception {

    // More VM than what the preferences allow => the "strict" parameter will be set automatically.
    TestUtils.getInternalField(this.autonomicMngr, "autonomicVmCount", AtomicInteger.class).set(10);
    Mockito.when(this.preferencesMngr.get(Mockito.anyString(), Mockito.anyString()))
        .thenReturn("5");

    ManagedApplication ma = factorizeConfiguration();
    this.autonomicMngr.handleEvent(ma, new MsgNotifAutonomic("app", "/root", "event", null));

    ArgumentCaptor<CommandExecutionContext> execCtx =
        ArgumentCaptor.forClass(CommandExecutionContext.class);
    Mockito.verify(this.commandsMngr, Mockito.times(3))
        .execute(Mockito.any(Application.class), Mockito.anyString(), execCtx.capture());

    for (CommandExecutionContext c : execCtx.getAllValues()) {
      Assert.assertEquals(5, c.getMaxVm());
      Assert.assertTrue(c.isStrictMaxVm());
    }
  }