/** * Get a random key from the given region that is within this instance's range. If no keys qualify * in the region, return null. * * @param aRegion - The region to get the key from. * @param excludeKey - The region to get the key from. * @returns A key from aRegion, or null. */ public Object getRandomKey(Region aRegion, Object excludeKey) { long start = System.currentTimeMillis(); int lower = ((Integer) (lowerKeyRange.get())).intValue(); int upper = ((Integer) (upperKeyRange.get())).intValue(); long randomKeyIndex = TestConfig.tab().getRandGen().nextLong(lower, upper); long startKeyIndex = randomKeyIndex; Object key = NameFactory.getObjectNameForCounter(randomKeyIndex); do { boolean done = false; if ((!(key.equals(excludeKey))) && (aRegion.containsKey(key))) done = true; if (done) break; randomKeyIndex++; // go to the next key if (randomKeyIndex > upper) randomKeyIndex = lower; if (randomKeyIndex == startKeyIndex) { // considered all keys key = null; break; } key = NameFactory.getObjectNameForCounter(randomKeyIndex); } while (true); long end = System.currentTimeMillis(); Log.getLogWriter() .info( "Done in TxUtilKeyRange:getRandomKey, key is " + key + " " + aRegion.getFullPath() + " getRandomKey took " + (end - start) + " millis"); return key; }
/** * Load a region with keys and values. The number of keys and values is specified by the total * number of keys in keyIntervals. This can be invoked by several threads to accomplish the work. */ public void loadRegion() { final long LOG_INTERVAL_MILLIS = 10000; int numKeysToCreate = keyIntervals.getNumKeys(); long lastLogTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis(); SharedCounters sc = CQUtilBB.getBB().getSharedCounters(); do { long shouldAddCount = CQUtilBB.getBB().getSharedCounters().incrementAndRead(CQUtilBB.SHOULD_ADD_COUNT); if (shouldAddCount > numKeysToCreate) { String aStr = "In loadRegion, shouldAddCount is " + shouldAddCount + ", numOriginalKeysCreated is " + sc.read(CQUtilBB.NUM_ORIGINAL_KEYS_CREATED) + ", numKeysToCreate is " + numKeysToCreate + ", region size is " + aRegion.size(); Log.getLogWriter().info(aStr); NameBB.getBB().printSharedCounters(); throw new StopSchedulingTaskOnClientOrder(aStr); } Object key = NameFactory.getNextPositiveObjectName(); QueryObject value = getValueToAdd(key); value.extra = key; Log.getLogWriter().info("Creating with put, key " + key + ", value " + value.toStringFull()); aRegion.put(key, value); sc.increment(CQUtilBB.NUM_ORIGINAL_KEYS_CREATED); if (System.currentTimeMillis() - lastLogTime > LOG_INTERVAL_MILLIS) { Log.getLogWriter() .info( "Added " + NameFactory.getPositiveNameCounter() + " out of " + numKeysToCreate + " entries into " + TestHelper.regionToString(aRegion, false)); lastLogTime = System.currentTimeMillis(); } } while ((minTaskGranularitySec == -1) || (System.currentTimeMillis() - startTime < minTaskGranularityMS)); }
public abstract class BaseHoplogTestCase extends TestCase { public static final String HDFS_STORE_NAME = "hdfs"; public static final Random rand = new Random(System.currentTimeMillis()); protected Path testDataDir; protected Cache cache; protected HDFSRegionDirector director; protected HdfsRegionManager regionManager; protected HDFSStoreFactory hsf; protected HDFSStoreImpl hdfsStore; protected RegionFactory<Object, Object> regionfactory; protected Region<Object, Object> region; protected SortedOplogStatistics stats; protected HFileStoreStatistics storeStats; protected BlockCache blockCache; @Override protected void setUp() throws Exception { super.setUp(); System.setProperty(HDFSStoreImpl.ALLOW_STANDALONE_HDFS_FILESYSTEM_PROP, "true"); // This is logged by HDFS when it is stopped. TestUtils.addExpectedException("sleep interrupted"); TestUtils.addExpectedException("java.io.InterruptedIOException"); testDataDir = new Path("test-case"); cache = createCache(); configureHdfsStoreFactory(); hdfsStore = (HDFSStoreImpl) hsf.create(HDFS_STORE_NAME); regionfactory = cache.createRegionFactory(RegionShortcut.PARTITION_HDFS); regionfactory.setHDFSStoreName(HDFS_STORE_NAME); region = regionfactory.create(getName()); // disable compaction by default and clear existing queues HDFSCompactionManager compactionManager = HDFSCompactionManager.getInstance(hdfsStore); compactionManager.reset(); director = HDFSRegionDirector.getInstance(); director.setCache(cache); regionManager = ((LocalRegion) region).getHdfsRegionManager(); stats = director.getHdfsRegionStats("/" + getName()); storeStats = hdfsStore.getStats(); blockCache = hdfsStore.getBlockCache(); AbstractHoplogOrganizer.JUNIT_TEST_RUN = true; } protected void configureHdfsStoreFactory() throws Exception { hsf = this.cache.createHDFSStoreFactory(); hsf.setHomeDir(testDataDir.toString()); HDFSCompactionConfigFactory cc = hsf.createCompactionConfigFactory(null); cc.setAutoCompaction(false); cc.setAutoMajorCompaction(false); hsf.setHDFSCompactionConfig(cc.create()); } protected Cache createCache() { CacheFactory cf = new CacheFactory().set("mcast-port", "0").set("log-level", "info"); cache = cf.create(); return cache; } @Override protected void tearDown() throws Exception { if (region != null) { region.destroyRegion(); } if (hdfsStore != null) { hdfsStore.getFileSystem().delete(testDataDir, true); hdfsStore.destroy(); } if (cache != null) { cache.close(); } super.tearDown(); TestUtils.removeExpectedException("sleep interrupted"); TestUtils.removeExpectedException("java.io.InterruptedIOException"); } /** * creates a hoplog file with numKeys records. Keys follow key-X pattern and values follow value-X * pattern where X=0 to X is = numKeys -1 * * @return the sorted map of inserted KVs */ protected TreeMap<String, String> createHoplog(int numKeys, Hoplog oplog) throws IOException { int offset = (numKeys > 10 ? 100000 : 0); HoplogWriter writer = oplog.createWriter(numKeys); TreeMap<String, String> map = new TreeMap<String, String>(); for (int i = offset; i < (numKeys + offset); i++) { String key = ("key-" + i); String value = ("value-" + System.nanoTime()); writer.append(key.getBytes(), value.getBytes()); map.put(key, value); } writer.close(); return map; } protected FileStatus[] getBucketHoplogs(String regionAndBucket, final String type) throws IOException { return getBucketHoplogs(hdfsStore.getFileSystem(), regionAndBucket, type); } protected FileStatus[] getBucketHoplogs(FileSystem fs, String regionAndBucket, final String type) throws IOException { FileStatus[] hoplogs = fs.listStatus( new Path(testDataDir, regionAndBucket), new PathFilter() { @Override public boolean accept(Path file) { return file.getName().endsWith(type); } }); return hoplogs; } protected String getRandomHoplogName() { String hoplogName = "hoplog-" + System.nanoTime() + "-" + rand.nextInt(10000) + ".hop"; return hoplogName; } public static MiniDFSCluster initMiniCluster(int port, int numDN) throws Exception { HashMap<String, String> map = new HashMap<String, String>(); map.put(DFSConfigKeys.DFS_REPLICATION_KEY, "1"); return initMiniCluster(port, numDN, map); } public static MiniDFSCluster initMiniCluster(int port, int numDN, HashMap<String, String> map) throws Exception { System.setProperty("test.build.data", "hdfs-test-cluster"); Configuration hconf = new HdfsConfiguration(); for (Entry<String, String> entry : map.entrySet()) { hconf.set(entry.getKey(), entry.getValue()); } hconf.set("dfs.namenode.fs-limits.min-block-size", "1024"); Builder builder = new MiniDFSCluster.Builder(hconf); builder.numDataNodes(numDN); builder.nameNodePort(port); MiniDFSCluster cluster = builder.build(); return cluster; } public static void setConfigFile(HDFSStoreFactory factory, File configFile, String config) throws Exception { BufferedWriter bw = new BufferedWriter(new FileWriter(configFile)); bw.write(config); bw.close(); factory.setHDFSClientConfigFile(configFile.getName()); } public static void alterMajorCompaction(HDFSStoreImpl store, boolean enable) { HDFSStoreMutator mutator = store.createHdfsStoreMutator(); mutator.getCompactionConfigMutator().setAutoMajorCompaction(enable); store.alter(mutator); } public static void alterMinorCompaction(HDFSStoreImpl store, boolean enable) { HDFSStoreMutator mutator = store.createHdfsStoreMutator(); mutator.getCompactionConfigMutator().setAutoCompaction(enable); store.alter(mutator); } public void deleteMiniClusterDir() throws Exception { File clusterDir = new File("hdfs-test-cluster"); if (clusterDir.exists()) { FileUtils.deleteDirectory(clusterDir); } } public static class TestEvent extends SortedHDFSQueuePersistedEvent { Object key; public TestEvent(String k, String v) throws Exception { this(k, v, Operation.PUT_IF_ABSENT); } public TestEvent(String k, String v, Operation op) throws Exception { super(v, op, (byte) 0x02, false, new DiskVersionTag(), BlobHelper.serializeToBlob(k), 0); this.key = k; } public Object getKey() { return key; } public Object getNewValue() { return valueObject; } public Operation getOperation() { return op; } public Region<Object, Object> getRegion() { return null; } public Object getCallbackArgument() { return null; } public boolean isCallbackArgumentAvailable() { return false; } public boolean isOriginRemote() { return false; } public DistributedMember getDistributedMember() { return null; } public boolean isExpiration() { return false; } public boolean isDistributed() { return false; } public Object getOldValue() { return null; } public SerializedCacheValue<Object> getSerializedOldValue() { return null; } public SerializedCacheValue<Object> getSerializedNewValue() { return null; } public boolean isLocalLoad() { return false; } public boolean isNetLoad() { return false; } public boolean isLoad() { return false; } public boolean isNetSearch() { return false; } public TransactionId getTransactionId() { return null; } public boolean isBridgeEvent() { return false; } public boolean hasClientOrigin() { return false; } public boolean isOldValueAvailable() { return false; } } public abstract class AbstractCompactor implements Compactor { @Override public HDFSStore getHdfsStore() { return hdfsStore; } public void suspend() {} public void resume() {} public boolean isBusy(boolean isMajor) { return false; } } }
/** * Verify the contents of the region, taking into account the keys that were destroyed, * invalidated, etc (as specified in keyIntervals) Throw an error of any problems are detected. * This must be called repeatedly by the same thread until StopSchedulingTaskOnClientOrder is * thrown. */ public void verifyRegionContents() { final long LOG_INTERVAL_MILLIS = 10000; // we already completed this check once; we can't do it again without reinitializing the // verify state variables if (verifyRegionContentsCompleted) { throw new TestException( "Test configuration problem; already verified region contents, " + "cannot call this task again without resetting batch variables"); } // iterate keys long lastLogTime = System.currentTimeMillis(); long minTaskGranularitySec = TestConfig.tab().longAt(TestHelperPrms.minTaskGranularitySec); long minTaskGranularityMS = minTaskGranularitySec * TestHelper.SEC_MILLI_FACTOR; long startTime = System.currentTimeMillis(); long size = aRegion.size(); boolean first = true; int numKeysToCheck = keyIntervals.getNumKeys() + numNewKeys; while (verifyRegionContentsIndex < numKeysToCheck) { verifyRegionContentsIndex++; if (first) { Log.getLogWriter() .info( "In verifyRegionContents, region has " + size + " keys; starting verify at verifyRegionContentsIndex " + verifyRegionContentsIndex + "; verifying key names with indexes through (and including) " + numKeysToCheck); first = false; } // check region size the first time through the loop to avoid it being called // multiple times when this is batched if (verifyRegionContentsIndex == 1) { if (totalNumKeys != size) { String tmpStr = "Expected region size to be " + totalNumKeys + ", but it is size " + size; Log.getLogWriter().info(tmpStr); verifyRegionContentsErrStr.append(tmpStr + "\n"); } } Object key = NameFactory.getObjectNameForCounter(verifyRegionContentsIndex); try { if (((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.NONE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.NONE))) || ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.GET)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.GET)))) { // this key was untouched after its creation checkContainsKey(key, true, "key was untouched"); checkContainsValueForKey(key, true, "key was untouched"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.INVALIDATE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.INVALIDATE))) { checkContainsKey(key, true, "key was invalidated"); checkContainsValueForKey(key, false, "key was invalidated"); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.LOCAL_INVALIDATE)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.LOCAL_INVALIDATE))) { // this key was locally invalidated checkContainsKey(key, true, "key was locally invalidated"); checkContainsValueForKey(key, true, "key was locally invalidated"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.DESTROY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.DESTROY))) { // this key was destroyed checkContainsKey(key, false, "key was destroyed"); checkContainsValueForKey(key, false, "key was destroyed"); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.LOCAL_DESTROY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.LOCAL_DESTROY))) { // this key was locally destroyed checkContainsKey(key, true, "key was locally destroyed"); checkContainsValueForKey(key, true, "key was locally destroyed"); Object value = aRegion.get(key); checkValue(key, value); } else if ((verifyRegionContentsIndex >= keyIntervals.getFirstKey(KeyIntervals.UPDATE_EXISTING_KEY)) && (verifyRegionContentsIndex <= keyIntervals.getLastKey(KeyIntervals.UPDATE_EXISTING_KEY))) { // this key was updated checkContainsKey(key, true, "key was updated"); checkContainsValueForKey(key, true, "key was updated"); Object value = aRegion.get(key); checkUpdatedValue(key, value); } else if (verifyRegionContentsIndex > keyIntervals.getNumKeys()) { // key was newly added checkContainsKey(key, true, "key was new"); checkContainsValueForKey(key, true, "key was new"); Object value = aRegion.get(key); checkValue(key, value); } } catch (TestException e) { Log.getLogWriter().info(TestHelper.getStackTrace(e)); verifyRegionContentsErrStr.append(e.getMessage() + "\n"); } if (System.currentTimeMillis() - lastLogTime > LOG_INTERVAL_MILLIS) { Log.getLogWriter() .info("Verified key " + verifyRegionContentsIndex + " out of " + totalNumKeys); lastLogTime = System.currentTimeMillis(); } if (System.currentTimeMillis() - startTime >= minTaskGranularityMS) { Log.getLogWriter() .info( "In HydraTask_verifyRegionContents, returning before completing verify " + "because of task granularity (this task must be batched to complete); last key verified is " + key); return; // task is batched; we are done with this batch } } verifyRegionContentsCompleted = true; if (verifyRegionContentsErrStr.length() > 0) { throw new TestException(verifyRegionContentsErrStr.toString()); } String aStr = "In HydraTask_verifyRegionContents, verified " + verifyRegionContentsIndex + " keys/values"; Log.getLogWriter().info(aStr); throw new StopSchedulingTaskOnClientOrder(aStr); }
/** * Tests that we are in {@link GemFireHealth#OKAY_HEALTH okay} health if cache loads take too * long. * * @see CacheHealthEvaluator#checkLoadTime */ public void testCheckLoadTime() throws CacheException { Cache cache = CacheFactory.create(this.system); CachePerfStats stats = ((GemFireCacheImpl) cache).getCachePerfStats(); AttributesFactory factory = new AttributesFactory(); factory.setScope(Scope.LOCAL); factory.setCacheLoader( new CacheLoader() { public Object load(LoaderHelper helper) throws CacheLoaderException { return "Loaded"; } public void close() {} }); RegionAttributes attrs = factory.create(); Region region = cache.createRegion(this.getName(), attrs); GemFireHealthConfig config = new GemFireHealthConfigImpl(null); config.setMaxLoadTime(100); CacheHealthEvaluator eval = new CacheHealthEvaluator(config, this.system.getDistributionManager()); for (int i = 0; i < 10; i++) { region.get("Test1 " + i); } long firstLoadTime = stats.getLoadTime(); long firstLoadsCompleted = stats.getLoadsCompleted(); assertTrue(firstLoadTime >= 0); assertTrue(firstLoadsCompleted > 0); // First time should always be empty List status = new ArrayList(); eval.evaluate(status); assertEquals(0, status.size()); config = new GemFireHealthConfigImpl(null); config.setMaxLoadTime(10); eval = new CacheHealthEvaluator(config, this.system.getDistributionManager()); eval.evaluate(status); long start = System.currentTimeMillis(); for (int i = 0; i < 100; i++) { region.get("Test2 " + i); } assertTrue(System.currentTimeMillis() - start < 1000); long secondLoadTime = stats.getLoadTime(); long secondLoadsCompleted = stats.getLoadsCompleted(); assertTrue( "firstLoadTime=" + firstLoadTime + ", secondLoadTime=" + secondLoadTime, secondLoadTime >= firstLoadTime); assertTrue(secondLoadsCompleted > firstLoadsCompleted); // Averge should be less than 10 milliseconds status = new ArrayList(); eval.evaluate(status); assertEquals(0, status.size()); region .getAttributesMutator() .setCacheLoader( new CacheLoader() { public Object load(LoaderHelper helper) throws CacheLoaderException { try { Thread.sleep(20); } catch (InterruptedException ex) { fail("Why was I interrupted?"); } return "Loaded"; } public void close() {} }); for (int i = 0; i < 50; i++) { region.get("Test3 " + i); } long thirdLoadTime = stats.getLoadTime(); long thirdLoadsCompleted = stats.getLoadsCompleted(); assertTrue(thirdLoadTime > secondLoadTime); assertTrue(thirdLoadsCompleted > secondLoadsCompleted); status = new ArrayList(); eval.evaluate(status); assertEquals(1, status.size()); AbstractHealthEvaluator.HealthStatus ill = (AbstractHealthEvaluator.HealthStatus) status.get(0); assertEquals(GemFireHealth.OKAY_HEALTH, ill.getHealthCode()); String s = "The average duration of a Cache load"; assertTrue(ill.getDiagnosis().indexOf(s) != -1); }