blob: 5053ade4ec7f36a30cab4860b38b96b2cee57a5d [file] [log] [blame]
/*
* Copyright 2012-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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.util.FileHashCache;
import com.facebook.buck.util.NullFileHashCache;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
public class DirArtifactCacheTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
private FileHashCache fileHashCache = new NullFileHashCache();
@Test
public void testCacheCreation() throws IOException {
File cacheDir = tmpDir.newFolder();
new DirArtifactCache(cacheDir, /* maxCacheSizeBytes */ Optional.of(0L));
}
@Test
public void testCacheFetchMiss() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = tmpDir.newFile("x");
DirArtifactCache dirArtifactCache = new DirArtifactCache(cacheDir,
/* maxCacheSizeBytes */ Optional.of(0L));
Files.write("x", fileX, Charsets.UTF_8);
BuildRule inputRuleX = new BuildRuleForTest(fileX);
RuleKey ruleKeyX = RuleKey.builder(inputRuleX,
fileHashCache).build().getTotalRuleKey();
assertEquals(CacheResult.MISS, dirArtifactCache.fetch(ruleKeyX, fileX));
}
@Test
public void testCacheStoreAndFetchHit() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = tmpDir.newFile("x");
DirArtifactCache dirArtifactCache = new DirArtifactCache(cacheDir,
/* maxCacheSizeBytes */ Optional.<Long>absent());
Files.write("x", fileX, Charsets.UTF_8);
BuildRule inputRuleX = new BuildRuleForTest(fileX);
RuleKey ruleKeyX = RuleKey.builder(inputRuleX, fileHashCache).build().getTotalRuleKey();
dirArtifactCache.store(ruleKeyX, fileX);
// Test that artifact overwrite works.
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyX, fileX));
assertEquals(inputRuleX, new BuildRuleForTest(fileX));
// Test that artifact creation works.
assertTrue(fileX.delete());
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyX, fileX));
assertEquals(inputRuleX, new BuildRuleForTest(fileX));
}
@Test
public void testCacheStoreOverwrite() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = tmpDir.newFile("x");
DirArtifactCache dirArtifactCache = new DirArtifactCache(cacheDir,
/* maxCacheSizeBytes */ Optional.of(0L));
Files.write("x", fileX, Charsets.UTF_8);
BuildRule inputRuleX = new BuildRuleForTest(fileX);
RuleKey ruleKeyX = RuleKey.builder(inputRuleX, fileHashCache).build().getTotalRuleKey();
dirArtifactCache.store(ruleKeyX, fileX);
dirArtifactCache.store(ruleKeyX, fileX); // Overwrite.
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyX, fileX));
assertEquals(inputRuleX, new BuildRuleForTest(fileX));
}
@Test
public void testCacheStoresAndFetchHits() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = tmpDir.newFile("x");
File fileY = tmpDir.newFile("y");
File fileZ = tmpDir.newFile("z");
DirArtifactCache dirArtifactCache = new DirArtifactCache(cacheDir,
/* maxCacheSizeBytes */ Optional.of(0L));
Files.write("x", fileX, Charsets.UTF_8);
Files.write("y", fileY, Charsets.UTF_8);
Files.write("z", fileZ, Charsets.UTF_8);
BuildRule inputRuleX = new BuildRuleForTest(fileX);
BuildRule inputRuleY = new BuildRuleForTest(fileY);
BuildRule inputRuleZ = new BuildRuleForTest(fileZ);
assertFalse(inputRuleX.equals(inputRuleY));
assertFalse(inputRuleX.equals(inputRuleZ));
assertFalse(inputRuleY.equals(inputRuleZ));
RuleKey ruleKeyX = RuleKey.builder(inputRuleX, fileHashCache).build().getTotalRuleKey();
RuleKey ruleKeyY = RuleKey.builder(inputRuleY, fileHashCache).build().getTotalRuleKey();
RuleKey ruleKeyZ = RuleKey.builder(inputRuleZ, fileHashCache).build().getTotalRuleKey();
assertEquals(CacheResult.MISS, dirArtifactCache.fetch(ruleKeyX, fileX));
assertEquals(CacheResult.MISS, dirArtifactCache.fetch(ruleKeyY, fileY));
assertEquals(CacheResult.MISS, dirArtifactCache.fetch(ruleKeyZ, fileZ));
dirArtifactCache.store(ruleKeyX, fileX);
dirArtifactCache.store(ruleKeyY, fileY);
dirArtifactCache.store(ruleKeyZ, fileZ);
assertTrue(fileX.delete());
assertTrue(fileY.delete());
assertTrue(fileZ.delete());
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyX, fileX));
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyY, fileY));
assertEquals(CacheResult.DIR_HIT, dirArtifactCache.fetch(ruleKeyZ, fileZ));
assertEquals(inputRuleX, new BuildRuleForTest(fileX));
assertEquals(inputRuleY, new BuildRuleForTest(fileY));
assertEquals(inputRuleZ, new BuildRuleForTest(fileZ));
assertEquals(3, cacheDir.listFiles().length);
dirArtifactCache.deleteOldFiles();
assertEquals(0, cacheDir.listFiles().length);
}
@Test
public void testDeleteNothing() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = new File(cacheDir, "x");
File fileY = new File(cacheDir, "y");
File fileZ = new File(cacheDir, "z");
DirArtifactCache dirArtifactCache = new DirArtifactCache(tmpDir.getRoot(),
/* maxCacheSizeBytes */ Optional.of(1024L));
Files.write("x", fileX, Charsets.UTF_8);
Files.write("y", fileY, Charsets.UTF_8);
Files.write("z", fileZ, Charsets.UTF_8);
assertEquals(3, cacheDir.listFiles().length);
dirArtifactCache.deleteOldFiles();
assertEquals(3, cacheDir.listFiles().length);
}
@Test
public void testDeleteNothingAbsentLimit() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileX = new File(cacheDir, "x");
File fileY = new File(cacheDir, "y");
File fileZ = new File(cacheDir, "z");
DirArtifactCache dirArtifactCache = new DirArtifactCache(tmpDir.getRoot(),
/* maxCacheSizeBytes */ Optional.<Long>absent());
Files.write("x", fileX, Charsets.UTF_8);
Files.write("y", fileY, Charsets.UTF_8);
Files.write("z", fileZ, Charsets.UTF_8);
assertEquals(3, cacheDir.listFiles().length);
dirArtifactCache.deleteOldFiles();
assertEquals(3, cacheDir.listFiles().length);
}
@Test
public void testDeleteSome() throws IOException {
File cacheDir = tmpDir.newFolder();
File fileW = new File(cacheDir, "w");
File fileX = new File(cacheDir, "x");
File fileY = new File(cacheDir, "y");
File fileZ = new File(cacheDir, "z");
DirArtifactCache dirArtifactCache = new DirArtifactCache(cacheDir,
/* maxCacheSizeBytes */ Optional.of(2L));
Files.write("w", fileW, Charsets.UTF_8);
Files.write("x", fileX, Charsets.UTF_8);
Files.write("y", fileY, Charsets.UTF_8);
Files.write("z", fileZ, Charsets.UTF_8);
java.nio.file.Files.setAttribute(fileW.toPath(), "lastAccessTime", FileTime.fromMillis(9000));
java.nio.file.Files.setAttribute(fileX.toPath(), "lastAccessTime", FileTime.fromMillis(0));
java.nio.file.Files.setAttribute(fileY.toPath(), "lastAccessTime", FileTime.fromMillis(1000));
java.nio.file.Files.setAttribute(fileZ.toPath(), "lastAccessTime", FileTime.fromMillis(2000));
assertEquals(4, cacheDir.listFiles().length);
dirArtifactCache.deleteOldFiles();
assertEquals(ImmutableSet.of(fileZ, fileW), ImmutableSet.copyOf(cacheDir.listFiles()));
}
private static class BuildRuleForTest extends FakeBuildRule {
private static final BuildRuleType TYPE = new BuildRuleType("fake");
private final File file;
private BuildRuleForTest(File file) {
super(TYPE, new BuildTarget("//foo", file.getName()));
this.file = Preconditions.checkNotNull(file);
}
@Override
public Iterable<Path> getInputs() {
return ImmutableList.of(file.toPath());
}
}
}