39
39
import org .apache .hadoop .hbase .util .HFileArchiveUtil ;
40
40
import org .apache .hadoop .hbase .util .MockServer ;
41
41
import org .apache .hadoop .hbase .zookeeper .ZKWatcher ;
42
+ import org .junit .After ;
42
43
import org .junit .AfterClass ;
44
+ import org .junit .Before ;
43
45
import org .junit .BeforeClass ;
44
46
import org .junit .ClassRule ;
45
47
import org .junit .Rule ;
@@ -57,9 +59,28 @@ public class TestHFileLinkCleaner {
57
59
public static final HBaseClassTestRule CLASS_RULE =
58
60
HBaseClassTestRule .forClass (TestHFileLinkCleaner .class );
59
61
62
+ private Configuration conf ;
63
+ private Path rootDir ;
64
+ private FileSystem fs ;
65
+ private TableName tableName ;
66
+ private TableName tableLinkName ;
67
+ private String hfileName ;
68
+ private String familyName ;
69
+ private RegionInfo hri ;
70
+ private RegionInfo hriLink ;
71
+ private Path archiveDir ;
72
+ private Path archiveStoreDir ;
73
+ private Path familyPath ;
74
+ private Path hfilePath ;
75
+ private Path familyLinkPath ;
76
+ private String hfileLinkName ;
77
+ private Path linkBackRefDir ;
78
+ private Path linkBackRef ;
79
+ private FileStatus [] backRefs ;
80
+ private HFileCleaner cleaner ;
60
81
private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil ();
61
-
62
82
private static DirScanPool POOL ;
83
+ private static final long TTL = 1000 ;
63
84
64
85
@ Rule
65
86
public TestName name = new TestName ();
@@ -74,49 +95,71 @@ public static void tearDown() {
74
95
POOL .shutdownNow ();
75
96
}
76
97
77
- @ Test
78
- public void testHFileLinkCleaning () throws Exception {
79
- Configuration conf = TEST_UTIL .getConfiguration ();
98
+ @ Before
99
+ public void configureDirectoriesAndLinks () throws IOException {
100
+ conf = TEST_UTIL .getConfiguration ();
80
101
CommonFSUtils .setRootDir (conf , TEST_UTIL .getDataTestDir ());
81
102
conf .set (HFileCleaner .MASTER_HFILE_CLEANER_PLUGINS , HFileLinkCleaner .class .getName ());
82
- Path rootDir = CommonFSUtils .getRootDir (conf );
83
- FileSystem fs = FileSystem .get (conf );
103
+ rootDir = CommonFSUtils .getRootDir (conf );
104
+ fs = FileSystem .get (conf );
84
105
85
- final TableName tableName = TableName .valueOf (name .getMethodName ());
86
- final TableName tableLinkName = TableName .valueOf (name .getMethodName () + "-link" );
87
- final String hfileName = "1234567890" ;
88
- final String familyName = "cf" ;
106
+ tableName = TableName .valueOf (name .getMethodName ());
107
+ tableLinkName = TableName .valueOf (name .getMethodName () + "-link" );
108
+ hfileName = "1234567890" ;
109
+ familyName = "cf" ;
89
110
90
- RegionInfo hri = RegionInfoBuilder .newBuilder (tableName ).build ();
91
- RegionInfo hriLink = RegionInfoBuilder .newBuilder (tableLinkName ).build ();
111
+ hri = RegionInfoBuilder .newBuilder (tableName ).build ();
112
+ hriLink = RegionInfoBuilder .newBuilder (tableLinkName ).build ();
92
113
93
- Path archiveDir = HFileArchiveUtil .getArchivePath (conf );
94
- Path archiveStoreDir =
114
+ archiveDir = HFileArchiveUtil .getArchivePath (conf );
115
+ archiveStoreDir =
95
116
HFileArchiveUtil .getStoreArchivePath (conf , tableName , hri .getEncodedName (), familyName );
96
117
97
118
// Create hfile /hbase/table-link/region/cf/getEncodedName.HFILE(conf);
98
- Path familyPath = getFamilyDirPath (archiveDir , tableName , hri .getEncodedName (), familyName );
119
+ familyPath = getFamilyDirPath (archiveDir , tableName , hri .getEncodedName (), familyName );
99
120
fs .mkdirs (familyPath );
100
- Path hfilePath = new Path (familyPath , hfileName );
121
+ hfilePath = new Path (familyPath , hfileName );
101
122
fs .createNewFile (hfilePath );
102
123
124
+ createLink (true );
125
+
126
+ // Initialize cleaner
127
+ conf .setLong (TimeToLiveHFileCleaner .TTL_CONF_KEY , TTL );
128
+ Server server = new DummyServer ();
129
+ cleaner = new HFileCleaner (1000 , server , conf , fs , archiveDir , POOL );
130
+ }
131
+
132
+ private void createLink (boolean createBackReference ) throws IOException {
103
133
// Create link to hfile
104
- Path familyLinkPath =
105
- getFamilyDirPath (rootDir , tableLinkName , hriLink .getEncodedName (), familyName );
134
+ familyLinkPath = getFamilyDirPath (rootDir , tableLinkName , hriLink .getEncodedName (), familyName );
106
135
fs .mkdirs (familyLinkPath );
107
- HFileLink .create (conf , fs , familyLinkPath , hri , hfileName );
108
- Path linkBackRefDir = HFileLink .getBackReferencesDir (archiveStoreDir , hfileName );
136
+ hfileLinkName = HFileLink .create (conf , fs , familyLinkPath , hri , hfileName , createBackReference );
137
+ linkBackRefDir = HFileLink .getBackReferencesDir (archiveStoreDir , hfileName );
109
138
assertTrue (fs .exists (linkBackRefDir ));
110
- FileStatus [] backRefs = fs .listStatus (linkBackRefDir );
139
+ backRefs = fs .listStatus (linkBackRefDir );
111
140
assertEquals (1 , backRefs .length );
112
- Path linkBackRef = backRefs [0 ].getPath ();
141
+ linkBackRef = backRefs [0 ].getPath ();
142
+ }
113
143
114
- // Initialize cleaner
115
- final long ttl = 1000 ;
116
- conf .setLong (TimeToLiveHFileCleaner .TTL_CONF_KEY , ttl );
117
- Server server = new DummyServer ();
118
- HFileCleaner cleaner = new HFileCleaner (1000 , server , conf , fs , archiveDir , POOL );
144
+ @ After
145
+ public void cleanup () throws IOException , InterruptedException {
146
+ // HFile can be removed
147
+ Thread .sleep (TTL * 2 );
148
+ cleaner .chore ();
149
+ assertFalse ("HFile should be deleted" , fs .exists (hfilePath ));
150
+ // Remove everything
151
+ for (int i = 0 ; i < 4 ; ++i ) {
152
+ Thread .sleep (TTL * 2 );
153
+ cleaner .chore ();
154
+ }
155
+ assertFalse ("HFile should be deleted" ,
156
+ fs .exists (CommonFSUtils .getTableDir (archiveDir , tableName )));
157
+ assertFalse ("Link should be deleted" ,
158
+ fs .exists (CommonFSUtils .getTableDir (archiveDir , tableLinkName )));
159
+ }
119
160
161
+ @ Test
162
+ public void testHFileLinkCleaning () throws Exception {
120
163
// Link backref cannot be removed
121
164
cleaner .chore ();
122
165
assertTrue (fs .exists (linkBackRef ));
@@ -127,21 +170,28 @@ public void testHFileLinkCleaning() throws Exception {
127
170
CommonFSUtils .getTableDir (archiveDir , tableLinkName ));
128
171
cleaner .chore ();
129
172
assertFalse ("Link should be deleted" , fs .exists (linkBackRef ));
173
+ }
130
174
131
- // HFile can be removed
132
- Thread .sleep (ttl * 2 );
175
+ @ Test
176
+ public void testHFileLinkByRemovingReference () throws Exception {
177
+ // Link backref cannot be removed
133
178
cleaner .chore ();
134
- assertFalse ("HFile should be deleted" , fs .exists (hfilePath ));
179
+ assertTrue (fs .exists (linkBackRef ));
180
+ assertTrue (fs .exists (hfilePath ));
135
181
136
- // Remove everything
137
- for (int i = 0 ; i < 4 ; ++i ) {
138
- Thread .sleep (ttl * 2 );
139
- cleaner .chore ();
140
- }
141
- assertFalse ("HFile should be deleted" ,
142
- fs .exists (CommonFSUtils .getTableDir (archiveDir , tableName )));
143
- assertFalse ("Link should be deleted" ,
144
- fs .exists (CommonFSUtils .getTableDir (archiveDir , tableLinkName )));
182
+ // simulate after removing the reference in data directory, the Link backref can be removed
183
+ fs .delete (new Path (familyLinkPath , hfileLinkName ), false );
184
+ cleaner .chore ();
185
+ assertFalse ("Link should be deleted" , fs .exists (linkBackRef ));
186
+ }
187
+
188
+ @ Test
189
+ public void testHFileLinkEmptyBackReferenceDirectory () throws Exception {
190
+ // simulate and remove the back reference
191
+ fs .delete (linkBackRef , false );
192
+ assertTrue ("back reference directory still exists" , fs .exists (linkBackRefDir ));
193
+ cleaner .chore ();
194
+ assertFalse ("back reference directory should be deleted" , fs .exists (linkBackRefDir ));
145
195
}
146
196
147
197
private static Path getFamilyDirPath (final Path rootDir , final TableName table ,
0 commit comments