All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.internal.cache.Bug37500JUnitTest Maven / Gradle / Ivy

There is a newer version: 2.0-BETA
Show newest version
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.internal.cache;

import com.gemstone.gemfire.cache.Scope;

import java.io.File;

/**
 * This is a bugtest for bug 37500.
 * 
 * @author Dinesh Patel
 * @author Mitul Bid
 * 
 */
public class Bug37500JUnitTest extends DiskRegionTestingBase
{

  /** The disk region configuration object for the test */
  private DiskRegionProperties diskProps = new DiskRegionProperties();

  /** The key for entry1 */
  static final String KEY1 = "KEY1";

  /** The key for entry2 */
  static final String KEY2 = "KEY2";

  /** Boolean to indicate the roller thread to proceed */
  static volatile boolean proceedForRolling = false;

  /**
   * Boolean to decide whether we want to allow roller to run ( used via
   * CacheObserver callback
   */
  static volatile boolean notifyRoller = false;

  /**
   * Constructor
   * 
   * @param name -
   *                Name of the test instance
   */
  public Bug37500JUnitTest(String name) {
    super(name);
  }

  /**
   * This test does the following: 
* 1. Create a disk-region with following configurations : *
  • dirSize = 2000 bytes *
  • maxOplogSize = 500 bytes *
  • rolling = true *
  • syncMode = true *
  • approx size on disk for operations = 440 bytes
    * * 2.Make Roller go into WAIT state via CacheObserverAdapter.beforeGoingToCompact * callback
    * 3.Put 440 bytes , it will go in oplog1
    * 4.Put another 440 bytes ,it will go in oplog1
    * 5.Put 440 bytes , switching will be caused, it will go in oplog2, Roller * will remained blocked (step 2)
    * 6.Put 440 bytes , it will go in oplog2, oplog2 will now be full
    * 7.Notify the Roller and put 440 bytes , this will try further switching. * The put will fail with exception due to bug 37500. The put thread takes an * entry level lock for entry2 ( the one with KEY2) and tries to write to disk * but there is no free space left, so it goes into wait, expecting Roller to * free up the space. The roller, which has now been notified to run, tries to * roll entry2 for which it seeks entry level lock which has been acquired by * put-thread. So the put thread eventually comes out of the wait with * DiskAccessException
    * * Another scenario for this bug is, once the disk space was getting exhausted , * the entry operation threads which had already taken a lock on Entry got * stuck trying to seek the Oplog Lock. The switching thread had acquired the * Oplog.lock & was waiting for the roller thread to free disk space. Since * the roller needed to acquire Entry lock to roll, it was unable to do so * because of entry operation threads. This would cause the entry operation * threads to get DiskAccessException after completing the stipulated wait. * The Roller was able to free space only when it has rolled all the relevant * entries which could happen only when the entry operation threads released * the entry lock after getting DiskAccessException. * * * @throws Exception */ public void testBug37500() throws Exception { final int MAX_OPLOG_SIZE = 1000; diskProps.setMaxOplogSize(MAX_OPLOG_SIZE); diskProps.setPersistBackup(true); diskProps.setRolling(true); diskProps.setSynchronous(false); File testdir = new File("bug37500-diskDir"); testdir.mkdir(); testdir.deleteOnExit(); diskProps.setDiskDirsAndSizes(new File[] { testdir }, new int[] { 2000 }); LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = true; region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); CacheObserver old = CacheObserverHolder .setInstance(new CacheObserverAdapter() { public void beforeGoingToCompact() { if (!proceedForRolling) { synchronized (Bug37500JUnitTest.class) { if (!proceedForRolling) { try { cache.getLogger().info( "beforeGoingToCompact :: going into wait"); Bug37500JUnitTest.class.wait(); } catch (InterruptedException e) { cache.getLogger().info("Roller interrupted"); fail("interrupted"); } cache.getLogger().info( "beforeGoingToCompact :: coming out of wait"); } } } } public void beforeSwitchingOplog() { if (notifyRoller) { cache.getLogger().info( "beforeSwitchingOplog :: going to notify Roller"); synchronized (Bug37500JUnitTest.class) { proceedForRolling = true; Bug37500JUnitTest.class.notify(); cache.getLogger().info( "beforeSwitchingOplog :: notified the Roller"); } } } }); cache.getLogger().info("goin to put no. 1"); // put 440 bytes , it will go in oplog1 region.put(KEY1, new byte[420]); cache.getLogger().info("goin to put no. 2"); // put another 440 bytes ,it will go in oplog1 region.put(KEY2, new byte[420]); cache.getLogger().info("goin to put no. 3"); // put 440 bytes , switching will be caused, it will go in oplog2 (value // size increased to 432 as key wont be written to disk for UPDATE) region.put(KEY1, new byte[432]); cache.getLogger().info("goin to put no. 4"); // put 440 bytes , it will go in oplog2 region.put(KEY1, new byte[432]); notifyRoller = true; cache.getLogger().info("goin to put no. 5"); // put 440 bytes , this will try further switching region.put(KEY2, new byte[432]); LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false; CacheObserverHolder.setInstance(old); closeDown(); } }




  • © 2015 - 2024 Weber Informatics LLC | Privacy Policy