/*
* Copyright 2016 The Simple File Server Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sfs.util;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.streams.ReadStream;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.sfs.SfsVertx;
import org.sfs.SfsVertxImpl;
import org.sfs.TestSubscriber;
import org.sfs.io.BufferReadStream;
import org.sfs.io.BufferWriteEndableWriteStream;
import org.sfs.io.FileBackedBuffer;
import org.sfs.thread.NamedCapacityFixedThreadPool;
import java.io.IOException;
import java.nio.file.Path;
import java.util.concurrent.ExecutorService;
import static io.vertx.core.buffer.Buffer.buffer;
import static java.lang.String.valueOf;
import static java.lang.System.currentTimeMillis;
import static java.nio.file.Files.createTempDirectory;
import static org.sfs.io.AsyncIO.pump;
import static org.sfs.rx.Defer.aVoid;
import static org.sfs.util.PrngRandom.getCurrentInstance;
import static org.sfs.util.VertxAssert.assertArrayEquals;
import static org.sfs.util.VertxAssert.assertEquals;
@RunWith(VertxUnitRunner.class)
public class FileBackedBufferTest {
@Rule
public final RunTestOnContext rule = new RunTestOnContext();
private ExecutorService backgroundPool;
private ExecutorService ioPool;
@Before
public void start() {
ioPool = NamedCapacityFixedThreadPool.newInstance(200, "sfs-io-pool");
backgroundPool = NamedCapacityFixedThreadPool.newInstance(200, "sfs-blocking-action-pool");
}
@After
public void stop(TestContext context) {
if (ioPool != null) {
ioPool.shutdown();
}
if (backgroundPool != null) {
backgroundPool.shutdown();
}
}
@Test
public void testSmallNoEncrypt(TestContext context) throws IOException {
testSmall(context, true);
}
@Test
public void testSmallEncrypt(TestContext context) throws IOException {
testSmall(context, false);
}
public void testSmall(TestContext context, boolean encrypt) throws IOException {
SfsVertx sfsVertx = new SfsVertxImpl(rule.vertx(), backgroundPool, ioPool);
Path tmpDir = createTempDirectory(valueOf(currentTimeMillis()));
Buffer testBuffer = buffer("test");
Async async = context.async();
aVoid()
.flatMap(aVoid -> {
FileBackedBuffer fileBackedBuffer = new FileBackedBuffer(sfsVertx, 2, encrypt, tmpDir);
ReadStream<Buffer> readStream = new BufferReadStream(testBuffer);
return pump(readStream, fileBackedBuffer)
.flatMap(aVoid1 -> {
ReadStream<Buffer> fileBackedReadStream = fileBackedBuffer.readStream();
BufferWriteEndableWriteStream bufferedWriteStreamConsumer = new BufferWriteEndableWriteStream();
return pump(fileBackedReadStream, bufferedWriteStreamConsumer)
.doOnNext(aVoid2 -> {
Buffer actualBuffer = bufferedWriteStreamConsumer.toBuffer();
assertArrayEquals(context, testBuffer.getBytes(), actualBuffer.getBytes());
assertEquals(context, true, fileBackedBuffer.isFileOpen());
});
})
.flatMap(aVoid1 -> fileBackedBuffer.close());
})
.subscribe(new TestSubscriber(context, async));
}
@Test
public void testLargeNoEncrypt(TestContext context) throws IOException {
testLarge(context, false);
}
@Test
public void testLargeEncrypt(TestContext context) throws IOException {
testLarge(context, true);
}
public void testLarge(TestContext context, boolean encrypt) throws IOException {
SfsVertx sfsVertx = new SfsVertxImpl(rule.vertx(), backgroundPool, ioPool);
Path tmpDir = createTempDirectory(valueOf(currentTimeMillis()));
byte[] data = new byte[1024 * 1024 * 10];
getCurrentInstance().nextBytesBlocking(data);
Buffer testBuffer = buffer(data);
Async async = context.async();
aVoid()
.flatMap(aVoid -> {
FileBackedBuffer fileBackedBuffer = new FileBackedBuffer(sfsVertx, 1024, encrypt, tmpDir);
ReadStream<Buffer> readStream = new BufferReadStream(testBuffer);
return pump(readStream, fileBackedBuffer)
.flatMap(aVoid1 -> {
ReadStream<Buffer> fileBackedReadStream = fileBackedBuffer.readStream();
BufferWriteEndableWriteStream bufferedWriteStreamConsumer = new BufferWriteEndableWriteStream();
return pump(fileBackedReadStream, bufferedWriteStreamConsumer)
.doOnNext(aVoid2 -> {
Buffer actualBuffer = bufferedWriteStreamConsumer.toBuffer();
assertArrayEquals(context, testBuffer.getBytes(), actualBuffer.getBytes());
assertEquals(context, true, fileBackedBuffer.isFileOpen());
});
})
.flatMap(aVoid1 -> fileBackedBuffer.close());
})
.subscribe(new TestSubscriber(context, async));
}
@Test
public void testOnlyBufferNoEncrypt(TestContext context) throws IOException {
testOnlyBuffer(context, false);
}
@Test
public void testOnlyBufferEncrypt(TestContext context) throws IOException {
testOnlyBuffer(context, true);
}
public void testOnlyBuffer(TestContext context, boolean encrypt) throws IOException {
SfsVertx sfsVertx = new SfsVertxImpl(rule.vertx(), backgroundPool, ioPool);
Path tmpDir = createTempDirectory(valueOf(currentTimeMillis()));
Buffer testBuffer = buffer("test");
Async async = context.async();
aVoid()
.flatMap(aVoid -> {
FileBackedBuffer fileBackedBuffer = new FileBackedBuffer(sfsVertx, 1024, encrypt, tmpDir);
ReadStream<Buffer> readStream = new BufferReadStream(testBuffer);
return pump(readStream, fileBackedBuffer)
.flatMap(aVoid1 -> {
ReadStream<Buffer> fileBackedReadStream = fileBackedBuffer.readStream();
BufferWriteEndableWriteStream bufferedWriteStreamConsumer = new BufferWriteEndableWriteStream();
return pump(fileBackedReadStream, bufferedWriteStreamConsumer)
.doOnNext(aVoid2 -> {
Buffer actualBuffer = bufferedWriteStreamConsumer.toBuffer();
assertArrayEquals(context, testBuffer.getBytes(), actualBuffer.getBytes());
assertEquals(context, false, fileBackedBuffer.isFileOpen());
});
})
.flatMap(aVoid1 -> fileBackedBuffer.close());
})
.subscribe(new TestSubscriber(context, async));
}
}