// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // 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 com.cloud.usage; import static org.junit.Assert.assertEquals; import java.io.FileNotFoundException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Arrays; import java.util.Collection; import java.util.Properties; import org.dbunit.DatabaseUnitException; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.ext.mysql.MySqlConnection; import org.dbunit.operation.DatabaseOperation; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.mockito.Mockito; import com.cloud.utils.PropertiesUtil; @RunWith(Parameterized.class) public class UsageSanityCheckerIT{ protected Connection cloudConn; protected Connection usageConn; protected MySqlConnection dbuUsageConn; protected MySqlConnection dbuCloudConn; protected Properties properties = new Properties(); protected IDataSet cloudDataSet; protected IDataSet usageDataSet; protected String cloudDbuFileName; protected String usageDbuFileName; protected String expectedErrors; protected static final String EXPECTED_ERRORS_1 = "Error: Found 2 usage records with raw_usage > 10\n" + "Error: Found 1 Vm usage records which are created after Vm is destroyed\n" + "Error: Found 2 duplicate allocated Vm entries in vm usage helper table\n" + "Error: Found 1 running Vm entries without corresponding allocated entries in vm usage helper table\n" + "Error: Found 1 volume usage records which are created after volume is removed\n" + "Error: Found 1 template/ISO usage records which are created after it is removed\n" + "Error: Found 1 snapshot usage records which are created after it is removed\n"; protected static final String EXPECTED_ERRORS_2 = "Error: Found 3 usage records with raw_usage > 10\n" + "Error: Found 1 Vm usage records which are created after Vm is destroyed\n" + "Error: Found 8 duplicate running Vm entries in vm usage helper table\n" + "Error: Found 4 duplicate allocated Vm entries in vm usage helper table\n" + "Error: Found 4 running Vm entries without corresponding allocated entries in vm usage helper table\n" + "Error: Found 2 volume usage records which are created after volume is removed\n" + "Error: Found 6 duplicate records in volume usage helper table\n" + "Error: Found 2 template/ISO usage records which are created after it is removed\n" + "Error: Found 1 snapshot usage records which are created after it is removed\n"; protected static final String EXPECTED_ERRORS_3 = ""; public UsageSanityCheckerIT(String cloudDbuFileName, String usageDbuFileName, String expectedErrors) { this.cloudDbuFileName = cloudDbuFileName; this.usageDbuFileName = usageDbuFileName; this.expectedErrors = expectedErrors; } @Parameters public static Collection<Object[]> data() { Object [][] data = new Object[][] { {"cloud1.xml", "cloud_usage1.xml", EXPECTED_ERRORS_1}, {"cloud2.xml", "cloud_usage2.xml", EXPECTED_ERRORS_2}, {"cloud3.xml", "cloud_usage3.xml", EXPECTED_ERRORS_3} }; return Arrays.asList(data); } protected Connection createConnection(String dbSchema) throws SQLException { String cloudDbUrl = "jdbc:mysql://"+properties.getProperty("db."+dbSchema+".host") + ":" + properties.getProperty("db."+dbSchema+".port") + "/" + properties.getProperty("db."+dbSchema+".name"); return DriverManager.getConnection(cloudDbUrl, properties.getProperty("db."+dbSchema+".username"), properties.getProperty("db."+dbSchema+".password")); } @Before public void setUp() throws Exception { PropertiesUtil.loadFromFile(properties, PropertiesUtil.findConfigFile("db.properties")); Class.forName("com.mysql.jdbc.Driver"); cloudConn = createConnection("cloud"); usageConn = createConnection("usage"); dbuCloudConn = new MySqlConnection(cloudConn, properties.getProperty("db.cloud.name")); dbuUsageConn = new MySqlConnection(usageConn, properties.getProperty("db.usage.name")); cloudDataSet = getCloudDataSet(); usageDataSet = getUsageDataSet(); DatabaseOperation.CLEAN_INSERT.execute(dbuCloudConn, cloudDataSet); DatabaseOperation.CLEAN_INSERT.execute(dbuUsageConn, usageDataSet); } @After public void tearDown() throws DataSetException, FileNotFoundException, DatabaseUnitException, SQLException { DatabaseOperation.DELETE_ALL.execute(dbuCloudConn, getCloudDataSet()); DatabaseOperation.DELETE_ALL.execute(dbuUsageConn, getUsageDataSet()); } @Test public void testRunSanityCheck() throws SQLException, ClassNotFoundException, FileNotFoundException, DatabaseUnitException { // Prepare UsageSanityChecker checker = Mockito.spy(new UsageSanityChecker()); Mockito.doReturn(cloudConn).when(checker).getConnection(); Mockito.doNothing().when(checker).readLastCheckId(); Mockito.doNothing().when(checker).updateNewMaxId(); checker.lastId = 2; // Execute String actualErrors = checker.runSanityCheck(); // Assert assertEquals("Expected errors not found", expectedErrors, actualErrors); } protected IDataSet getCloudDataSet() throws DataSetException, FileNotFoundException { return new FlatXmlDataSetBuilder().build(PropertiesUtil.openStreamFromURL(cloudDbuFileName)); } protected IDataSet getUsageDataSet() throws DataSetException, FileNotFoundException { return new FlatXmlDataSetBuilder().build(PropertiesUtil.openStreamFromURL(usageDbuFileName)); } }