@Test
  public void testHints_noHint() throws Exception {

    TestApplication app1 = new TestApplication();
    app1.name("app1");
    TestApplication app2 = new TestApplication();
    app2.name("app2");

    String t1 =
        this.mngr.createTarget(
            "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h");
    String t2 = this.mngr.createTarget("id: t2\nprop: ok\nhandler: docker");

    List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    TargetWrapperDescriptor b1 = beans.get(0);
    Assert.assertEquals(t1, b1.getId());
    Assert.assertEquals("target 1", b1.getName());
    Assert.assertEquals("t1's target", b1.getDescription());
    Assert.assertNotNull(b1.getHandler());
    Assert.assertFalse(b1.isDefault());

    TargetWrapperDescriptor b2 = beans.get(1);
    Assert.assertEquals(t2, b2.getId());
    Assert.assertEquals("docker", b2.getHandler());
    Assert.assertNull(b2.getName());
    Assert.assertNull(b2.getDescription());
    Assert.assertFalse(b2.isDefault());

    Assert.assertEquals(2, this.mngr.listPossibleTargets(app2).size());
  }
  @Test
  public void testHints_hintOnApplicationTemplate() throws Exception {

    TestApplication app1 = new TestApplication();
    app1.name("app1");
    TestApplication app2 = new TestApplication();
    app2.name("app2");
    Application app3 = new Application("app3", new ApplicationTemplate("tpl").qualifier("v1"));

    String t1 =
        this.mngr.createTarget(
            "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h");
    String t2 = this.mngr.createTarget("id: t2\nprop: ok\nhandler: docker");

    // Hint between app1 and app2's template and t1.
    // t1 has now a scope, which includes (indirectly) app1 and app2.
    // Therefore, t1 should not be listed for app3 (not in the scope).
    this.mngr.addHint(t1, app1.getTemplate());

    List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    TargetWrapperDescriptor b1 = beans.get(0);
    Assert.assertEquals(t1, b1.getId());
    Assert.assertEquals("target 1", b1.getName());
    Assert.assertEquals("t1's target", b1.getDescription());
    Assert.assertNotNull(b1.getHandler());
    Assert.assertFalse(b1.isDefault());

    TargetWrapperDescriptor b2 = beans.get(1);
    Assert.assertEquals(t2, b2.getId());
    Assert.assertEquals("docker", b2.getHandler());
    Assert.assertNull(b2.getName());
    Assert.assertNull(b2.getDescription());
    Assert.assertFalse(b2.isDefault());

    List<TargetWrapperDescriptor> otherBeans = this.mngr.listPossibleTargets(app2);
    Assert.assertEquals(beans, otherBeans);

    otherBeans = this.mngr.listPossibleTargets(app2.getTemplate());
    Assert.assertEquals(beans, otherBeans);

    beans = this.mngr.listPossibleTargets(app3);
    Assert.assertEquals(1, beans.size());

    b2 = beans.get(0);
    Assert.assertEquals(t2, b2.getId());
    Assert.assertEquals("docker", b2.getHandler());
    Assert.assertNull(b2.getName());
    Assert.assertNull(b2.getDescription());
    Assert.assertFalse(b2.isDefault());
  }
  @Test
  public void testHints_removeHintOnApplication() throws Exception {

    TestApplication app1 = new TestApplication();
    app1.name("app1");
    TestApplication app2 = new TestApplication();
    app2.name("app2");

    String t1 =
        this.mngr.createTarget(
            "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h");
    String t2 = this.mngr.createTarget("id: t2\nprop: ok\nhandler: docker\nhandler: h");

    // Hint between app1 and t1.
    // t1 has now a scope, which includes app1.
    // Therefore, t1 should not be listed for app2 (not in the scope).
    this.mngr.addHint(t1, app1);

    List<TargetWrapperDescriptor> beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    beans = this.mngr.listPossibleTargets(app2);
    Assert.assertEquals(1, beans.size());

    // Remove the hint on the WRONG application => nothing changes
    this.mngr.removeHint(t1, app2);

    beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    beans = this.mngr.listPossibleTargets(app2);
    Assert.assertEquals(1, beans.size());

    // Remove the hint on the WRONG application => nothing changes
    this.mngr.removeHint(t2, app1);

    beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    beans = this.mngr.listPossibleTargets(app2);
    Assert.assertEquals(1, beans.size());

    // Remove the hint on the one we used
    this.mngr.removeHint(t1, app1);

    beans = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(2, beans.size());

    beans = this.mngr.listPossibleTargets(app2);
    Assert.assertEquals(2, beans.size());
  }
  @Test
  public void testApplicationWasDeleted() throws Exception {

    // Prepare the model
    TestApplication app1 = new TestApplication();
    app1.name("app1");
    TestApplication app2 = new TestApplication();
    app2.name("app2");

    String t1 =
        this.mngr.createTarget(
            "id: t1\nprop: ok\nname: target 1\ndescription: t1's target\nhandler: h");
    String t2 = this.mngr.createTarget("id: t2\nprop: ok\nhandler: docker");

    String path = InstanceHelpers.computeInstancePath(app1.getTomcatVm());

    // Create hints and associations
    this.mngr.associateTargetWith(t1, app1.getTemplate(), null);
    this.mngr.associateTargetWith(t1, app1, null);
    this.mngr.associateTargetWith(t2, app1, path);
    this.mngr.associateTargetWith(t2, app2, null);

    this.mngr.addHint(t1, app1);
    this.mngr.addHint(t2, app1);
    this.mngr.addHint(t2, app2);

    // Verify preconditions
    Assert.assertEquals(t1, this.mngr.findTargetId(app1, null));
    Assert.assertEquals(t2, this.mngr.findTargetId(app1, path));
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app1).size());

    Assert.assertEquals(t2, this.mngr.findTargetId(app2, null));
    Assert.assertEquals(t2, this.mngr.findTargetId(app2, path));
    Assert.assertEquals(1, this.mngr.listPossibleTargets(app2).size());

    Assert.assertEquals(t1, this.mngr.findTargetId(app1.getTemplate(), path));
    Assert.assertEquals(0, this.mngr.listPossibleTargets(app1.getTemplate()).size());

    // Delete the application
    this.mngr.applicationWasDeleted(app1);

    // Verify post-conditions
    Assert.assertNull(this.mngr.findTargetId(app1, null));
    Assert.assertNull(this.mngr.findTargetId(app1, path));

    // t1 has not hint anymore, so it becomes global
    List<TargetWrapperDescriptor> hints = this.mngr.listPossibleTargets(app1);
    Assert.assertEquals(1, hints.size());
    Assert.assertEquals(t1, hints.get(0).getId());

    Assert.assertEquals(t2, this.mngr.findTargetId(app2, null));
    Assert.assertEquals(t2, this.mngr.findTargetId(app2, path));

    // t1 is global now
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app2).size());

    // t1 is global now
    Assert.assertEquals(t1, this.mngr.findTargetId(app1.getTemplate(), path));
    Assert.assertEquals(1, this.mngr.listPossibleTargets(app1.getTemplate()).size());

    // Delete the template of app1
    this.mngr.applicationWasDeleted(app1.getTemplate());

    // Verify post-conditions
    Assert.assertNull(this.mngr.findTargetId(app1, null));
    Assert.assertNull(this.mngr.findTargetId(app1, path));
    Assert.assertEquals(1, this.mngr.listPossibleTargets(app1).size());

    Assert.assertEquals(t2, this.mngr.findTargetId(app2, null));
    Assert.assertEquals(t2, this.mngr.findTargetId(app2, path));
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app2).size());

    Assert.assertNull(this.mngr.findTargetId(app1.getTemplate(), path));
    Assert.assertEquals(1, this.mngr.listPossibleTargets(app1.getTemplate()).size());

    // Delete app2
    this.mngr.applicationWasDeleted(app2);

    // Verify post-conditions
    // t2 does not have any hint anymore => it is global
    Assert.assertNull(this.mngr.findTargetId(app1, null));
    Assert.assertNull(this.mngr.findTargetId(app1, path));
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app1).size());

    Assert.assertNull(this.mngr.findTargetId(app2, null));
    Assert.assertNull(this.mngr.findTargetId(app2, path));
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app2).size());

    Assert.assertNull(this.mngr.findTargetId(app1.getTemplate(), path));
    Assert.assertEquals(2, this.mngr.listPossibleTargets(app1.getTemplate()).size());
  }