| /* |
| * Licensed to 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 org.apache.hadoop.hdfs.server.datanode; |
| |
| import java.io.IOException; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fi.DataTransferTestUtil; |
| import org.apache.hadoop.fi.FiTestUtil; |
| import org.apache.hadoop.fi.DataTransferTestUtil.DataTransferTest; |
| import org.apache.hadoop.fi.DataTransferTestUtil.SleepAction; |
| import org.apache.hadoop.fi.FiTestUtil.Action; |
| import org.apache.hadoop.fs.FSDataInputStream; |
| import org.apache.hadoop.fs.FSDataOutputStream; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.hdfs.DFSConfigKeys; |
| import org.apache.hadoop.hdfs.HdfsConfiguration; |
| import org.apache.hadoop.hdfs.MiniDFSCluster; |
| import org.apache.hadoop.hdfs.protocol.DatanodeID; |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| /** Test DataTransferProtocol with fault injection. */ |
| public class TestFiPipelineClose { |
| static final short REPLICATION = 3; |
| static final long BLOCKSIZE = 1L * (1L << 20); |
| |
| static final Configuration conf = new HdfsConfiguration(); |
| static { |
| conf.setInt("dfs.datanode.handler.count", 1); |
| conf.setInt("dfs.replication", REPLICATION); |
| conf.setInt(DFSConfigKeys.DFS_CLIENT_SOCKET_TIMEOUT_KEY, 5000); |
| } |
| |
| static private FSDataOutputStream createFile(FileSystem fs, Path p |
| ) throws IOException { |
| return fs.create(p, true, fs.getConf().getInt("io.file.buffer.size", 4096), |
| REPLICATION, BLOCKSIZE); |
| } |
| |
| /** |
| * 1. create files with dfs |
| * 2. write 1 byte |
| * 3. close file |
| * 4. open the same file |
| * 5. read the 1 byte and compare results |
| */ |
| private static void write1byte(String methodName) throws IOException { |
| final MiniDFSCluster cluster = new MiniDFSCluster(conf, REPLICATION, true, |
| null); |
| final FileSystem dfs = cluster.getFileSystem(); |
| try { |
| final Path p = new Path("/" + methodName + "/foo"); |
| final FSDataOutputStream out = createFile(dfs, p); |
| out.write(1); |
| out.close(); |
| |
| final FSDataInputStream in = dfs.open(p); |
| final int b = in.read(); |
| in.close(); |
| Assert.assertEquals(1, b); |
| } |
| finally { |
| dfs.close(); |
| cluster.shutdown(); |
| } |
| } |
| |
| private static void runPipelineCloseTest(String methodName, |
| Action<DatanodeID, IOException> a) throws IOException { |
| FiTestUtil.LOG.info("Running " + methodName + " ..."); |
| final DataTransferTest t = (DataTransferTest) DataTransferTestUtil |
| .initTest(); |
| t.fiPipelineClose.set(a); |
| write1byte(methodName); |
| } |
| |
| /** |
| * Pipeline close: |
| * DN0 never responses after received close request from client. |
| * Client gets an IOException and determine DN0 bad. |
| */ |
| @Test |
| public void pipeline_Fi_36() throws IOException { |
| final String methodName = FiTestUtil.getMethodName(); |
| runPipelineCloseTest(methodName, new SleepAction(methodName, 0, 0)); |
| } |
| |
| /** |
| * Pipeline close: |
| * DN1 never responses after received close request from client. |
| * Client gets an IOException and determine DN1 bad. |
| */ |
| @Test |
| public void pipeline_Fi_37() throws IOException { |
| final String methodName = FiTestUtil.getMethodName(); |
| runPipelineCloseTest(methodName, new SleepAction(methodName, 1, 0)); |
| } |
| |
| /** |
| * Pipeline close: |
| * DN2 never responses after received close request from client. |
| * Client gets an IOException and determine DN2 bad. |
| */ |
| @Test |
| public void pipeline_Fi_38() throws IOException { |
| final String methodName = FiTestUtil.getMethodName(); |
| runPipelineCloseTest(methodName, new SleepAction(methodName, 2, 0)); |
| } |
| } |