/* * Copyright 2017-present 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.buck.rules.keys; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import com.facebook.buck.io.ProjectFilesystem; import com.facebook.buck.rules.FakeBuildRuleParamsBuilder; import com.facebook.buck.rules.NoopBuildRule; import com.facebook.buck.testutil.FakeProjectFilesystem; import com.facebook.buck.timing.Clock; import com.facebook.buck.timing.IncrementingFakeClock; import com.google.common.collect.ImmutableList; import org.hamcrest.Matchers; import org.junit.Test; public class DefaultRuleKeyCacheTest { private static final ProjectFilesystem FILESYSTEM = new FakeProjectFilesystem(); @Test public void testGetReturnValue() { DefaultRuleKeyCache<String> cache = new DefaultRuleKeyCache<>(); TestRule rule = new TestRule(); assertThat( cache.get(rule, r -> new RuleKeyResult<>("result", ImmutableList.of(), ImmutableList.of())), Matchers.equalTo("result")); } @Test public void testCacheRule() { DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(); TestRule rule = new TestRule(); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of())); assertTrue(cache.isCached(rule)); cache.get( rule, r -> { throw new IllegalStateException(); }); } @Test public void testInvalidateInputToCachedRule() { DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(); TestRule rule = new TestRule(); RuleKeyInput input = RuleKeyInput.of(FILESYSTEM, FILESYSTEM.getPath("input")); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of(input))); assertTrue(cache.isCached(rule)); cache.invalidateInputs(ImmutableList.of(input)); assertFalse(cache.isCached(rule)); } @Test public void testInvalidateTransitiveInputToCachedRule() { DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(); RuleKeyInput input = RuleKeyInput.of(FILESYSTEM, FILESYSTEM.getPath("input")); TestRule dep = new TestRule(); cache.get(dep, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of(input))); TestRule rule = new TestRule(); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(dep), ImmutableList.of())); assertTrue(cache.isCached(rule)); assertTrue(cache.isCached(dep)); cache.invalidateInputs(ImmutableList.of(input)); assertFalse(cache.isCached(rule)); assertFalse(cache.isCached(dep)); } @Test public void testInvalidateInputToCachedRuleDoesNotInvalidateDependency() { DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(); RuleKeyInput input = RuleKeyInput.of(FILESYSTEM, FILESYSTEM.getPath("input")); TestRule dep = new TestRule(); cache.get(dep, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of())); TestRule rule = new TestRule(); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(dep), ImmutableList.of(input))); assertTrue(cache.isCached(rule)); assertTrue(cache.isCached(dep)); cache.invalidateInputs(ImmutableList.of(input)); assertFalse(cache.isCached(rule)); assertTrue(cache.isCached(dep)); } @Test public void testHitMissStats() { DefaultRuleKeyCache<String> cache = new DefaultRuleKeyCache<>(); TestRule rule = new TestRule(); cache.get(rule, r -> new RuleKeyResult<>("result", ImmutableList.of(), ImmutableList.of())); cache.get(rule, r -> new RuleKeyResult<>("result", ImmutableList.of(), ImmutableList.of())); cache.get(rule, r -> new RuleKeyResult<>("result", ImmutableList.of(), ImmutableList.of())); assertThat(cache.getStats().missCount(), Matchers.equalTo(1L)); assertThat(cache.getStats().hitCount(), Matchers.equalTo(2L)); } @Test public void testEvictionStats() { DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(); TestRule rule = new TestRule(); RuleKeyInput input = RuleKeyInput.of(FILESYSTEM, FILESYSTEM.getPath("input")); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of(input))); cache.invalidateInputs(ImmutableList.of(input)); assertThat(cache.getStats().evictionCount(), Matchers.equalTo(1L)); } @Test public void testLoadTime() { Clock clock = new IncrementingFakeClock(); DefaultRuleKeyCache<Void> cache = new DefaultRuleKeyCache<>(clock); TestRule rule = new TestRule(); RuleKeyInput input = RuleKeyInput.of(FILESYSTEM, FILESYSTEM.getPath("input")); cache.get(rule, r -> new RuleKeyResult<>(null, ImmutableList.of(), ImmutableList.of(input))); cache.invalidateInputs(ImmutableList.of(input)); assertThat(cache.getStats().totalLoadTime(), Matchers.equalTo(1L)); } private static class TestRule extends NoopBuildRule { private TestRule() { super(new FakeBuildRuleParamsBuilder("//:rule").build()); } } }