// Copyright 2019 The Nomulus Authors. 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.
package google.registry.testing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import google.registry.model.EppResource;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.registry.label.PremiumList;
import java.util.Map;
import java.util.Optional;
import org.joda.time.Duration;
import org.junit.rules.ExternalResource;
/**
* Sets up caches with desired data expiry for testing and restores their default configurations
* when tests complete.
*
*
This rule is necessary because many caches in the system are singleton and referenced through
* static fields.
*/
public class TestCacheRule extends ExternalResource {
private final ImmutableList cacheHandlers;
private TestCacheRule(ImmutableList cacheHandlers) {
this.cacheHandlers = cacheHandlers;
}
@Override
protected void before() {
cacheHandlers.forEach(TestCacheHandler::before);
}
@Override
protected void after() {
cacheHandlers.forEach(TestCacheHandler::after);
}
/** Builder for {@link TestCacheRule}. */
public static class Builder {
private final Map cacheHandlerMap = Maps.newHashMap();
public Builder withEppResourceCache(Duration expiry) {
cacheHandlerMap.put(
"EppResource.cacheEppResources",
new TestCacheHandler(EppResource::setCacheForTest, expiry));
return this;
}
public Builder withForeignIndexKeyCache(Duration expiry) {
cacheHandlerMap.put(
"ForeignKeyIndex.cacheForeignKeyIndexes",
new TestCacheHandler(ForeignKeyIndex::setCacheForTest, expiry));
return this;
}
public Builder withPremiumListsCache(Duration expiry) {
cacheHandlerMap.put(
"PremiumList.cachePremiumLists",
new TestCacheHandler(PremiumList::setPremiumListCacheForTest, expiry));
return this;
}
public Builder withPremiumListEntriesCache(Duration expiry) {
cacheHandlerMap.put(
"PremiumList.cachePremiumListEntries",
new TestCacheHandler(PremiumList::setPremiumListEntriesCacheForTest, expiry));
return this;
}
public TestCacheRule build() {
TestCacheRule rule = new TestCacheRule(ImmutableList.copyOf(cacheHandlerMap.values()));
return rule;
}
}
static class TestCacheHandler {
private final TestCacheSetter setter;
private final Duration testExpiry;
private TestCacheHandler(TestCacheSetter setter, Duration testExpiry) {
this.setter = setter;
this.testExpiry = testExpiry;
}
void before() {
setter.setCache(Optional.of(testExpiry));
}
void after() {
setter.setCache(Optional.empty());
}
}
@FunctionalInterface
interface TestCacheSetter {
/**
* Creates a new cache for use during tests.
*
* @param expiry expiry for the test cache. If not present, use default setting
*/
void setCache(Optional expiry);
}
}