/* * Copyright (c) 2014 Hewlett-Packard Development Company, L.P. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * See the License for the specific language governing permissions and * limitations under the License. */ package monasca.thresh.infrastructure.persistence; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import com.google.common.base.Joiner; import com.google.common.io.Resources; import monasca.common.model.alarm.AlarmExpression; import monasca.common.model.alarm.AlarmSubExpression; import monasca.thresh.domain.model.AlarmDefinition; import monasca.thresh.domain.model.SubExpression; import monasca.thresh.domain.service.AlarmDefinitionDAO; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Map; @Test public class AlarmDefinitionDAOImplTest { private static final String TENANT_ID = "bob"; private static final String ALARM_DEFINITION_ID = "123"; private static String ALARM_NAME = "90% CPU"; private static String ALARM_DESCR = "Description for " + ALARM_NAME; private static final Joiner COMMA_JOINER = Joiner.on(','); private DBI db; private Handle handle; private AlarmDefinitionDAO dao; @BeforeClass protected void setupClass() throws Exception { db = new DBI("jdbc:h2:mem:test;MODE=MySQL"); handle = db.open(); handle .execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset())); dao = new AlarmDefinitionDAOImpl(db); } @AfterClass protected void afterClass() { handle.close(); } @BeforeMethod protected void beforeMethod() { handle.execute("truncate table alarm_definition"); handle.execute("truncate table sub_alarm_definition"); handle.execute("truncate table sub_alarm_definition_dimension"); } public void testGetById() { assertNull(dao.findById(ALARM_DEFINITION_ID)); final AlarmExpression expression = new AlarmExpression("max(cpu{service=nova}) > 90"); final AlarmDefinition alarmDefinition = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression, "LOW", false, Arrays.asList("fred")); insertAndCheck(alarmDefinition); final AlarmExpression expression2 = new AlarmExpression("max(cpu{service=swift}) > 90"); final AlarmDefinition alarmDefinition2 = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression2, "LOW", false, Arrays.asList("hostname", "dev")); insertAndCheck(alarmDefinition2); // Make sure it works when there are no dimensions final AlarmExpression expression3 = new AlarmExpression("max(cpu) > 90"); final AlarmDefinition alarmDefinition3 = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression3, "LOW", false, Arrays.asList("hostname", "dev")); insertAndCheck(alarmDefinition3); final AlarmExpression expression4 = new AlarmExpression("max(cpu,deterministic) > 90"); final AlarmDefinition alarmDefinition4 = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression4, "LOW", false, Arrays.asList("hostname", "dev")); insertAndCheck(alarmDefinition4); } public void testListAll() { assertEquals(0, dao.listAll().size()); final AlarmExpression expression = new AlarmExpression("max(cpu{service=nova}) > 90"); final AlarmDefinition alarmDefinition = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression, "LOW", false, Arrays.asList("fred", "barney")); insertAlarmDefinition(handle, alarmDefinition); verifyListAllMatches(alarmDefinition); final AlarmExpression expression2 = new AlarmExpression("max(cpu{service=swift}) > 90"); final AlarmDefinition alarmDefinition2 = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression2, "LOW", false, Arrays.asList("fred", "barney", "wilma", "betty")); insertAlarmDefinition(handle, alarmDefinition2); verifyListAllMatches(alarmDefinition, alarmDefinition2); final AlarmExpression expression3 = new AlarmExpression( "max(cpu{service=swift}, deterministic) > 90" ); final AlarmDefinition alarmDefinition3 = new AlarmDefinition(TENANT_ID, ALARM_NAME, ALARM_DESCR, expression3, "LOW", false, Arrays.asList("fred", "barney", "wilma", "betty", "scooby", "doo")); insertAlarmDefinition(handle, alarmDefinition3); verifyListAllMatches(alarmDefinition, alarmDefinition2, alarmDefinition3); } private void insertAndCheck(final AlarmDefinition alarmDefinition) { insertAlarmDefinition(handle, alarmDefinition); assertEquals(dao.findById(alarmDefinition.getId()), alarmDefinition); } private void verifyListAllMatches(final AlarmDefinition... alarmDefinitions) { List<AlarmDefinition> found = dao.listAll(); assertEquals(alarmDefinitions.length, found.size()); for (AlarmDefinition alarmDef : alarmDefinitions) { assertTrue(found.contains(alarmDef)); } } // This method is not a test but without this TestNG tries to run it @Test(enabled=false) public static void insertAlarmDefinition(Handle handle, AlarmDefinition alarmDefinition) { try { handle.begin(); handle .insert( "insert into alarm_definition (id, tenant_id, name, description, severity, expression, match_by, actions_enabled, created_at, updated_at, deleted_at) values (?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), NULL)", alarmDefinition.getId(), alarmDefinition.getTenantId(), alarmDefinition.getName(), alarmDefinition.getDescription(), "LOW", alarmDefinition.getAlarmExpression().getExpression(), alarmDefinition.getMatchBy().isEmpty() ? null : COMMA_JOINER.join(alarmDefinition .getMatchBy()), alarmDefinition.isActionsEnabled()); for (final SubExpression subExpression : alarmDefinition.getSubExpressions()) { final AlarmSubExpression alarmSubExpr = subExpression.getAlarmSubExpression(); handle .insert( "insert into sub_alarm_definition (id, alarm_definition_id, function, metric_name, operator, " + "threshold, period, periods, is_deterministic, created_at, updated_at) " + "values (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())", subExpression.getId(), alarmDefinition.getId(), alarmSubExpr.getFunction().name(), alarmSubExpr.getMetricDefinition().name, alarmSubExpr.getOperator().name(), alarmSubExpr.getThreshold(), alarmSubExpr.getPeriod(), alarmSubExpr.getPeriods(), alarmSubExpr.isDeterministic() ); for (final Map.Entry<String, String> entry : alarmSubExpr.getMetricDefinition().dimensions.entrySet()) { handle .insert( "insert into sub_alarm_definition_dimension (sub_alarm_definition_id, dimension_name, value) values (?, ?, ?)", subExpression.getId(), entry.getKey(), entry.getValue()); } } handle.commit(); } catch (RuntimeException e) { handle.rollback(); throw e; } } }