@Test
  public void testAggregateAlerts() throws Exception {
    // create definition
    AlertDefinitionEntity definition = new AlertDefinitionEntity();
    definition.setDefinitionName("to_aggregate");
    definition.setLabel("My Label");
    definition.setLabel("My Description");
    definition.setServiceName(SERVICE);
    definition.setComponentName(null);
    definition.setClusterId(m_cluster.getClusterId());
    definition.setHash(UUID.randomUUID().toString());
    definition.setScheduleInterval(Integer.valueOf(60));
    definition.setScope(Scope.HOST);
    definition.setSource("{\"type\" : \"SCRIPT\"}");
    definition.setSourceType(SourceType.SCRIPT);
    m_definitionDao.create(definition);

    // create aggregate of definition
    AlertDefinitionEntity aggDef = new AlertDefinitionEntity();
    aggDef.setDefinitionName("aggregate_test");
    aggDef.setServiceName(SERVICE);
    aggDef.setComponentName(null);
    aggDef.setClusterId(m_cluster.getClusterId());
    aggDef.setHash(UUID.randomUUID().toString());
    aggDef.setScheduleInterval(Integer.valueOf(60));
    aggDef.setScope(Scope.SERVICE);

    AggregateSource source = new AggregateSource();
    source.setAlertName("to_aggregate");

    // !!! type is protected
    Field field = Source.class.getDeclaredField("type");
    field.setAccessible(true);
    field.set(source, SourceType.AGGREGATE);

    Reporting reporting = new Reporting();

    ReportTemplate template = new ReportTemplate();
    template.setText("You are good {1}/{0}");
    reporting.setOk(template);

    template = new ReportTemplate();
    template.setText("Going bad {1}/{0}");
    template.setValue(Double.valueOf(0.33d));
    reporting.setWarning(template);

    template = new ReportTemplate();
    template.setText("On fire! {1}/{0}");
    template.setValue(Double.valueOf(0.66d));
    reporting.setCritical(template);

    source.setReporting(reporting);

    Gson gson = new Gson();

    aggDef.setSource(gson.toJson(source));
    aggDef.setSourceType(SourceType.AGGREGATE);
    m_definitionDao.create(aggDef);

    // add current and history across four hosts
    for (int i = 0; i < 4; i++) {
      AlertHistoryEntity history = new AlertHistoryEntity();
      history.setAlertDefinition(definition);
      history.setAlertInstance(null);
      history.setAlertLabel(definition.getLabel());
      history.setAlertState(AlertState.OK);
      history.setAlertText("OK");
      history.setAlertTimestamp(Long.valueOf(1));
      history.setClusterId(m_cluster.getClusterId());
      history.setComponentName(definition.getComponentName());
      history.setHostName("h" + (i+1));
      history.setServiceName(definition.getServiceName());
      m_dao.create(history);

      AlertCurrentEntity current = new AlertCurrentEntity();
      current.setAlertHistory(history);
      current.setLatestText(history.getAlertText());
      current.setLatestTimestamp(Long.valueOf(1L));
      current.setOriginalTimestamp(Long.valueOf(1L));
      m_dao.merge(current);
    }

    // !!! need a synchronous op for testing
    AlertEventPublisher publisher = m_injector.getInstance(AlertEventPublisher.class);
    EventBusSynchronizer.synchronizeAlertEventPublisher(m_injector);

    final AtomicReference<Alert> ref = new AtomicReference<>();
    publisher.register(new TestListener() {
      @Override
      @Subscribe
      public void catchIt(AlertReceivedEvent event) {
        ref.set(event.getAlert());
      }
    });

    AlertAggregateListener listener = m_injector.getInstance(AlertAggregateListener.class);
    AlertDefinitionFactory factory = new AlertDefinitionFactory();

    // get the aggregate cache and test it a little bit
    AggregateDefinitionMapping aggregateMapping = m_injector.getInstance(AggregateDefinitionMapping.class);

    AlertDefinition aggregateDefinition = factory.coerce(aggDef);
    aggregateMapping.registerAggregate(m_cluster.getClusterId(),
        aggregateDefinition );

    // make sure the aggregate has the correct associations
    Assert.assertEquals(aggregateDefinition,
        aggregateMapping.getAggregateDefinitions(m_cluster.getClusterId()).get(0));

    Assert.assertEquals(definition.getDefinitionName(),
        aggregateMapping.getAlertsWithAggregates(m_cluster.getClusterId()).get(0));

    AggregateSource as = (AggregateSource) aggregateDefinition.getSource();
    AlertDefinition aggregatedDefinition = aggregateMapping.getAggregateDefinition(
        m_cluster.getClusterId(), as.getAlertName());

    assertNotNull(aggregatedDefinition);

    Alert alert = new Alert(
        definition.getDefinitionName(),
        null,
        definition.getServiceName(),
        definition.getComponentName(),
        "h1",
        AlertState.OK);

    AlertCurrentEntity current = m_dao.findCurrentByHostAndName(
        m_cluster.getClusterId(), "h1", definition.getDefinitionName());

    AlertStateChangeEvent event = new AlertStateChangeEvent(
        m_cluster.getClusterId(), alert, current, AlertState.OK, AlertFirmness.HARD);

    listener.onAlertStateChangeEvent(event);
    assertNotNull(ref.get());
    assertEquals(AlertState.OK, ref.get().getState());
    assertTrue(ref.get().getText().indexOf("0/4") > -1);

    // check if one is critical, still ok
    current.getAlertHistory().setAlertState(AlertState.CRITICAL);
    m_dao.merge(current.getAlertHistory());

    listener.onAlertStateChangeEvent(event);
    assertEquals("aggregate_test", ref.get().getName());
    assertEquals(AlertState.OK, ref.get().getState());
    assertTrue(ref.get().getText().indexOf("1/4") > -1);

    // two are either warning or critical, warning
    current = m_dao.findCurrentByHostAndName(m_cluster.getClusterId(), "h2",
        definition.getDefinitionName());

    current.getAlertHistory().setAlertState(AlertState.WARNING);
    m_dao.merge(current.getAlertHistory());

    listener.onAlertStateChangeEvent(event);
    assertEquals("aggregate_test", ref.get().getName());
    assertEquals(AlertState.WARNING, ref.get().getState());
    assertTrue(ref.get().getText().indexOf("2/4") > -1);

    // three make it critical
    current = m_dao.findCurrentByHostAndName(m_cluster.getClusterId(), "h3",
        definition.getDefinitionName());

    current.getAlertHistory().setAlertState(AlertState.CRITICAL);
    m_dao.merge(current.getAlertHistory());

    listener.onAlertStateChangeEvent(event);
    assertEquals("aggregate_test", ref.get().getName());
    assertEquals(AlertState.CRITICAL, ref.get().getState());
    assertTrue(ref.get().getText().indexOf("3/4") > -1);
  }
Tests that {@link AlertStateChangeEvent} cause an {@link AlertNoticeEntity}
entry.

@throws Exception
ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java