1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.regionserver.wal;
21  
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.fs.Path;
30  import org.apache.hadoop.hbase.HBaseTestingUtility;
31  import org.apache.hadoop.hbase.HConstants;
32  import org.apache.hadoop.hbase.HRegionInfo;
33  import org.apache.hadoop.hbase.HTableDescriptor;
34  import org.apache.hadoop.hbase.KeyValue;
35  import org.apache.hadoop.hbase.util.Bytes;
36  import org.junit.After;
37  import org.junit.Before;
38  import org.junit.BeforeClass;
39  import org.junit.Test;
40  import static org.junit.Assert.*;
41  
42  /**
43   * Test that the actions are called while playing with an HLog
44   */
45  public class TestWALObserver {
46    protected static final Log LOG = LogFactory.getLog(TestWALObserver.class);
47  
48    private final static HBaseTestingUtility TEST_UTIL =
49        new HBaseTestingUtility();
50  
51    private final static byte[] SOME_BYTES =  Bytes.toBytes("t");
52    private static FileSystem fs;
53    private static Path oldLogDir;
54    private static Path logDir;
55    private static Configuration conf;
56  
57    @BeforeClass
58    public static void setUpBeforeClass() throws Exception {
59      conf = TEST_UTIL.getConfiguration();
60      conf.setInt("hbase.regionserver.maxlogs", 5);
61      fs = FileSystem.get(conf);
62      oldLogDir = new Path(HBaseTestingUtility.getTestDir(),
63          HConstants.HREGION_OLDLOGDIR_NAME);
64      logDir = new Path(HBaseTestingUtility.getTestDir(),
65          HConstants.HREGION_LOGDIR_NAME);
66    }
67  
68    @Before
69    public void setUp() throws Exception {
70      fs.delete(logDir, true);
71      fs.delete(oldLogDir, true);
72    }
73  
74    @After
75    public void tearDown() throws Exception {
76      setUp();
77    }
78  
79    /**
80     * Add a bunch of dummy data and roll the logs every two insert. We
81     * should end up with 10 rolled files (plus the roll called in
82     * the constructor). Also test adding a listener while it's running.
83     */
84    @Test
85    public void testActionListener() throws Exception {
86      DummyWALObserver observer = new DummyWALObserver();
87      List<WALObserver> list = new ArrayList<WALObserver>();
88      list.add(observer);
89      DummyWALObserver laterobserver = new DummyWALObserver();
90      HLog hlog = new HLog(fs, logDir, oldLogDir, conf, list, null);
91      HRegionInfo hri = new HRegionInfo(new HTableDescriptor(SOME_BYTES),
92          SOME_BYTES, SOME_BYTES, false);
93  
94      for (int i = 0; i < 20; i++) {
95        byte[] b = Bytes.toBytes(i+"");
96        KeyValue kv = new KeyValue(b,b,b);
97        WALEdit edit = new WALEdit();
98        edit.add(kv);
99        HLogKey key = new HLogKey(b,b, 0, 0);
100       hlog.append(hri, key, edit);
101       if (i == 10) {
102         hlog.registerWALActionsListener(laterobserver);
103       }
104       if (i % 2 == 0) {
105         hlog.rollWriter();
106       }
107     }
108 
109     hlog.close();
110     hlog.closeAndDelete();
111 
112     assertEquals(11, observer.logRollCounter);
113     assertEquals(5, laterobserver.logRollCounter);
114     assertEquals(2, observer.closedCount);
115   }
116 
117   /**
118    * Just counts when methods are called
119    */
120   static class DummyWALObserver implements WALObserver {
121     public int logRollCounter = 0;
122     public int closedCount = 0;
123 
124     @Override
125     public void logRolled(Path newFile) {
126       logRollCounter++;
127     }
128 
129     @Override
130     public void logRollRequested() {
131       // Not interested
132     }
133 
134     @Override
135     public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey,
136         WALEdit logEdit) {
137       // Not interested
138       
139     }
140 
141     @Override
142     public void logCloseRequested() {
143       closedCount++;
144     }
145   }
146 }