View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with this
6    * work for additional information regarding copyright ownership. The ASF
7    * licenses this file to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16   * License for the specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.io.hfile.bucket;
20  
21  import static org.junit.Assert.assertArrayEquals;
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertNotEquals;
24  import static org.junit.Assert.assertNotNull;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.nio.ByteBuffer;
29  import java.nio.channels.FileChannel;
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  import org.apache.hadoop.hbase.testclassification.SmallTests;
34  import org.junit.After;
35  import org.junit.Before;
36  import org.junit.Test;
37  import org.junit.experimental.categories.Category;
38  
39  /**
40   * Basic test for {@link FileIOEngine}
41   */
42  @Category(SmallTests.class)
43  public class TestFileIOEngine {
44  
45    private static final long TOTAL_CAPACITY = 6 * 1024 * 1024; // 6 MB
46    private static final String[] FILE_PATHS = {"testFileIOEngine1", "testFileIOEngine2",
47        "testFileIOEngine3"};
48    private static final long SIZE_PER_FILE = TOTAL_CAPACITY / FILE_PATHS.length; // 2 MB per File
49    private final static List<Long> boundaryStartPositions = new ArrayList<Long>();
50    private final static List<Long> boundaryStopPositions = new ArrayList<Long>();
51  
52    private FileIOEngine fileIOEngine;
53  
54    static {
55      boundaryStartPositions.add(0L);
56      for (int i = 1; i < FILE_PATHS.length; i++) {
57        boundaryStartPositions.add(SIZE_PER_FILE * i - 1);
58        boundaryStartPositions.add(SIZE_PER_FILE * i);
59        boundaryStartPositions.add(SIZE_PER_FILE * i + 1);
60      }
61      for (int i = 1; i < FILE_PATHS.length; i++) {
62        boundaryStopPositions.add(SIZE_PER_FILE * i - 1);
63        boundaryStopPositions.add(SIZE_PER_FILE * i);
64        boundaryStopPositions.add(SIZE_PER_FILE * i + 1);
65      }
66      boundaryStopPositions.add(SIZE_PER_FILE * FILE_PATHS.length - 1);
67    }
68  
69    @Before
70    public void setUp() throws IOException {
71      fileIOEngine = new FileIOEngine(TOTAL_CAPACITY, FILE_PATHS);
72    }
73  
74    @After
75    public void cleanUp() throws IOException {
76      fileIOEngine.shutdown();
77      for (String filePath : FILE_PATHS) {
78        File file = new File(filePath);
79        if (file.exists()) {
80          file.delete();
81        }
82      }
83    }
84  
85    @Test
86    public void testFileIOEngine() throws IOException {
87      for (int i = 0; i < 500; i++) {
88        int len = (int) Math.floor(Math.random() * 100) + 1;
89        long offset = (long) Math.floor(Math.random() * TOTAL_CAPACITY % (TOTAL_CAPACITY - len));
90        if (i < boundaryStartPositions.size()) {
91          // make the boundary start positon
92          offset = boundaryStartPositions.get(i);
93        } else if ((i - boundaryStartPositions.size()) < boundaryStopPositions.size()) {
94          // make the boundary stop positon
95          offset = boundaryStopPositions.get(i - boundaryStartPositions.size()) - len + 1;
96        } else if (i % 2 == 0) {
97          // make the cross-files block writing/reading
98          offset = Math.max(1, i % FILE_PATHS.length) * SIZE_PER_FILE - len / 2;
99        }
100       byte[] data1 = new byte[len];
101       for (int j = 0; j < data1.length; ++j) {
102         data1[j] = (byte) (Math.random() * 255);
103       }
104       byte[] data2 = new byte[len];
105       fileIOEngine.write(ByteBuffer.wrap(data1), offset);
106       fileIOEngine.read(ByteBuffer.wrap(data2), offset);
107       assertArrayEquals(data1, data2);
108     }
109   }
110 
111   @Test
112   public void testFileIOEngineHandlesZeroLengthInput() throws IOException {
113     byte[] data1 = new byte[0];
114 
115 
116     byte[] data2 = new byte[0];
117     fileIOEngine.write(ByteBuffer.wrap(data1), 0);
118     fileIOEngine.read(ByteBuffer.wrap(data2), 0);
119     assertArrayEquals(data1, data2);
120   }
121 
122   @Test
123   public void testClosedChannelException() throws IOException {
124     fileIOEngine.closeFileChannels();
125     int len = 5;
126     long offset = 0L;
127     byte[] data1 = new byte[len];
128     for (int j = 0; j < data1.length; ++j) {
129       data1[j] = (byte) (Math.random() * 255);
130     }
131     byte[] data2 = new byte[len];
132     fileIOEngine.write(ByteBuffer.wrap(data1), offset);
133     fileIOEngine.read(ByteBuffer.wrap(data2), offset);
134     assertArrayEquals(data1, data2);
135   }
136 
137   @Test
138   public void testRefreshFileConnection() throws IOException {
139     FileChannel[] fileChannels = fileIOEngine.getFileChannels();
140     FileChannel fileChannel = fileChannels[0];
141     assertNotNull(fileChannel);
142     fileChannel.close();
143     fileIOEngine.refreshFileConnection(0, new IOException("Test Exception"));
144     FileChannel[] reopenedFileChannels = fileIOEngine.getFileChannels();
145     FileChannel reopenedFileChannel = reopenedFileChannels[0];
146     assertNotEquals(fileChannel, reopenedFileChannel);
147     assertEquals(fileChannels.length, reopenedFileChannels.length);
148     for (int i = 1; i < fileChannels.length; i++) {
149       assertEquals(fileChannels[i], reopenedFileChannels[i]);
150     }
151   }
152 }