/*
* 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.geode.internal.cache.persistence;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.Scope;
import org.apache.geode.internal.FileUtil;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.test.dunit.AsyncInvocation;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.Wait;
import org.apache.geode.test.dunit.WaitCriterion;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
public abstract class PersistentReplicatedTestBase extends JUnit4CacheTestCase {
protected static final int MAX_WAIT = 30 * 1000;
protected static String REGION_NAME = "region";
protected File diskDir;
protected static String SAVED_ACK_WAIT_THRESHOLD;
@Override
public final void postSetUp() throws Exception {
Invoke.invokeInEveryVM(PersistentReplicatedTestBase.class, "setRegionName",
new Object[] {getUniqueName()});
setRegionName(getUniqueName());
diskDir = new File("diskDir-" + getName()).getAbsoluteFile();
org.apache.geode.internal.FileUtil.delete(diskDir);
diskDir.mkdir();
diskDir.deleteOnExit();
}
public static void setRegionName(String testName) {
REGION_NAME = testName + "Region";
}
@Override
public final void postTearDownCacheTestCase() throws Exception {
org.apache.geode.internal.FileUtil.delete(diskDir);
postTearDownPersistentReplicatedTestBase();
}
protected void postTearDownPersistentReplicatedTestBase() throws Exception {}
protected void waitForBlockedInitialization(VM vm) {
vm.invoke(new SerializableRunnable() {
public void run() {
Wait.waitForCriterion(new WaitCriterion() {
public String description() {
return "Waiting for another persistent member to come online";
}
public boolean done() {
GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
PersistentMemberManager mm = cache.getPersistentMemberManager();
Map<String, Set<PersistentMemberID>> regions = mm.getWaitingRegions();
boolean done = !regions.isEmpty();
return done;
}
}, MAX_WAIT, 100, true);
}
});
}
protected SerializableRunnable createPersistentRegionWithoutCompaction(final VM vm0) {
SerializableRunnable createRegion = new SerializableRunnable("Create persistent region") {
public void run() {
Cache cache = getCache();
DiskStoreFactory dsf = cache.createDiskStoreFactory();
File dir = getDiskDirForVM(vm0);
dir.mkdirs();
dsf.setDiskDirs(new File[] {dir});
dsf.setMaxOplogSize(1);
dsf.setAutoCompact(false);
dsf.setAllowForceCompaction(true);
dsf.setCompactionThreshold(20);
DiskStore ds = dsf.create(REGION_NAME);
RegionFactory rf = new RegionFactory();
rf.setDiskStoreName(ds.getName());
rf.setDiskSynchronous(true);
rf.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
rf.setScope(Scope.DISTRIBUTED_ACK);
rf.create(REGION_NAME);
}
};
vm0.invoke(createRegion);
return createRegion;
}
protected void closeRegion(final VM vm) {
SerializableRunnable closeRegion = new SerializableRunnable("Close persistent region") {
public void run() {
Cache cache = getCache();
Region region = cache.getRegion(REGION_NAME);
region.close();
}
};
vm.invoke(closeRegion);
}
protected void closeCache(final VM vm) {
SerializableRunnable closeCache = new SerializableRunnable("close cache") {
public void run() {
Cache cache = getCache();
cache.close();
}
};
vm.invoke(closeCache);
}
protected AsyncInvocation closeCacheAsync(VM vm0) {
SerializableRunnable close = new SerializableRunnable() {
public void run() {
Cache cache = getCache();
cache.close();
}
};
return vm0.invokeAsync(close);
}
protected void createNonPersistentRegion(VM vm) throws Exception {
SerializableRunnable createRegion = new SerializableRunnable("Create non persistent region") {
public void run() {
Cache cache = getCache();
RegionFactory rf = new RegionFactory();
rf.setDataPolicy(DataPolicy.REPLICATE);
rf.setScope(Scope.DISTRIBUTED_ACK);
rf.create(REGION_NAME);
}
};
vm.invoke(createRegion);
}
protected AsyncInvocation createPersistentRegionWithWait(VM vm) throws Exception {
return _createPersistentRegion(vm, true);
}
protected void createPersistentRegion(VM vm) throws Exception {
_createPersistentRegion(vm, false);
}
private AsyncInvocation _createPersistentRegion(VM vm, boolean wait) throws Exception {
AsyncInvocation future = createPersistentRegionAsync(vm);
long waitTime = wait ? 500 : MAX_WAIT;
future.join(waitTime);
if (future.isAlive() && !wait) {
fail("Region not created within" + MAX_WAIT);
}
if (!future.isAlive() && wait) {
fail("Did not expecte region creation to complete");
}
if (!wait && future.exceptionOccurred()) {
throw new RuntimeException(future.getException());
}
return future;
}
protected AsyncInvocation createPersistentRegionAsync(final VM vm) {
SerializableRunnable createRegion = new SerializableRunnable("Create persistent region") {
public void run() {
Cache cache = getCache();
DiskStoreFactory dsf = cache.createDiskStoreFactory();
File dir = getDiskDirForVM(vm);
dir.mkdirs();
dsf.setDiskDirs(new File[] {dir});
dsf.setMaxOplogSize(1);
DiskStore ds = dsf.create(REGION_NAME);
RegionFactory rf = new RegionFactory();
rf.setDiskStoreName(ds.getName());
rf.setDiskSynchronous(true);
rf.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
rf.setScope(Scope.DISTRIBUTED_ACK);
rf.create(REGION_NAME);
}
};
return vm.invokeAsync(createRegion);
}
protected File getDiskDirForVM(final VM vm) {
File dir = new File(diskDir, String.valueOf(vm.getPid()));
return dir;
}
protected void backupDir(VM vm) throws IOException {
File dirForVM = getDiskDirForVM(vm);
File backFile = new File(dirForVM.getParent(), dirForVM.getName() + ".bk");
FileUtil.copy(dirForVM, backFile);
}
protected void restoreBackup(VM vm) throws IOException {
File dirForVM = getDiskDirForVM(vm);
File backFile = new File(dirForVM.getParent(), dirForVM.getName() + ".bk");
if (!backFile.renameTo(dirForVM)) {
FileUtil.delete(dirForVM);
FileUtil.copy(backFile, dirForVM);
FileUtil.delete(backFile);
}
}
}