/** * Copyright 2016 StreamSets Inc. * * Licensed under the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 com.streamsets.pipeline.lib.io.fileref; import com.codahale.metrics.Counter; import com.streamsets.pipeline.api.FileRef; import com.streamsets.pipeline.api.OnRecordError; import com.streamsets.pipeline.api.Stage; import com.streamsets.pipeline.sdk.ContextInfoCreator; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.internal.util.reflection.Whitebox; import java.io.File; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; import java.util.UUID; public class TestMetricsEnabledWrapperStream { private File testDir; private Stage.Context context; @Before public void setup() throws Exception { testDir = new File("target", UUID.randomUUID().toString()); testDir.mkdirs(); FileRefTestUtil.writePredefinedTextToFile(testDir); context = ContextInfoCreator.createTargetContext("", false, OnRecordError.TO_ERROR); } @After public void tearDown() throws Exception { testDir.delete(); } private <T extends AutoCloseable> long getRemainingBytes(T stream) { return ((Counter)Whitebox.getInternalState(stream, "remainingBytesCounter")).getCount(); } private <T extends AutoCloseable> long getSentBytes(T stream) { return ((Counter)Whitebox.getInternalState(stream, "sentBytesCounter")).getCount(); } private <T extends AutoCloseable> void checkStateDuringReads(long fileSize, long remainingFileSize, T is) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); Assert.assertEquals(fileSize - remainingFileSize, getSentBytes(is)); Assert.assertEquals(fileSize, getRemainingBytes(is) + getSentBytes(is)); } private <T extends AutoCloseable> void checkStateAfterReadCompletion(long fileSize, long remainingFileSize, T is) { Assert.assertEquals(0, remainingFileSize); Assert.assertEquals(fileSize, getSentBytes(is)); Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); } @Test public void testIOReadParameterLess() throws Exception { FileRef fileRef = FileRefTestUtil.getLocalFileRef(testDir, true, null, null); long fileSize = Files.size(Paths.get(FileRefTestUtil.getSourceFilePath(testDir))); long remainingFileSize = fileSize; try (InputStream is = fileRef.createInputStream(context, InputStream.class)) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); while(is.read() != -1) { remainingFileSize--; checkStateDuringReads(fileSize, remainingFileSize, is); } checkStateAfterReadCompletion(fileSize, remainingFileSize, is); } } @Test public void testIOReadParameterized() throws Exception { FileRef fileRef = FileRefTestUtil.getLocalFileRef(testDir, true, null, null); long fileSize = Files.size(Paths.get(FileRefTestUtil.getSourceFilePath(testDir))); long remainingFileSize = fileSize; try (InputStream is = fileRef.createInputStream(context, InputStream.class)) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); int bytesRead; byte[] b = new byte[10]; while( (bytesRead = is.read(b, 0, b.length)) > 0) { remainingFileSize -= bytesRead; checkStateDuringReads(fileSize, remainingFileSize, is); } checkStateAfterReadCompletion(fileSize, remainingFileSize, is); } } @Test public void testIOReadsMixed() throws Exception { FileRef fileRef = FileRefTestUtil.getLocalFileRef(testDir, true, null, null); long fileSize = Files.size(Paths.get(FileRefTestUtil.getSourceFilePath(testDir))); long remainingFileSize = fileSize; try (InputStream is = fileRef.createInputStream(context, InputStream.class)) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); int bytesRead; while ((bytesRead= FileRefTestUtil.randomReadMethodsWithInputStream(is)) > 0) { remainingFileSize -= bytesRead; checkStateDuringReads(fileSize, remainingFileSize, is); } checkStateAfterReadCompletion(fileSize, remainingFileSize, is); } } @Test public void testNIOReadWithDirectBuffer() throws Exception { FileRef fileRef = FileRefTestUtil.getLocalFileRef(testDir, true, null, null); long fileSize = Files.size(Paths.get(FileRefTestUtil.getSourceFilePath(testDir))); long remainingFileSize = fileSize; try (ReadableByteChannel is = fileRef.createInputStream(context, ReadableByteChannel.class)) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); int bytesRead; ByteBuffer b = ByteBuffer.allocateDirect(10); while((bytesRead = is.read(b)) > 0) { remainingFileSize -= bytesRead; checkStateDuringReads(fileSize, remainingFileSize, is); b.compact(); } checkStateAfterReadCompletion(fileSize, remainingFileSize, is); } } @Test public void testNIOReadWithHeapByteBuffer() throws Exception { FileRef fileRef = FileRefTestUtil.getLocalFileRef(testDir, true, null, null); long fileSize = Files.size(Paths.get(FileRefTestUtil.getSourceFilePath(testDir))); long remainingFileSize = fileSize; try (ReadableByteChannel is = fileRef.createInputStream(context, ReadableByteChannel.class)) { Assert.assertEquals(remainingFileSize, getRemainingBytes(is)); int bytesRead; ByteBuffer b = ByteBuffer.allocate(10); while((bytesRead = is.read(b)) > 0) { remainingFileSize -= bytesRead; checkStateDuringReads(fileSize, remainingFileSize, is); b.compact(); } checkStateAfterReadCompletion(fileSize, remainingFileSize, is); } } @Test public void testCompletedFileCountForMultipleClose() throws Exception { InputStream is = FileRefTestUtil.getLocalFileRef(testDir, true, null, null).createInputStream(context, InputStream.class); try { while (is.read() != -1); } finally { is.close(); is.close(); } Map<String, Object> gaugeMap = (Map<String, Object>)(context.getGauge(FileRefUtil.GAUGE_NAME).getValue()); long completedCount = (long)gaugeMap.get(FileRefUtil.COMPLETED_FILE_COUNT); Assert.assertEquals(1, completedCount); } @Test public void testConvertBytesToDisplayFormat() throws Exception { //Bytes Assert.assertEquals("1023 B", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1023d)); Assert.assertEquals("512 B", MetricEnabledWrapperStream.convertBytesToDisplayFormat(512d)); Assert.assertEquals("0 B", MetricEnabledWrapperStream.convertBytesToDisplayFormat(0d)); //KB Assert.assertEquals("1 KB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1025d)); Assert.assertEquals("1.5 KB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1540d)); Assert.assertEquals("1.55 KB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1588d)); Assert.assertEquals("1023.99 KB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1048570d)); //MB Assert.assertEquals("1 MB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1048576d)); Assert.assertEquals("100.98 MB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(105885205d)); Assert.assertEquals("1024 MB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1073741810d)); //GB Assert.assertEquals("1 GB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1073741824d)); Assert.assertEquals("1024 GB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1099511627774d)); //TB Assert.assertEquals("1 TB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1099511627776d)); Assert.assertEquals("1025 TB", MetricEnabledWrapperStream.convertBytesToDisplayFormat(1126999418470400d)); } }