/**
* TestMeasurementGarbageCollector.java This file is part of WattDepot.
*
* Copyright (C) 2014 Cam Moore
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.wattdepot.server.measurement.pruning;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.List;
import javax.measure.unit.Unit;
import javax.xml.datatype.XMLGregorianCalendar;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.wattdepot.common.domainmodel.Depository;
import org.wattdepot.common.domainmodel.InstanceFactory;
import org.wattdepot.common.domainmodel.Measurement;
import org.wattdepot.common.domainmodel.MeasurementPruningDefinition;
import org.wattdepot.common.domainmodel.MeasurementType;
import org.wattdepot.common.domainmodel.Organization;
import org.wattdepot.common.domainmodel.Sensor;
import org.wattdepot.common.domainmodel.SensorModel;
import org.wattdepot.common.domainmodel.UserInfo;
import org.wattdepot.common.domainmodel.UserPassword;
import org.wattdepot.common.exception.BadSlugException;
import org.wattdepot.common.exception.IdNotFoundException;
import org.wattdepot.common.exception.MeasurementTypeException;
import org.wattdepot.common.exception.MisMatchedOwnerException;
import org.wattdepot.common.exception.UniqueIdException;
import org.wattdepot.common.util.DateConvert;
import org.wattdepot.common.util.UnitsHelper;
import org.wattdepot.common.util.tstamp.Tstamp;
import org.wattdepot.server.ServerProperties;
import org.wattdepot.server.WattDepotPersistence;
import org.wattdepot.server.depository.impl.hibernate.WattDepotPersistenceImpl;
/**
* TestMeasurementGarbageCollector test cases for the
* MeasurementGarbageCollector class.
*
* @author Cam Moore
*
*/
public class TestMeasurementGarbageCollector {
private static WattDepotPersistenceImpl impl;
private static UserInfo testUser;
private static UserPassword testPassword;
private static Organization testOrg;
private static ServerProperties properties;
private static Depository depository;
private static Sensor sensor;
private static MeasurementPruningDefinition gcd;
private XMLGregorianCalendar now;
private XMLGregorianCalendar start;
private XMLGregorianCalendar end;
private int totalMeasurements;
/**
* Sets up the WattDepotPersistenceImpl using test properties.
*/
@BeforeClass
public static void setupImpl() throws Exception {
properties = new ServerProperties();
properties.setTestProperties();
impl = new WattDepotPersistenceImpl(properties);
testUser = InstanceFactory.getUserInfo();
testPassword = InstanceFactory.getUserPassword();
testOrg = InstanceFactory.getOrganization();
// shouldn't have to do this.
testUser.setOrganizationId(testOrg.getId());
// prime the MeasurementTypes
UnitsHelper.quantities.containsKey("W");
}
/**
* @throws java.lang.Exception if there is a problem.
*/
@Before
public void setUp() throws Exception {
// 1. define the organization w/o any users.
try {
impl.getOrganization(testOrg.getId(), true);
}
catch (IdNotFoundException e) {
try {
impl.defineOrganization(testOrg.getId(), testOrg.getName(), new HashSet<String>());
}
catch (BadSlugException e1) {
e1.printStackTrace();
}
catch (IdNotFoundException e1) {
e1.printStackTrace();
}
}
// 2. define the user
try {
impl.getUser(testUser.getUid(), testUser.getOrganizationId(), true);
}
catch (IdNotFoundException e) {
try {
impl.defineUserInfo(testUser.getUid(), testUser.getFirstName(), testUser.getLastName(),
testUser.getEmail(), testUser.getOrganizationId(), testUser.getProperties(),
testUser.getPassword());
}
catch (IdNotFoundException e1) {
// Shouldn't happen!
e1.printStackTrace();
}
}
// 3. update the organization
try {
impl.updateOrganization(testOrg);
}
catch (IdNotFoundException e1) {
// this shouldn't happen
e1.printStackTrace();
}
addSensor();
addMeasurementType();
addDepository();
addMeasurementPruningDefinition();
}
/**
* @throws java.lang.Exception if there is a problem.
*/
@After
public void tearDown() throws Exception {
Organization testO;
try {
testO = impl.getOrganization(testOrg.getId(), true);
if (testO != null) {
impl.deleteOrganization(testO.getId());
}
}
catch (IdNotFoundException e) {
e.printStackTrace();
}
try {
impl.deleteOrganization(InstanceFactory.getUserInfo2().getOrganizationId());
}
catch (IdNotFoundException e1) { // NOPMD
// not a problem
}
UserPassword testP;
try {
testP = impl.getUserPassword(testPassword.getUid(), testPassword.getOrganizationId(), true);
if (testP != null) {
impl.deleteUserPassword(testP.getUid(), testPassword.getOrganizationId());
}
}
catch (IdNotFoundException e) { // NOPMD
// e.printStackTrace();
}
UserInfo testU;
try {
testU = impl.getUser(testUser.getUid(), testUser.getOrganizationId(), true);
if (testU != null) {
impl.deleteUser(testU.getUid(), testU.getOrganizationId());
}
}
catch (IdNotFoundException e) { // NOPMD
// e.printStackTrace();
}
}
/**
* Test method for
* {@link org.wattdepot.server.measurement.pruning.MeasurementPruner#getMeasurementsToDelete()}
* .
*
* @throws Exception if there is a problem.
*/
@Test
public void testGetMeasurementsToDelete() throws Exception {
populateMeasurements(2);
MeasurementPruner mgc = new MeasurementPruner(properties, gcd.getId(),
gcd.getOrganizationId(), false);
List<Measurement> toDel = mgc.getMeasurementsToDelete();
assertTrue(toDel.size() > 0);
assertTrue(toDel.size() < totalMeasurements);
}
/**
* @throws Exception if there is a problem.
*/
@Test
public void testMeasurementPruning() throws Exception {
populateMeasurements(2);
MeasurementPruner mgc = new MeasurementPruner(properties, gcd.getId(),
gcd.getOrganizationId(), false);
int numToDel = mgc.getMeasurementsToDelete().size();
mgc.run();
List<Measurement> toDel = mgc.getMeasurementsToDelete();
assertTrue(toDel.size() == 0);
WattDepotPersistence p = mgc.getPersistance();
List<Measurement> data = p.getMeasurements(gcd.getDepositoryId(), gcd.getOrganizationId(),
gcd.getSensorId(), false);
assertNotNull(data);
assertTrue(data.size() < totalMeasurements);
assertTrue(data.size() == totalMeasurements - numToDel);
}
/**
* @throws UniqueIdException if the Model is already defined.
*/
private void addSensorModel() throws UniqueIdException {
SensorModel model = InstanceFactory.getSensorModel();
try {
impl.getSensorModel(model.getId(), true);
}
catch (IdNotFoundException e1) {
try {
impl.defineSensorModel(model.getId(), model.getName(), model.getProtocol(),
model.getType(), model.getVersion());
}
catch (BadSlugException e) {
e.printStackTrace();
}
}
}
/**
* @throws MisMatchedOwnerException if there is a mismatch in the ownership.
* @throws UniqueIdException if the Sensor is already defined.
* @throws IdNotFoundException if the SensorLocation or SensorModel aren't
* defined.
*/
private void addSensor() throws MisMatchedOwnerException, UniqueIdException, IdNotFoundException {
addSensorModel();
TestMeasurementGarbageCollector.sensor = InstanceFactory.getSensor();
try {
impl.getSensor(sensor.getId(), sensor.getOrganizationId(), true);
}
catch (IdNotFoundException e) {
try {
impl.defineSensor(sensor.getId(), sensor.getName(), sensor.getUri(), sensor.getModelId(),
sensor.getProperties(), sensor.getOrganizationId());
}
catch (BadSlugException e1) {
e1.printStackTrace();
}
}
}
/**
* @throws UniqueIdException if the MeasurementType is already defined.
*/
private void addMeasurementType() throws UniqueIdException {
MeasurementType type = InstanceFactory.getMeasurementType();
try {
impl.getMeasurementType(type.getId(), true);
}
catch (IdNotFoundException e1) {
try {
impl.defineMeasurementType(type.getId(), type.getName(), type.getUnits());
}
catch (BadSlugException e) {
e.printStackTrace();
}
}
}
/**
* @throws UniqueIdException if there is already a Depository defined.
* @throws IdNotFoundException if there are problems with the ids.
*/
private void addDepository() throws UniqueIdException, IdNotFoundException {
TestMeasurementGarbageCollector.depository = InstanceFactory.getDepository();
try {
impl.getDepository(depository.getId(), depository.getOrganizationId(), true);
}
catch (IdNotFoundException e) {
try {
impl.defineDepository(depository.getId(), depository.getName(),
depository.getMeasurementType(), depository.getOrganizationId());
}
catch (BadSlugException e1) {
e1.printStackTrace();
}
}
}
/**
* Adds the predefined MeasurementPruningDefinition.
*/
private void addMeasurementPruningDefinition() {
TestMeasurementGarbageCollector.gcd = InstanceFactory.getMeasurementPruningDefinition();
try {
impl.getMeasurementPruningDefinition(gcd.getId(), gcd.getOrganizationId(), true);
}
catch (IdNotFoundException e) {
try {
impl.defineMeasurementPruningDefinition(gcd.getId(), gcd.getName(), gcd.getDepositoryId(),
gcd.getSensorId(), gcd.getOrganizationId(), gcd.getIgnoreWindowDays(),
gcd.getCollectWindowDays(), gcd.getMinGapSeconds());
}
catch (UniqueIdException e1) {
e1.printStackTrace();
}
catch (BadSlugException e1) {
e1.printStackTrace();
}
catch (IdNotFoundException e1) {
e1.printStackTrace();
}
}
}
/**
* @param time The time of the measurement.
* @return A fake measurement at the given time.
*/
private Measurement makeMeasurement(XMLGregorianCalendar time) {
return new Measurement(InstanceFactory.getSensor().getId(), DateConvert.convertXMLCal(time),
123.0, Unit.valueOf(InstanceFactory.getMeasurementType().getUnits()));
}
/**
* @param minBetween The number of minutes between measurements.
* @throws MeasurementTypeException This shouldn't happen.
* @throws IdNotFoundException If there is a problem with the ids. This
* shouldn't happen.
*/
private void populateMeasurements(int minBetween) throws MeasurementTypeException,
IdNotFoundException {
// Need to add high frequency Measurements to the database.
now = Tstamp.makeTimestamp();
start = Tstamp.incrementDays(now, -1 * gcd.getIgnoreWindowDays());
end = Tstamp.incrementDays(start, -1 * gcd.getCollectWindowDays());
List<XMLGregorianCalendar> measTimes = Tstamp.getTimestampList(end, now, minBetween);
totalMeasurements = measTimes.size();
for (XMLGregorianCalendar cal : measTimes) {
impl.putMeasurement(depository.getId(), depository.getOrganizationId(), makeMeasurement(cal));
}
}
}