@Test
  public void testLoadUpdateAndRemove() throws Exception {

    // Create an application
    TestApplication app = new TestApplication();
    app.setDirectory(this.folder.newFolder());

    // Create rule files
    File autonomicRulesDir = new File(app.getDirectory(), Constants.PROJECT_DIR_RULES_AUTONOMIC);
    Assert.assertTrue(autonomicRulesDir.mkdir());

    File f = new File(autonomicRulesDir, "rule1.invalid-ext");
    Assert.assertTrue(f.createNewFile());

    f = new File(autonomicRulesDir, "rule2" + Constants.FILE_EXT_RULE);
    Utils.writeStringInto("rule \"test1\"\nwhen event1 then cmd1 end", f);

    f = new File(autonomicRulesDir, "rule3" + Constants.FILE_EXT_RULE);
    Utils.writeStringInto("rule \"test2\"\nwhen event2 then invalid syntax", f);

    // Load the rules
    Assert.assertEquals(0, this.autonomicMngr.appNameToContext.size());
    this.autonomicMngr.loadApplicationRules(app);
    Assert.assertEquals(1, this.autonomicMngr.appNameToContext.size());

    AutonomicApplicationContext ctx = this.autonomicMngr.appNameToContext.get(app.getName());
    Assert.assertNotNull(ctx);
    Assert.assertEquals(1, ctx.ruleNameToRule.size());
    Assert.assertNotNull(ctx.ruleNameToRule.get("test1"));

    // Update the invalid rule
    Utils.writeStringInto("rule \"test2\"\nwhen event2 then cmd2 end", f);
    this.autonomicMngr.refreshApplicationRules(app, "rule3");
    Assert.assertEquals(1, this.autonomicMngr.appNameToContext.size());

    Assert.assertEquals(2, ctx.ruleNameToRule.size());
    Assert.assertNotNull(ctx.ruleNameToRule.get("test1"));
    Assert.assertNotNull(ctx.ruleNameToRule.get("test2"));

    // Reload the first one
    Rule oldRule1 = ctx.ruleNameToRule.remove("test1");
    this.autonomicMngr.refreshApplicationRules(app, "rule2" + Constants.FILE_EXT_RULE);

    Assert.assertEquals(1, this.autonomicMngr.appNameToContext.size());
    Assert.assertEquals(2, ctx.ruleNameToRule.size());
    Assert.assertNotNull(ctx.ruleNameToRule.get("test1"));
    Assert.assertNotNull(ctx.ruleNameToRule.get("test2"));
    Assert.assertNotSame(oldRule1, ctx.ruleNameToRule.get("test1"));

    // Unload the rules
    this.autonomicMngr.unloadApplicationRules(app);
    Assert.assertEquals(0, this.autonomicMngr.appNameToContext.size());
  }
  @Test
  public void testLoadRules_noAutonomicDir() throws Exception {

    // Create an application
    TestApplication app = new TestApplication();
    app.setDirectory(this.folder.newFolder());

    // Load the rules
    Assert.assertEquals(0, this.autonomicMngr.appNameToContext.size());
    this.autonomicMngr.loadApplicationRules(app);
    Assert.assertEquals(1, this.autonomicMngr.appNameToContext.size());

    AutonomicApplicationContext ctx = this.autonomicMngr.appNameToContext.get(app.getName());
    Assert.assertNotNull(ctx);
    Assert.assertEquals(0, ctx.ruleNameToRule.size());
  }
  @Test
  public void testRefreshRules_unknownRule() throws Exception {

    // Create an application
    TestApplication app = new TestApplication();
    app.setDirectory(this.folder.newFolder());

    // Create the autonomic directory
    File autonomicRulesDir = new File(app.getDirectory(), Constants.PROJECT_DIR_RULES_AUTONOMIC);
    Assert.assertTrue(autonomicRulesDir.mkdir());

    // Load the rules
    Assert.assertEquals(0, this.autonomicMngr.appNameToContext.size());
    this.autonomicMngr.loadApplicationRules(app);
    Assert.assertEquals(1, this.autonomicMngr.appNameToContext.size());

    AutonomicApplicationContext ctx = this.autonomicMngr.appNameToContext.get(app.getName());
    Assert.assertNotNull(ctx);
    Assert.assertEquals(0, ctx.ruleNameToRule.size());

    // Try to refresh an invalid rule
    this.autonomicMngr.refreshApplicationRules(app, "unknown");
    Assert.assertEquals(0, ctx.ruleNameToRule.size());
  }
  @Test
  public void testFindUsageStatistics() throws Exception {

    // Setup
    TestApplication app = new TestApplication();
    Instance newRootInstance = new Instance("newRoot").component(app.getMySqlVm().getComponent());
    app.getRootInstances().add(newRootInstance);

    String t1 = this.mngr.createTarget("prop: ok\nid: t1\nhandler: h");
    String t2 = this.mngr.createTarget("prop: ok\nid: t2\nhandler: h");
    String t3 = this.mngr.createTarget("prop: ok\nid: t3\nhandler: h");

    this.mngr.associateTargetWith(t1, app, InstanceHelpers.computeInstancePath(app.getMySqlVm()));
    this.mngr.associateTargetWith(t1, app, InstanceHelpers.computeInstancePath(newRootInstance));
    this.mngr.associateTargetWith(t2, app, null);

    // Checks
    List<TargetUsageItem> items = this.mngr.findUsageStatistics(t1);
    Assert.assertEquals(1, items.size());

    TargetUsageItem item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t2);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t3);
    Assert.assertEquals(0, items.size());

    // Mark one as used
    this.mngr.lockAndGetTarget(app, app.getTomcatVm());

    items = this.mngr.findUsageStatistics(t1);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t3);
    Assert.assertEquals(0, items.size());

    items = this.mngr.findUsageStatistics(t2);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertTrue(item.isReferencing());

    // The change is here!
    Assert.assertTrue(item.isUsing());

    // Release it
    this.mngr.unlockTarget(app, app.getTomcatVm());

    items = this.mngr.findUsageStatistics(t1);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t2);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t3);
    Assert.assertEquals(0, items.size());

    // Remove the association for the named instance
    this.mngr.dissociateTargetFrom(app, InstanceHelpers.computeInstancePath(app.getMySqlVm()));
    items = this.mngr.findUsageStatistics(t1);
    Assert.assertEquals(1, items.size());

    this.mngr.dissociateTargetFrom(app, InstanceHelpers.computeInstancePath(newRootInstance));
    items = this.mngr.findUsageStatistics(t1);
    Assert.assertEquals(0, items.size());

    items = this.mngr.findUsageStatistics(t2);
    Assert.assertEquals(1, items.size());

    item = items.get(0);
    Assert.assertEquals(app.getName(), item.getName());
    Assert.assertNull(item.getQualifier());
    Assert.assertFalse(item.isUsing());
    Assert.assertTrue(item.isReferencing());

    items = this.mngr.findUsageStatistics(t3);
    Assert.assertEquals(0, items.size());
  }