Skip to content

Commit

Permalink
Add performance test
Browse files Browse the repository at this point in the history
  • Loading branch information
evrignaud committed Oct 22, 2015
1 parent 235790e commit ec6eaff
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 6 deletions.
182 changes: 182 additions & 0 deletions src/test/java/org/fim/internal/hash/FileHasherPerformanceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* This file is part of Fim - File Integrity Manager
*
* Copyright (C) 2015 Etienne Vrignaud
*
* Fim 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.
*
* Fim 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 Fim. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fim.internal.hash;

import static java.lang.Math.min;
import static java.nio.file.StandardOpenOption.CREATE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.fim.model.HashMode.hashSmallBlock;
import static org.fim.tooling.TestConstants._1_KB;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.fim.model.Constants;
import org.fim.model.FileHash;
import org.fim.tooling.BuildableContext;
import org.fim.tooling.StateAssert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

@Ignore // Don't run it during unit tests
public class FileHasherPerformanceTest extends StateAssert
{
public static final int TOTAL_FILE_CONT = 2000;
private static byte contentBytes[];
private static Path rootDir = Paths.get("target/" + FileHasherPerformanceTest.class.getSimpleName());

static
{
StringBuilder builder = new StringBuilder();
for (char c = 33; c < 126; c++)
{
builder.append(c);
}
contentBytes = builder.toString().getBytes();
}

private long globalSequenceCount = 0;
private HashProgress hashProgress;
private BuildableContext context;
private FileHasher cut;

@BeforeClass
public static void setupOnce() throws NoSuchAlgorithmException, IOException
{
if (!Files.exists(rootDir))
{
Files.createDirectories(rootDir);
}
}

@Before
public void setup() throws NoSuchAlgorithmException, IOException
{
hashProgress = mock(HashProgress.class);
context = defaultContext();
context.setHashMode(hashSmallBlock);
context.setRepositoryRootDir(rootDir);

when(hashProgress.getContext()).thenReturn(context);

cut = new FileHasher(hashProgress, null, rootDir.toString());
}

@Test
public void createFiles() throws IOException
{
long start = System.currentTimeMillis();

for (int fileCount = 0; fileCount < TOTAL_FILE_CONT; fileCount++)
{
createFileWithSize(fileCount, (5 * Constants._1_MB) + 291);
}

long duration = System.currentTimeMillis() - start;
System.out.println("Took: " + DurationFormatUtils.formatDuration(duration, "HH:mm:ss"));
}

@Test
public void hashFiles() throws IOException
{
long start = System.currentTimeMillis();

List<FileHash> allHash = new ArrayList();
for (int fileCount = 0; fileCount < TOTAL_FILE_CONT; fileCount++)
{
Path fileToHash = context.getRepositoryRootDir().resolve("file_" + fileCount);
allHash.add(cut.hashFile(fileToHash, Files.size(fileToHash)));
}

long duration = System.currentTimeMillis() - start;
System.out.println("Took: " + DurationFormatUtils.formatDuration(duration, "HH:mm:ss"));
System.out.println("Total bytes hash=" + FileUtils.byteCountToDisplaySize(cut.getTotalBytesHashed()));
}

private Path createFileWithSize(int fileCount, int fileSize) throws IOException
{
Path newFile = context.getRepositoryRootDir().resolve("file_" + fileCount);
if (Files.exists(newFile))
{
Files.delete(newFile);
}

if (fileSize == 0)
{
Files.createFile(newFile);
return newFile;
}

try (ByteArrayOutputStream out = new ByteArrayOutputStream(fileSize))
{
int contentSize = _1_KB / 4;
int remaining = fileSize;
for (; remaining > 0; globalSequenceCount++)
{
int size = min(contentSize, remaining);
byte[] content = generateContent(globalSequenceCount, size);
remaining -= size;
out.write(content);
}

byte[] fileContent = out.toByteArray();
assertThat(fileContent.length).isEqualTo(fileSize);
Files.write(newFile, fileContent, CREATE);
}

return newFile;
}

private byte[] generateContent(long sequenceCount, int contentSize)
{
byte[] content = new byte[contentSize];
for (int index = 0; index < contentSize; index += 2)
{
content[index] = getContentByte(sequenceCount, false);
if (index + 1 < contentSize)
{
content[index + 1] = getContentByte(sequenceCount, true);
}
}
return content;
}

private byte getContentByte(long sequenceCount, boolean fromTheEnd)
{
int index = (int) (sequenceCount % contentBytes.length);
if (fromTheEnd)
{
index = contentBytes.length - 1 - index;
}
return contentBytes[index];
}

}
12 changes: 6 additions & 6 deletions src/test/java/org/fim/internal/hash/FileHasherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public class FileHasherTest extends StateAssert
contentBytes = builder.toString().getBytes();
}

private long globalSequenceCount = 0;
private HashProgress hashProgress;
private HashMode hashMode;
private BuildableContext context;
Expand Down Expand Up @@ -361,10 +362,10 @@ private Path createFileWithSize(int fileSize) throws IOException
{
int contentSize = _1_KB / 4;
int remaining = fileSize;
for (int sequenceCount = 0; remaining > 0; sequenceCount++)
for (; remaining > 0; globalSequenceCount++)
{
int size = min(contentSize, remaining);
byte[] content = generateContent(sequenceCount, size);
byte[] content = generateContent(globalSequenceCount, size);
remaining -= size;
out.write(content);
}
Expand All @@ -377,7 +378,7 @@ private Path createFileWithSize(int fileSize) throws IOException
return newFile;
}

private byte[] generateContent(int sequenceCount, int contentSize)
private byte[] generateContent(long sequenceCount, int contentSize)
{
byte[] content = new byte[contentSize];
for (int index = 0; index < contentSize; index += 2)
Expand All @@ -391,17 +392,16 @@ private byte[] generateContent(int sequenceCount, int contentSize)
return content;
}

private byte getContentByte(int sequenceCount, boolean fromTheEnd)
private byte getContentByte(long sequenceCount, boolean fromTheEnd)
{
int index = sequenceCount % contentBytes.length;
int index = (int) (sequenceCount % contentBytes.length);
if (fromTheEnd)
{
index = contentBytes.length - 1 - index;
}
return contentBytes[index];
}

// smallRange, mediumRange
private FileHash computeExpectedHash(Path fileToHash, Range[] smallRanges, Range[] mediumRanges) throws IOException
{
byte[] fullContent = Files.readAllBytes(fileToHash);
Expand Down

0 comments on commit ec6eaff

Please sign in to comment.