/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.systemservices.impl.logsvc;
import java.io.BufferedWriter;
import java.io.File;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.io.FileOutputStream;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.emc.storageos.systemservices.impl.logsvc.stream.LogReader;
import com.emc.storageos.systemservices.impl.logsvc.util.LogUtil;
import com.emc.vipr.model.sys.logging.LogRequest;
public class LogReaderTest {
private static final Logger logger = LoggerFactory.getLogger(LogReaderTest.class);
private static volatile File logDir;
String regularSvcLogPath = null;
String superLongSvcLogPath = null;
String multipleLineINFOLogPath = null;
/**
* Creates a temporary log dir to use within this test.
*/
@BeforeClass
public static void createLogDir() {
logDir = new File(FileUtils.getTempDirectory(), LogReaderTest.class.getSimpleName());
logDir.mkdirs();
}
/**
* Deletes the temporary log dir and all files within.
*/
@AfterClass
public static void deleteLogDir() {
if (logDir != null) {
FileUtils.deleteQuietly(logDir);
}
}
@Before
public void before() {
String svcLog1 = "2014-01-16 17:07:57,561 [LogLevelResetter] INFO LoggingMBean.java (line 322) Starting log level config reset, lastResetTime = 0";
String superLongLog = "2014-01-16 19:00:01,519 [pool-35-thread-1] INFO DefaultSingletonBeanRegistry.java (line 433) Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@25f13769: defining beans [namespaces,scanner,registeredProfiles,reference-profile,profile-prop,profileProcessor,providerVersionSupport,resultClass-softwareIdentity,softwareIdentity-prop,softwareIdentityProcessor,system,resultClass-system,system-prop,scannerProcessor,model,reference-comp,resultClass-chassis,model-prop,modelProcessor,argscreator,smiutility,cimClient,block,commandgenerator,executor,null,bool,bool-true]; root of factory hierarchy";
String multipleLineINFOLog = "2014-01-16 18:58:24,025 [pool-10-thread-1] INFO ProcessMonitor.java (line 34) \nMemory Usage Metrics \nTotal Memory: 379MB; \nAvailable Free Memory: 146MB; \nAvailable Maximum Memory : 910MB; \nUsed Memory: 233MB; \nMax used Memory : 366MB at 2014-01-01 23:03:24.025 UTC; ";
regularSvcLogPath = new File(logDir, "regular_log.log").getAbsolutePath();
superLongSvcLogPath = new File(logDir, "super_long_log.log").getAbsolutePath();
multipleLineINFOLogPath = new File(logDir, "multiple_line_INFO_log.log").getAbsolutePath();
// initialize log file
try (FileOutputStream fos = new FileOutputStream(regularSvcLogPath);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter out = new BufferedWriter(osw)) {
out.write(svcLog1);
out.flush();
} catch (Exception e) {
logger.error("Exception in writing regular log file for syssvc test", e);
}
try (FileOutputStream fos = new FileOutputStream(superLongSvcLogPath);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter out = new BufferedWriter(osw)) {
out.write(superLongLog);
out.flush();
} catch (Exception e) {
logger.error("Exception in writing regular log file for syssvc test", e);
}
try (FileOutputStream fos = new FileOutputStream(multipleLineINFOLogPath);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter out = new BufferedWriter(osw)) {
out.write(multipleLineINFOLog);
out.flush();
} catch (Exception e) {
logger.error("Exception in writing regular log file for syssvc test", e);
}
}
/**
* Test if readMessage() can read regular service log from file and parse it correctly
*/
@Test
public void testReadRegularLogNoFilterSvcParser() throws Exception {
LogStatusInfo status = new LogStatusInfo();
LogRequest req = new LogRequest.Builder().build();
LogReader reader = new LogReader(regularSvcLogPath, req, status, null);
LogMessage l = reader.readNextLogMessage();
Calendar calendar = Calendar.getInstance();
calendar.set(2014, 0, 16, 17, 7, 57); // month starts from 0;
calendar.set(Calendar.MILLISECOND, 561);
Date date = calendar.getTime();
long time = date.getTime();
assertEquals("Time is wrong", l.getTime(), time);
assertTrue("Thread name is wrong", Arrays.equals(LogUtil.stringToBytes("LogLevelResetter"), l.getThreadName()));
assertEquals("Log level is wrong", new String(l.getLevel()), "INFO");
assertTrue("File name is wrong", Arrays.equals(LogUtil.stringToBytes("LoggingMBean"), l.getFileName()));
assertTrue("Line number is wrong", Arrays.equals(l.getLineNumber(), LogUtil.stringToBytes("322")));
assertTrue("Log message contact is wrong", Arrays.equals(
LogUtil.stringToBytes("Starting log level config reset, lastResetTime = 0"), l.getLogContent()));
}
/**
* Test if readMessage() can read super long service log from file and parse it correctly
*/
@Test
public void testSuperLongLogNoFilterSVCParser() throws Exception {
LogStatusInfo status = new LogStatusInfo();
LogRequest req = new LogRequest.Builder().build();
LogReader reader = new LogReader(superLongSvcLogPath, req, status, null);
LogMessage l = reader.readNextLogMessage();
Calendar calendar = Calendar.getInstance();
calendar.set(2014, 0, 16, 19, 00, 1); // month starts from 0;
calendar.set(Calendar.MILLISECOND, 519);
Date date = calendar.getTime();
long time = date.getTime();
assertEquals("Time is wrong", l.getTime(), time);
assertTrue("Thread name is wrong", Arrays.equals(LogUtil.stringToBytes("pool-35-thread-1"), l.getThreadName()));
assertEquals("Log level is wrong", new String(l.getLevel()), "INFO");
assertTrue("File name is wrong", Arrays.equals(LogUtil.stringToBytes("DefaultSingletonBeanRegistry"), l.getFileName()));
assertTrue("Line number is wrong", Arrays.equals(l.getLineNumber(), LogUtil.stringToBytes("433")));
assertTrue(
"Log message contact is wrong",
Arrays.equals(
LogUtil.stringToBytes("Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@25f13769: defining beans [namespaces,scanner,registeredProfiles,reference-profile,profile-prop,profileProcessor,providerVersionSupport,resultClass-softwareIdentity,softwareIdentity-prop,softwareIdentityProcessor,system,resultClass-system,system-prop,scannerProcessor,model,reference-comp,resultClass-chassis,model-prop,modelProcessor,argscreator,smiutility,cimClient,block,commandgenerator,executor,null,bool,bool-true]; root of factory hierarchy")
, l.getLogContent()));
}
/**
* Test if readMessage() can read multiple lines INFO service log from file and parse it correctly
* Test log whose first line's message field is null.
*/
@Test
public void testMultipleLinesInfoNoFilterSVCParser() throws Exception {
LogStatusInfo status = new LogStatusInfo();
LogRequest req = new LogRequest.Builder().build();
LogReader reader = new LogReader(multipleLineINFOLogPath, req, status, null);
LogMessage l = reader.readNextLogMessage();
Calendar calendar = Calendar.getInstance();
calendar.set(2014, 0, 16, 18, 58, 24); // month starts from 0;
calendar.set(Calendar.MILLISECOND, 25);
Date date = calendar.getTime();
long time = date.getTime();
assertEquals("Time is wrong", l.getTime(), time);
assertTrue("Thread name is wrong", Arrays.equals(LogUtil.stringToBytes("pool-10-thread-1"), l.getThreadName()));
assertEquals("Log level is wrong", new String(l.getLevel()), "INFO");
assertTrue("File name is wrong", Arrays.equals(LogUtil.stringToBytes("ProcessMonitor"), l.getFileName()));
assertTrue("Line number is wrong", Arrays.equals(l.getLineNumber(), LogUtil.stringToBytes("34")));
assertTrue("Log message content is wrong", Arrays.equals(LogUtil.stringToBytes("" + '\n' + "Memory Usage Metrics "
+ '\n' + "Total Memory: 379MB; " + '\n' + "Available Free Memory: 146MB; " + '\n'
+ "Available Maximum Memory : 910MB; " + '\n' + "Used Memory: 233MB; " + '\n'
+ "Max used Memory : 366MB at 2014-01-01 23:03:24.025 UTC; "), l.getLogContent()));
}
@After
public void after() {
File regularLogFile = new File(regularSvcLogPath);
File superLongLogFile = new File(superLongSvcLogPath);
File multiLineLogFile = new File(multipleLineINFOLogPath);
if (regularLogFile.exists()) {
regularLogFile.delete();
}
if (superLongLogFile.exists()) {
superLongLogFile.delete();
}
if (multiLineLogFile.exists()) {
multiLineLogFile.delete();
}
}
}