/* * 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.fs.contract; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.junit.Test; import java.io.FileNotFoundException; import java.io.IOException; import static org.apache.hadoop.fs.contract.ContractTestUtils.createFile; import static org.apache.hadoop.fs.contract.ContractTestUtils.dataset; import static org.apache.hadoop.fs.contract.ContractTestUtils.rm; import static org.apache.hadoop.fs.contract.ContractTestUtils.touch; /** * Test Seek operations */ public abstract class AbstractContractOpenTest extends AbstractFSContractTestBase { private FSDataInputStream instream; @Override protected Configuration createConfiguration() { Configuration conf = super.createConfiguration(); conf.setInt(CommonConfigurationKeysPublic.IO_FILE_BUFFER_SIZE_KEY, 4096); return conf; } @Override public void teardown() throws Exception { IOUtils.closeStream(instream); instream = null; super.teardown(); } @Test public void testOpenReadZeroByteFile() throws Throwable { describe("create & read a 0 byte file"); Path path = path("zero.txt"); touch(getFileSystem(), path); instream = getFileSystem().open(path); assertEquals(0, instream.getPos()); //expect initial read to fail int result = instream.read(); assertMinusOne("initial byte read", result); } @Test public void testFsIsEncrypted() throws Exception { describe("create an empty file and call FileStatus.isEncrypted()"); final Path path = path("file"); createFile(getFileSystem(), path, false, new byte[0]); final FileStatus stat = getFileSystem().getFileStatus(path); assertFalse("Expecting false for stat.isEncrypted()", stat.isEncrypted()); } @Test public void testOpenReadDir() throws Throwable { describe("create & read a directory"); Path path = path("zero.dir"); mkdirs(path); try { instream = getFileSystem().open(path); //at this point we've opened a directory fail("A directory has been opened for reading"); } catch (FileNotFoundException e) { handleExpectedException(e); } catch (IOException e) { handleRelaxedException("opening a directory for reading", "FileNotFoundException", e); } } @Test public void testOpenReadDirWithChild() throws Throwable { describe("create & read a directory which has a child"); Path path = path("zero.dir"); mkdirs(path); Path path2 = new Path(path, "child"); mkdirs(path2); try { instream = getFileSystem().open(path); //at this point we've opened a directory fail("A directory has been opened for reading"); } catch (FileNotFoundException e) { handleExpectedException(e); } catch (IOException e) { handleRelaxedException("opening a directory for reading", "FileNotFoundException", e); } } @Test public void testOpenFileTwice() throws Throwable { describe("verify that two opened file streams are independent"); Path path = path("testopenfiletwice.txt"); byte[] block = dataset(TEST_FILE_LEN, 0, 255); //this file now has a simple rule: offset => value createFile(getFileSystem(), path, false, block); //open first FSDataInputStream instream1 = getFileSystem().open(path); int c = instream1.read(); assertEquals(0,c); FSDataInputStream instream2 = null; try { instream2 = getFileSystem().open(path); assertEquals("first read of instream 2", 0, instream2.read()); assertEquals("second read of instream 1", 1, instream1.read()); instream1.close(); assertEquals("second read of instream 2", 1, instream2.read()); //close instream1 again instream1.close(); } finally { IOUtils.closeStream(instream1); IOUtils.closeStream(instream2); } } @Test public void testSequentialRead() throws Throwable { describe("verify that sequential read() operations return values"); Path path = path("testsequentialread.txt"); int len = 4; int base = 0x40; // 64 byte[] block = dataset(len, base, base + len); //this file now has a simple rule: offset => (value | 0x40) createFile(getFileSystem(), path, false, block); //open first instream = getFileSystem().open(path); assertEquals(base, instream.read()); assertEquals(base + 1, instream.read()); assertEquals(base + 2, instream.read()); assertEquals(base + 3, instream.read()); // and now, failures assertEquals(-1, instream.read()); assertEquals(-1, instream.read()); instream.close(); } }