001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io.asyncfs; 019 020import static org.hamcrest.CoreMatchers.instanceOf; 021import static org.hamcrest.MatcherAssert.assertThat; 022import static org.junit.jupiter.api.Assertions.assertEquals; 023import static org.junit.jupiter.api.Assertions.fail; 024 025import java.io.FileNotFoundException; 026import java.io.IOException; 027import org.apache.hadoop.fs.FSDataInputStream; 028import org.apache.hadoop.fs.FSDataOutputStream; 029import org.apache.hadoop.fs.FileSystem; 030import org.apache.hadoop.fs.Path; 031import org.apache.hadoop.hbase.testclassification.MediumTests; 032import org.apache.hadoop.hbase.testclassification.MiscTests; 033import org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException; 034import org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException; 035import org.apache.hadoop.ipc.RemoteException; 036import org.junit.jupiter.api.AfterAll; 037import org.junit.jupiter.api.BeforeAll; 038import org.junit.jupiter.api.Tag; 039import org.junit.jupiter.api.Test; 040import org.junit.jupiter.api.TestInfo; 041 042/** 043 * Used to confirm that it is OK to overwrite a file which is being written currently. 044 */ 045@Tag(MiscTests.TAG) 046@Tag(MediumTests.TAG) 047public class TestOverwriteFileUnderConstruction extends AsyncFSTestBase { 048 049 private static FileSystem FS; 050 051 @BeforeAll 052 public static void setUp() throws Exception { 053 startMiniDFSCluster(3); 054 FS = CLUSTER.getFileSystem(); 055 } 056 057 @AfterAll 058 public static void tearDown() throws Exception { 059 shutdownMiniDFSCluster(); 060 } 061 062 @Test 063 public void testNotOverwrite(TestInfo testInfo) throws IOException { 064 Path file = new Path("/" + testInfo.getDisplayName()); 065 try (FSDataOutputStream out1 = FS.create(file)) { 066 try { 067 FS.create(file, false); 068 fail("Should fail as there is a file with the same name which is being written"); 069 } catch (RemoteException e) { 070 // expected 071 assertThat(e.unwrapRemoteException(), instanceOf(AlreadyBeingCreatedException.class)); 072 } 073 } 074 } 075 076 @Test 077 public void testOverwrite(TestInfo testInfo) throws IOException { 078 Path file = new Path("/" + testInfo.getDisplayName()); 079 FSDataOutputStream out1 = FS.create(file); 080 FSDataOutputStream out2 = FS.create(file, true); 081 out1.write(2); 082 out2.write(1); 083 try { 084 out1.close(); 085 // a successful close is also OK for us so no assertion here, we just need to confirm that the 086 // data in the file are correct. 087 } catch (FileNotFoundException fnfe) { 088 // hadoop3 throws one of these. 089 } catch (RemoteException e) { 090 // expected 091 assertThat(e.unwrapRemoteException(), instanceOf(LeaseExpiredException.class)); 092 } 093 out2.close(); 094 try (FSDataInputStream in = FS.open(file)) { 095 assertEquals(1, in.read()); 096 assertEquals(-1, in.read()); 097 } 098 } 099}