/**
* Copyright 2016, Xiaomi.
* All rights reserved.
* Author: xiajun@xiaomi.com
*/
package com.xiaomi.infra.galaxy.lcs.log.core.file;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.xiaomi.infra.galaxy.lcs.log.core.ILogger;
import com.xiaomi.infra.galaxy.lcs.log.core.dummy.DummyLogger;
import com.xiaomi.infra.galaxy.talos.client.serialization.MessageSerialization;
import com.xiaomi.infra.galaxy.talos.client.serialization.MessageSerializationFactory;
import com.xiaomi.infra.galaxy.talos.thrift.Message;
import com.xiaomi.infra.galaxy.talos.thrift.MessageType;
import static org.junit.Assert.assertEquals;
public class LCSFileReaderWriterTest {
private static File path;
private static String topicName;
private static String rootFilePath;
private static long maxFileNumber;
private static long rotateFileBytes;
private static long rotateFileIntervalMillis;
private static Message message;
private static List<Message> messageList;
private static int messageNumber;
private static String topicFilePath;
private static String tempTopicFilePath;
private LCSFileReader lcsFileReader;
private LCSFileWriter lcsFileWriter;
@BeforeClass
public static void setUpTestCase() throws Exception {
topicName = "LCSFileReaderWriterTestTopic";
path = new File("./target/rootFilePath/");
rootFilePath = path.getAbsolutePath();
System.out.print("rootFilePath: " + rootFilePath + "\n");
maxFileNumber = 1000;
rotateFileBytes = 10000;
rotateFileIntervalMillis = 100;
topicFilePath = FileUtils.formatTopicFilePath(rootFilePath, topicName);
tempTopicFilePath = FileUtils.formatTempTopicFilePath(topicFilePath);
message = new Message();
message.setCreateTimestamp(System.currentTimeMillis());
message.setMessageType(MessageType.BINARY);
message.setSequenceNumber("sequenceNumber");
message.setMessage("message".getBytes());
messageList = new ArrayList<Message>(1);
messageList.add(message);
messageNumber = 100000;
}
@AfterClass
public static void tearDownTestCase() throws Exception {
}
@Before
public void setUp() throws Exception {
if (!path.exists() && !path.mkdirs()) {
throw new IOException("Mkdir path: " + path.getPath() + " failed");
}
// delete topic file
String topicFilePath = FileUtils.formatTopicFilePath(rootFilePath, topicName);
TreeMap<String, File> fileTreeMap = FileUtils.listFile(topicFilePath, topicName);
for (File file : fileTreeMap.values()) {
FileUtils.deleteFile(file.getPath());
}
// delete topic temp file
fileTreeMap = FileUtils.listFile(tempTopicFilePath, topicName);
for (File file : fileTreeMap.values()) {
FileUtils.deleteFile(file.getPath());
}
}
@After
public void tearDown() throws Exception {
// delete topic file
String topicFilePath = FileUtils.formatTopicFilePath(rootFilePath, topicName);
TreeMap<String, File> fileTreeMap = FileUtils.listFile(topicFilePath, topicName);
for (File file : fileTreeMap.values()) {
FileUtils.deleteFile(file.getPath());
}
// delete topic temp file
String tempTopicFilePath = FileUtils.formatTempTopicFilePath(topicFilePath);
fileTreeMap = FileUtils.listFile(tempTopicFilePath, topicName);
for (File file : fileTreeMap.values()) {
FileUtils.deleteFile(file.getPath());
}
}
@Test
public void testWriteAndReadMessage() throws Exception {
lcsFileWriter = new LCSFileWriter(new DummyLogger(), topicName, rootFilePath,
maxFileNumber, rotateFileBytes, rotateFileIntervalMillis);
lcsFileReader = new LCSFileReader(new DummyLogger(), topicName, rootFilePath);
// write message;
lcsFileWriter.init();
for (int i = 0; i < messageNumber; ++i) {
lcsFileWriter.writeMessage(messageList);
}
// wait flush last message;
try {
Thread.sleep(rotateFileIntervalMillis * 2);
} catch (InterruptedException e) {
}
lcsFileWriter.writeMessage(new ArrayList<Message>());
lcsFileWriter.close();
int readMessageNumber = 0;
lcsFileReader.initTransaction();
while (true) {
lcsFileReader.startTransaction();
List<Message> readMessageList = lcsFileReader.take();
lcsFileReader.commitTransaction();
if (readMessageList == null || readMessageList.size() == 0) {
break;
}
readMessageNumber += readMessageList.size();
System.out.print("readMessageNumber: " + readMessageNumber + "\n");
for (Message readMessage : readMessageList) {
assertEquals(readMessage, message);
}
}
lcsFileReader.closeTransaction();
assertEquals(readMessageNumber, messageNumber);
}
@Test
public void testRotateFileByFileSize() throws Exception {
lcsFileWriter = new LCSFileWriter(new DummyLogger(), topicName, rootFilePath,
maxFileNumber, MessageSerialization.getMessageSize(message,
MessageSerializationFactory.getDefaultMessageVersion()), 100000000);
lcsFileWriter.init();
lcsFileWriter.writeMessage(messageList);
lcsFileWriter.writeMessage(messageList);
lcsFileWriter.writeMessage(new ArrayList<Message>());
assertEquals(FileUtils.listFile(topicFilePath, topicName).size(), 2);
lcsFileWriter.close();
}
@Test
public void testRotateFileByTime() throws Exception {
lcsFileWriter = new LCSFileWriter(new DummyLogger(), topicName, rootFilePath,
maxFileNumber, 10000000, 100);
lcsFileWriter.init();
lcsFileWriter.writeMessage(messageList);
try {
Thread.sleep(100 + 100);
} catch (InterruptedException e) {
}
lcsFileWriter.writeMessage(messageList);
try {
Thread.sleep(100 + 100);
} catch (InterruptedException e) {
}
lcsFileWriter.writeMessage(new ArrayList<Message>());
assertEquals(FileUtils.listFile(topicFilePath, topicName).size(), 2);
lcsFileWriter.close();
}
@Test (expected = IOException.class)
public void testWriteFileWithTooManyFile() throws Exception {
lcsFileWriter = new LCSFileWriter(new DummyLogger(), topicName, rootFilePath,
1, 1, 100000000);
lcsFileWriter.init();
lcsFileWriter.writeMessage(messageList);
lcsFileWriter.writeMessage(messageList);
assertEquals(FileUtils.listFile(topicFilePath, topicName).size(), 1);
lcsFileWriter.close();
}
}