package io.eguan.srv; /* * #%L * Project eguan * %% * Copyright (C) 2012 - 2017 Oodrive * %% * 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. * #L% */ import java.io.File; import java.io.FileInputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import org.junit.Assert; public class BasicIopsTestHelper extends AbstractIopsTestHelper { public BasicIopsTestHelper(final int blockSize, final int numBlocks, final int length) { super(blockSize, numBlocks, length); } private final void writeData(final File dataDump, final ClientBasicIops client, final String target, final int increment) throws Exception { final Random random = new Random(System.currentTimeMillis()); final ByteBuffer readData = ByteBuffer.allocate(blockSize * numBlocks); try (final RandomAccessFile raf = new RandomAccessFile(dataDump.getAbsolutePath(), "rw")) { final FileChannel out = raf.getChannel(); final ByteBuffer writeData = ByteBuffer.allocate(blockSize * numBlocks); for (int i = 0; i < length; i += increment) { random.nextBytes(writeData.array()); final int lba = i * numBlocks; client.write(target, writeData, lba, writeData.capacity(), blockSize); writeData.rewind(); out.write(writeData, lba * blockSize); writeData.rewind(); client.read(target, readData, lba, readData.capacity(), blockSize); readData.rewind(); Assert.assertEquals(readData, writeData); } } } private final void readData(final File dataDump, final ClientBasicIops client, final String target, final long size) throws Exception { final ByteBuffer readData = ByteBuffer.allocate(blockSize * numBlocks); final ByteBuffer refData = ByteBuffer.allocate(blockSize * numBlocks); try (final FileInputStream fis = new FileInputStream(dataDump.getAbsolutePath())) { final FileChannel in = fis.getChannel(); for (int i = 0; i < length; i++) { final int lba = i * numBlocks; int toRead = blockSize * numBlocks; toRead -= in.read(refData, lba * blockSize); while (toRead > 0) { toRead -= in.read(refData); } refData.rewind(); client.read(target, readData, lba, readData.capacity(), blockSize); readData.rewind(); Assert.assertEquals("Error i=" + i + ", lba=" + lba, readData, refData); } } client.checkCapacity(target, size); } /** * Read data on a node with an Initiator and compare it with the original file * * @param referenceFile * the reference File to compare the data read from the target * @param client * the initiator used to connect the iscsi server * @param targetName * the target name * @param targetSize * the target size * */ public final void initiatorReadData(final File referenceFile, final ClientBasicIops client, final String targetName, final long targetSize) throws Exception { client.createSession(targetName); try { readData(referenceFile, client, targetName, targetSize); } finally { client.closeSession(targetName); } } public final File initiatorReadWriteData(final ClientBasicIops client, final String targetName, final long targetSize) throws Exception { return initiatorReadWriteData(client, targetName, targetSize, 1, null); } /** * Write data on a node and on a reference file with an Initiator and read it to compare with the reference file * * @param client * the initiator used to connect the iscsi server. * @param targetName * the target name. * @param targetSize * the target size. * @param increment * define the scope of the write of the file: 1 for all the file, 2 for half, etc... * @param * * @return the new file created */ public final File initiatorReadWriteData(final ClientBasicIops client, final String targetName, final long targetSize, final int increment, final File referencePrev) throws Exception { final File referenceFile = referencePrev == null ? File.createTempFile("vold", "test") : referencePrev; try { client.createSession(targetName); try { writeData(referenceFile, client, targetName, increment); readData(referenceFile, client, targetName, targetSize); } finally { client.closeSession(targetName); } } catch (final Exception | Error e) { referenceFile.delete(); throw e; } return referenceFile; } /** * Multi thread R/W method. * * @param executor * @param target * @param iopClient * @param size * @param the * file used to check the data * * @return the future to wait the result */ public Future<File> multiThreadRW(final ExecutorService executor, final String target, final ClientBasicIops iopClient, final long size, final File filename) { final Future<File> future = executor.submit(new Callable<File>() { @Override public File call() throws Exception { return initiatorReadWriteData(iopClient, target, size, 1, filename); } }); return future; } /** * Multi thread R/W method. * * @param executor * @param target * @param iopClient * @param size * * @return the future to wait the result */ public Future<File> multiThreadRW(final ExecutorService executor, final String target, final ClientBasicIops iopClient, final long size) { final Future<File> future = executor.submit(new Callable<File>() { @Override public File call() throws Exception { return initiatorReadWriteData(iopClient, target, size); } }); return future; } }