package org.ovirt.engine.core.dao;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.ovirt.engine.core.common.AuditLogSeverity;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.businessentities.AuditLog;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.utils.MockConfigRule;
/**
* {@code AuditLogDaoTest} performs tests against the {@link AuditLogDao} type.
*/
public class AuditLogDaoTest extends BaseDaoTestCase {
@ClassRule
public static MockConfigRule mcr = new MockConfigRule();
private static final String VM_NAME = "rhel5-pool-50";
private static final String VM_TEMPLATE_NAME = "1";
private static final Guid VDS_ID = new Guid("afce7a39-8e8c-4819-ba9c-796d316592e6");
private static final String VDS_NAME = "magenta-vdsc";
private static final Guid VM_ID = new Guid("77296e00-0cad-4e5a-9299-008a7b6f4354");
private static final Guid VM_TEMPLATE_ID = new Guid("1b85420c-b84c-4f29-997e-0eb674b40b79");
private static final Guid GLUSTER_VOLUME_ID = new Guid("0c3f45f6-3fe9-4b35-a30c-be0d1a835ea8");
private static final long EXISTING_ENTRY_ID = 44291;
private static final long EXTERNAL_ENTRY_ID = 44297;
private static final int FILTERED_COUNT = 6;
private static final int AFTER_DATE_COUNT = 7;
private static final int TOTAL_COUNT = 8;
private static final int CUSTOM_BAKUP_EVENT_ID = 9022;
private AuditLogDao dao;
/** Note that {@link SimpleDateFormat} is inherently not thread-safe, and should not be static */
private final SimpleDateFormat EXPECTED_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private AuditLog newAuditLog;
private AuditLog existingAuditLog;
private AuditLog externalAuditLog;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
dao = dbFacade.getAuditLogDao();
// create some test data
newAuditLog = new AuditLog();
newAuditLog.setAuditLogId(44000);
newAuditLog.setUserId(new Guid("9bf7c640-b620-456f-a550-0348f366544b"));
newAuditLog.setUserName("userportal3");
newAuditLog.setVmId(VM_ID);
newAuditLog.setVmName(VM_NAME);
newAuditLog.setVmTemplateId(VM_TEMPLATE_ID);
newAuditLog.setVmTemplateName(VM_TEMPLATE_NAME);
newAuditLog.setVdsId(VDS_ID);
newAuditLog.setVdsName("magenta-vdsc");
newAuditLog.setLogTime(EXPECTED_DATE_FORMAT.parse("2010-12-22 14:00:00"));
newAuditLog.setLogType(AuditLogType.IRS_DISK_SPACE_LOW_ERROR);
newAuditLog.setSeverity(AuditLogSeverity.ERROR);
newAuditLog.setMessage("Critical, Low disk space. domain has 1 GB of free space");
newAuditLog.setStoragePoolId(new Guid("6d849ebf-755f-4552-ad09-9a090cda105d"));
newAuditLog.setStoragePoolName("rhel6.iscsi");
newAuditLog.setStorageDomainId(new Guid("72e3a666-89e1-4005-a7ca-f7548004a9ab"));
newAuditLog.setStorageDomainName("fDMzhE-wx3s-zo3q-Qcxd-T0li-yoYU-QvVePk");
newAuditLog.setQuotaId(FixturesTool.DEFAULT_QUOTA_GENERAL);
newAuditLog.setQuotaName("General Quota");
newAuditLog.setGlusterVolumeId(new Guid("0e0abdbc-2a0f-4df0-8b99-cc577a7a9bb5"));
newAuditLog.setGlusterVolumeName("gluster_volume_name-1");
existingAuditLog = dao.get(EXISTING_ENTRY_ID);
externalAuditLog = dao.get(EXTERNAL_ENTRY_ID);
}
/**
* Ensures that if the id is invalid then no AuditLog is returned.
*/
@Test
public void testGetWithInvalidId() {
AuditLog result = dao.get(7);
assertNull(result);
}
/**
* Ensures that, if the id is valid, then retrieving a AuditLog works as expected.
*/
@Test
public void testGet() {
AuditLog result = dao.get(44291);
assertNotNull(result);
assertEquals(existingAuditLog, result);
}
/**
* Ensures that, for External Events, then retrieving a AuditLog works as expected.
*/
@Test
public void testGetByOriginAndCustomEventId() {
AuditLog result = dao.getByOriginAndCustomEventId("EMC", 1);
assertNotNull(result);
assertEquals(externalAuditLog, result);
}
/**
* Ensures that finding all AuditLog works as expected.
*/
@Test
public void testGetAll() {
List<AuditLog> result = dao.getAll(null, false);
assertEquals(TOTAL_COUNT, result.size());
}
@Test
public void testGetAllFiltered() {
List<AuditLog> result = dao.getAll(PRIVILEGED_USER_ID, true);
assertEquals(FILTERED_COUNT, result.size());
}
/**
* Test date filtering
*/
@Test
public void testGetAllAfterDate()
throws Exception {
Date cutoff = EXPECTED_DATE_FORMAT.parse("2010-12-20 13:00:00");
List<AuditLog> result = dao.getAllAfterDate(cutoff);
assertNotNull(result);
assertEquals(AFTER_DATE_COUNT, result.size());
cutoff = EXPECTED_DATE_FORMAT.parse("2010-12-20 14:00:00");
result = dao.getAllAfterDate(cutoff);
assertNotNull(result);
assertEquals(0, result.size());
}
/** Tests {@link AuditLogDao#getAllByVMId(Guid)} with a name of a VM that exists */
@Test
public void testGetAllByVMId() {
assertGetByNameValidResults(dao.getAllByVMId(VM_ID));
}
/** Tests {@link AuditLogDao#getAllByVMId(Guid)} with an ID of a VM that doesn't exist */
@Test
public void testGetAllByVMIdInvalidId() {
assertGetByNameInvalidResults(dao.getAllByVMId(Guid.newGuid()));
}
/** Tests {@link AuditLogDao#getAllByVMId(Guid, Guid, boolean)} with a user that has permissions on that VM */
@Test
public void testGetAllByVMIdPrivilegedUser() {
assertGetByNameValidResults(dao.getAllByVMId(VM_ID, PRIVILEGED_USER_ID, true));
}
/** Tests {@link AuditLogDao#getAllByVMId(Guid, Guid, boolean)} with a user that doesn't have permissions on that VM, but with the filtering mechanism disabled */
@Test
public void testGetAllByVMNameUnprivilegedUserNoFiltering() {
assertGetByNameValidResults(dao.getAllByVMId(VM_ID, UNPRIVILEGED_USER_ID, false));
}
/** Tests {@link AuditLogDao#getAllByVMId(Guid, Guid, boolean)} with a user that doesn't have permissions on that VM */
@Test
public void testGetAllByVMNameUnprivilegedUserFiltering() {
assertGetByNameInvalidResults(dao.getAllByVMId(VM_ID, UNPRIVILEGED_USER_ID, true));
}
/** Tests {@link AuditLogDao#getAllByVMTemplateId(Guid)} with an ID of a VM Template that exists */
@Test
public void testGetAllByVMTemplateName() {
assertGetByNameValidResults(dao.getAllByVMTemplateId(VM_TEMPLATE_ID));
}
/** Tests {@link AuditLogDao#getAllByVMTemplateId(Guid)} with a an ID of a VM Template that doesn't exist */
@Test
public void testGetAllByVMTemplateIdInvalidId() {
assertGetByNameInvalidResults(dao.getAllByVMTemplateId(Guid.newGuid()));
}
/** Tests {@link AuditLogDao#getAllByVMTemplateId(Guid, Guid, boolean)} with a user that has permissions on that VM Template */
@Test
public void testGetAllByVMTemplateIdPrivilegedUser() {
assertGetByNameValidResults(dao.getAllByVMTemplateId(VM_TEMPLATE_ID, PRIVILEGED_USER_ID, true));
}
/** Tests {@link AuditLogDao#getAllByVMTemplateId(Guid, Guid, boolean)} with a user that doesn't have permissions on that VM Template, but with the filtering mechanism disabled */
@Test
public void testGetAllByVMTemplateIdUnprivilegedUserNoFiltering() {
assertGetByNameValidResults(dao.getAllByVMTemplateId(VM_TEMPLATE_ID, UNPRIVILEGED_USER_ID, false));
}
/** Tests {@link AuditLogDao#getAllByVMTemplateId(Guid, Guid, boolean)} with a user that doesn't have permissions on that VM Template */
@Test
public void testGetAllByVMTemplateIdUnprivilegedUserFiltering() {
assertGetByNameInvalidResults(dao.getAllByVMTemplateId(VM_TEMPLATE_ID, UNPRIVILEGED_USER_ID, true));
}
private static void assertGetByNameValidResults(List<AuditLog> results) {
assertGetByNameResults(results, FILTERED_COUNT);
}
private static void assertGetByNameInvalidResults(List<AuditLog> results) {
assertGetByNameResults(results, 0);
}
private static void assertGetByNameResults(List<AuditLog> results, int expectedResults) {
assertNotNull("Results object should not be null", results);
assertEquals("Wrong number of results", expectedResults, results.size());
for (AuditLog auditLog : results) {
assertEquals("Wrong name of VM in result", VM_NAME, auditLog.getVmName());
assertEquals("Wrong template name of VM in result", VM_TEMPLATE_NAME, auditLog.getVmTemplateName());
}
}
/**
* Test query
*/
@Test
public void testGetAllWithQuery() {
List<AuditLog> result = dao.getAllWithQuery("SELECT * FROM audit_log WHERE vds_name = 'magenta-vdsc'");
assertEquals(FILTERED_COUNT, result.size());
}
@Test
public void testRemoveAllBeforeDate()
throws Exception {
Date cutoff = EXPECTED_DATE_FORMAT.parse("2010-12-20 13:11:00");
dao.removeAllBeforeDate(cutoff);
List<AuditLog> result = dao.getAll(PRIVILEGED_USER_ID, true);
assertEquals(1, result.size());
}
@Test
public void testRemoveAllForVds()
throws Exception {
dao.removeAllForVds(VDS_ID, true);
List<AuditLog> result = dao.getAll(null, false);
assertEquals(7, result.size());
}
@Test
public void testRemoveAllOfTypeForVds()
throws Exception {
dao.removeAllOfTypeForVds(VDS_ID,
AuditLogType.IRS_DISK_SPACE_LOW_ERROR.getValue());
// show be 1 left that was in event_notification_hist
List<AuditLog> result = dao.getAll(PRIVILEGED_USER_ID, true);
assertEquals(3, result.size());
}
/**
* Ensures that saving a AuditLog works as expected.
*/
@Test
public void testSave() {
dao.save(newAuditLog);
AuditLog result = dao.get(newAuditLog.getAuditLogId());
assertNotNull(result);
assertEquals(newAuditLog, result);
}
@Test
public void testSaveExternalEvent() {
AuditLog newExternalEvent = new AuditLog();
newExternalEvent.setLogType(AuditLogType.EXTERNAL_EVENT_NORMAL);
newExternalEvent.setExternal(true);
newExternalEvent.setOrigin("XYZ");
newExternalEvent.setCustomEventId(123123123);
newExternalEvent.setCustomData("Some text here");
newExternalEvent.setMessage("And here");
newExternalEvent.setEventFloodInSec(100);
dao.save(newExternalEvent);
AuditLog result = dao.get(newExternalEvent.getAuditLogId());
assertNotNull(result);
assertTrue(result.getAuditLogId() > 0);
assertEquals(newExternalEvent.getOrigin(), result.getOrigin());
assertEquals(newExternalEvent.getCustomEventId(), result.getCustomEventId());
assertEquals(newExternalEvent.getCustomData(), result.getCustomData());
assertEquals(newExternalEvent.getMessage(), result.getMessage());
assertEquals(newExternalEvent.getEventFloodInSec(), result.getEventFloodInSec());
}
/**
* Ensures that removing an AuditLog works as expected.
*/
@Test
public void testRemove() {
dao.remove(existingAuditLog.getAuditLogId());
AuditLog result = dao.get(existingAuditLog.getAuditLogId());
assertTrue(result.isDeleted());
}
private long getAlertCount(AuditLog entry, List<AuditLog> results) {
return results.stream()
.filter(a -> a.getSeverity() == entry.getSeverity() &&
entry.getVdsId().equals(a.getVdsId()) &&
a.getLogType() == entry.getLogType())
.count();
}
/**
* Checks if multiple alerts of the same type for the same host are ignored if repeatable is set to {@code false}
*/
@Test
public void testMultipleAlertsWithSameTypeAndHostAreIgnored() {
AuditLog entry = new AuditLog(AuditLogType.VDS_ALERT_FENCE_DISABLED_BY_CLUSTER_POLICY, AuditLogSeverity.ALERT);
entry.setVdsId(VDS_ID);
entry.setVdsName(VDS_NAME);
entry.setMessage("Testing alert");
// test if no alert of the same type for the same host exists
assertEquals(0L, getAlertCount(entry, dao.getAll(null, false)));
dao.save(entry);
AuditLog savedAlert = dao.get(entry.getAuditLogId());
assertNotNull(savedAlert);
// test if 1st alert was stored in db
assertEquals(1L, getAlertCount(entry, dao.getAll(null, false)));
// try to store 2nd alert in db
entry.setLogTime(new Date());
dao.save(entry);
savedAlert = dao.get(entry.getAuditLogId());
assertNotNull(savedAlert);
// test if 2nd alert was ignored
assertEquals(1L, getAlertCount(entry, dao.getAll(null, false)));
}
/**
* Checks if multiple alerts of the same type for the same host are saved if repeatable is set to {@code true}
*/
@Test
public void testMultipleAlertsWithSameTypeAndHostAreSavedIfRepeatableTrue() {
AuditLog entry = new AuditLog(AuditLogType.VDS_ALERT_FENCE_DISABLED_BY_CLUSTER_POLICY, AuditLogSeverity.ALERT);
entry.setVdsId(VDS_ID);
entry.setVdsName(VDS_NAME);
entry.setMessage("Testing alert");
entry.setRepeatable(true);
// test if no alert of the same type for the same host exists
assertEquals(0L, getAlertCount(entry, dao.getAll(null, false)));
dao.save(entry);
AuditLog savedAlert = dao.get(entry.getAuditLogId());
assertNotNull(savedAlert);
// test if 1st alert was stored in db
assertEquals(1L, getAlertCount(entry, dao.getAll(null, false)));
// try to save 2nd alert
entry.setLogTime(new Date());
dao.save(entry);
savedAlert = dao.get(entry.getAuditLogId());
assertNotNull(savedAlert);
// test if 2nd alert was also stored in db
assertEquals(2L, getAlertCount(entry, dao.getAll(null, false)));
}
@Test
public void testDeleteBackupRelatedAlerts() {
AuditLog entry = dao.getByOriginAndCustomEventId(AuditLog.OVIRT_ORIGIN, CUSTOM_BAKUP_EVENT_ID);
assertNotNull(entry);
assertFalse(entry.isDeleted());
dao.deleteBackupRelatedAlerts();
entry = dao.getByOriginAndCustomEventId(AuditLog.OVIRT_ORIGIN, CUSTOM_BAKUP_EVENT_ID);
assertNotNull(entry);
assertTrue(entry.isDeleted());
}
@Test
public void testRemoveAllOfTypeForVolume() {
List<AuditLog> entries =
dao.getByVolumeIdAndType(GLUSTER_VOLUME_ID,
AuditLogType.GLUSTER_VOLUME_SNAPSHOT_SOFT_LIMIT_REACHED.getValue());
assertEquals(1, entries.size());
dao.removeAllOfTypeForVolume(GLUSTER_VOLUME_ID,
AuditLogType.GLUSTER_VOLUME_SNAPSHOT_SOFT_LIMIT_REACHED.getValue());
List<AuditLog> entries1 =
dao.getByVolumeIdAndType(GLUSTER_VOLUME_ID,
AuditLogType.GLUSTER_VOLUME_SNAPSHOT_SOFT_LIMIT_REACHED.getValue());
assertEquals(1, entries1.size());
assertEquals(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_SOFT_LIMIT_REACHED, entries1.get(0).getLogType());
}
@Test
public void testGetByVolumeIdAndType() {
List<AuditLog> entries =
dao.getByVolumeIdAndType(GLUSTER_VOLUME_ID,
AuditLogType.GLUSTER_VOLUME_SNAPSHOT_SOFT_LIMIT_REACHED.getValue());
assertEquals(1, entries.size());
}
}