1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.cleaner;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.HBaseTestingUtility;
28 import org.apache.hadoop.hbase.Stoppable;
29 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
30 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
31 import org.apache.hadoop.hbase.testclassification.MasterTests;
32 import org.apache.hadoop.hbase.testclassification.SmallTests;
33 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
34 import org.junit.Test;
35 import org.junit.experimental.categories.Category;
36 import org.mockito.Mockito;
37
38
39
40
41 @Category({MasterTests.class, SmallTests.class})
42 public class TestSnapshotCleanerChore {
43
44 private static final Log LOG = LogFactory.getLog(TestSnapshotCleanerChore.class);
45
46 private static final HBaseTestingUtility HBASE_TESTING_UTILITY = new HBaseTestingUtility();
47
48 private SnapshotManager snapshotManager;
49
50 private Configuration getSnapshotCleanerConf() {
51 Configuration conf = HBASE_TESTING_UTILITY.getConfiguration();
52 conf.setInt("hbase.master.cleaner.snapshot.interval", 100);
53 return conf;
54 }
55
56
57 @Test
58 public void testSnapshotCleanerWithoutAnyCompletedSnapshot() throws IOException {
59 snapshotManager = Mockito.mock(SnapshotManager.class);
60 Stoppable stopper = new StoppableImplementation();
61 Configuration conf = getSnapshotCleanerConf();
62 SnapshotCleanerChore snapshotCleanerChore =
63 new SnapshotCleanerChore(stopper, conf, snapshotManager);
64 try {
65 snapshotCleanerChore.chore();
66 } finally {
67 stopper.stop("Stopping Test Stopper");
68 }
69 Mockito.verify(snapshotManager, Mockito.times(0))
70 .deleteSnapshot(Mockito.any(SnapshotDescription.class));
71 }
72
73 @Test
74 public void testSnapshotCleanerWithNoTtlExpired() throws IOException {
75 snapshotManager = Mockito.mock(SnapshotManager.class);
76 Stoppable stopper = new StoppableImplementation();
77 Configuration conf = getSnapshotCleanerConf();
78 SnapshotCleanerChore snapshotCleanerChore =
79 new SnapshotCleanerChore(stopper, conf, snapshotManager);
80 List<SnapshotDescription> snapshotDescriptionList = new ArrayList<>();
81 snapshotDescriptionList.add(getSnapshotDescription(-2, "snapshot01", "table01",
82 EnvironmentEdgeManager.currentTime() - 100000));
83 snapshotDescriptionList.add(getSnapshotDescription(10, "snapshot02", "table02",
84 EnvironmentEdgeManager.currentTime()));
85 Mockito.when(snapshotManager.getCompletedSnapshots()).thenReturn(snapshotDescriptionList);
86 try {
87 LOG.info("2 Snapshots are completed but TTL is not expired for any of them");
88 snapshotCleanerChore.chore();
89 } finally {
90 stopper.stop("Stopping Test Stopper");
91 }
92 Mockito.verify(snapshotManager, Mockito.times(0))
93 .deleteSnapshot(Mockito.any(SnapshotDescription.class));
94 }
95
96 @Test
97 public void testSnapshotCleanerWithSomeTtlExpired() throws IOException {
98 snapshotManager = Mockito.mock(SnapshotManager.class);
99 Stoppable stopper = new StoppableImplementation();
100 Configuration conf = getSnapshotCleanerConf();
101 SnapshotCleanerChore snapshotCleanerChore =
102 new SnapshotCleanerChore(stopper, conf, snapshotManager);
103 List<SnapshotDescription> snapshotDescriptionList = new ArrayList<>();
104 snapshotDescriptionList.add(getSnapshotDescription(10, "snapshot01", "table01", 1));
105 snapshotDescriptionList.add(getSnapshotDescription(5, "snapshot02", "table02", 2));
106 snapshotDescriptionList.add(getSnapshotDescription(30, "snapshot01", "table01",
107 EnvironmentEdgeManager.currentTime()));
108 snapshotDescriptionList.add(getSnapshotDescription(0, "snapshot02", "table02",
109 EnvironmentEdgeManager.currentTime()));
110 snapshotDescriptionList.add(getSnapshotDescription(40, "snapshot03", "table03",
111 EnvironmentEdgeManager.currentTime()));
112 Mockito.when(snapshotManager.getCompletedSnapshots()).thenReturn(snapshotDescriptionList);
113 try {
114 LOG.info("5 Snapshots are completed. TTL is expired for 2 them. Going to delete them");
115 snapshotCleanerChore.chore();
116 } finally {
117 stopper.stop("Stopping Test Stopper");
118 }
119 Mockito.verify(snapshotManager, Mockito.times(2))
120 .deleteSnapshot(Mockito.any(SnapshotDescription.class));
121 }
122
123 @Test
124 public void testSnapshotCleanerWithReadIOE() throws IOException {
125 snapshotManager = Mockito.mock(SnapshotManager.class);
126 Stoppable stopper = new StoppableImplementation();
127 Configuration conf = new HBaseTestingUtility().getConfiguration();
128 SnapshotCleanerChore snapshotCleanerChore =
129 new SnapshotCleanerChore(stopper, conf, snapshotManager);
130 Mockito.when(snapshotManager.getCompletedSnapshots()).thenThrow(IOException.class);
131 try {
132 LOG.info("While getting completed Snapshots, IOException would occur. Hence, No Snapshot"
133 + " should be deleted");
134 snapshotCleanerChore.chore();
135 } finally {
136 stopper.stop("Stopping Test Stopper");
137 }
138 Mockito.verify(snapshotManager, Mockito.times(0))
139 .deleteSnapshot(Mockito.any(SnapshotDescription.class));
140 }
141
142 @Test
143 public void testSnapshotChoreWithTtlOutOfRange() throws IOException {
144 snapshotManager = Mockito.mock(SnapshotManager.class);
145 Stoppable stopper = new StoppableImplementation();
146 Configuration conf = getSnapshotCleanerConf();
147 List<SnapshotDescription> snapshotDescriptionList = new ArrayList<>();
148 snapshotDescriptionList.add(getSnapshotDescription(Long.MAX_VALUE, "snapshot01", "table01", 1));
149 snapshotDescriptionList.add(getSnapshotDescription(5, "snapshot02", "table02", 2));
150 Mockito.when(snapshotManager.getCompletedSnapshots()).thenReturn(snapshotDescriptionList);
151 SnapshotCleanerChore snapshotCleanerChore =
152 new SnapshotCleanerChore(stopper, conf, snapshotManager);
153 try {
154 LOG.info("Snapshot Chore is disabled. No cleanup performed for Expired Snapshots");
155 snapshotCleanerChore.chore();
156 } finally {
157 stopper.stop("Stopping Test Stopper");
158 }
159 Mockito.verify(snapshotManager, Mockito.times(1)).getCompletedSnapshots();
160 }
161
162 private SnapshotDescription getSnapshotDescription(final long ttl,
163 final String snapshotName, final String tableName, final long snapshotCreationTime) {
164 SnapshotDescription.Builder snapshotDescriptionBuilder =
165 SnapshotDescription.newBuilder();
166 snapshotDescriptionBuilder.setTtl(ttl);
167 snapshotDescriptionBuilder.setName(snapshotName);
168 snapshotDescriptionBuilder.setTable(tableName);
169 snapshotDescriptionBuilder.setType(SnapshotDescription.Type.FLUSH);
170 snapshotDescriptionBuilder.setCreationTime(snapshotCreationTime);
171 return snapshotDescriptionBuilder.build();
172 }
173
174
175
176
177 private static class StoppableImplementation implements Stoppable {
178
179 private volatile boolean stop = false;
180
181 @Override
182 public void stop(String why) {
183 this.stop = true;
184 }
185
186 @Override
187 public boolean isStopped() {
188 return this.stop;
189 }
190
191 }
192
193 }