Package com.facebook.concurrency

Source Code of com.facebook.concurrency.TestExpiringConcurrentCache

/*
* Copyright (C) 2012 Facebook, Inc.
*
* 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.
*/
package com.facebook.concurrency;

import com.facebook.collections.Pair;
import com.facebook.testing.MockExecutor;
import org.joda.time.DateTimeUtils;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class TestExpiringConcurrentCache {
  private ExpiringConcurrentCache<String, ReapableString, RuntimeException> legacyCache;
  private static final String KEY = "key";
  private ReapableString reapableValue1;
  private String value1;
  private BlockingValueProducer<ReapableString, RuntimeException> producer;
  private ConcurrentCacheTestHelper<String, ReapableString> testHelper;
  private MockExecutor mockExecutor;
  private ExpiringConcurrentCache<String, String, RuntimeException> cache;
  private List<Pair<String,String>> evicted;

  @BeforeMethod(alwaysRun = true)
  public void setUp() throws Exception {
    value1 = "value1";
    reapableValue1 = new ReapableString(value1);
    producer =
      new BlockingValueProducer<ReapableString, RuntimeException>(reapableValue1);
    mockExecutor = new MockExecutor();
    // arbitrary time for now
    DateTimeUtils.setCurrentMillisFixed(0);   
    legacyCache = ExpiringConcurrentCache.createWithReapableValue(
      new ValueFactory<String, ReapableString, RuntimeException>() {
        @Override
        public ReapableString create(String input) throws RuntimeException {
          return producer.call();
        }
      },
      30,
      TimeUnit.MILLISECONDS,
      RuntimeExceptionHandler.INSTANCE,
      mockExecutor
    );
    evicted = new ArrayList<Pair<String, String>>();
    cache = new ExpiringConcurrentCache<String, String, RuntimeException>(
      new ValueFactory<String, String, RuntimeException>() {
        @Override
        public String create(String input) throws RuntimeException {
          return producer.call().toString();
        }
      },
      30,
      TimeUnit.MILLISECONDS,
      new EvictionListener<String, String>() {
        @Override
        public void evicted(String key, String value) {
          evicted.add(new Pair<String, String>(key, value));
        }
      },
      RuntimeExceptionHandler.INSTANCE,
      mockExecutor
    );
    testHelper = new ConcurrentCacheTestHelper<String, ReapableString>(
      legacyCache
    );
  }

  @Test(groups = "fast")
  public void testExpiration() throws Exception {
    // add a value to the cache
    Assert.assertEquals(legacyCache.get(KEY), reapableValue1);
    Assert.assertEquals(producer.getCalledCount(), 1);
    // advance time to close to the expiration
    DateTimeUtils.setCurrentMillisFixed(29);       
    // still in cache
    Assert.assertTrue(legacyCache.getIfPresent(KEY) != null, "key should be in cache");
    // now 30ms passed, should expire
    DateTimeUtils.setCurrentMillisFixed(30);   
    Assert.assertFalse(legacyCache.getIfPresent(KEY) != null, "key should NOT be in cache");
    mockExecutor.drain();
    // and value1.shutdown was called
    Assert.assertEquals(reapableValue1.getShutdownCalled(), 1);
  }
 
  @Test(groups = "fast")
  public void testEvictionListener() throws Exception {
    // add a value to the cache
    Assert.assertEquals(cache.get(KEY), value1);
    Assert.assertEquals(producer.getCalledCount(), 1);
    DateTimeUtils.setCurrentMillisFixed(30);
    cache.prune();
    // key is removed from the cache
    Assert.assertEquals(cache.size(), 0);
    // and this will execute the eviction callback
    mockExecutor.drain();
    Assert.assertEquals(evicted.size(), 1);
   
  }
 
  @AfterMethod(alwaysRun = true)
  public void tearDown() throws Exception {
    DateTimeUtils.setCurrentMillisSystem()
  }

  private static class ReapableString implements Reapable<RuntimeException>{
    private final String value;
    private final AtomicLong shutdownCalled = new AtomicLong(0);

    private ReapableString(String value) {
      this.value = value;
    }

    @Override
    public void shutdown() throws RuntimeException {
      shutdownCalled.incrementAndGet();
    }

    public long getShutdownCalled() {
      return shutdownCalled.get();
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      final ReapableString that = (ReapableString) o;

      if (value != null ? !value.equals(that.value) : that.value != null) {
        return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return value != null ? value.hashCode() : 0;
    }

    @Override
    public String toString() {
      return value;
    }
  }
}
TOP

Related Classes of com.facebook.concurrency.TestExpiringConcurrentCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.