github.phpd.cn/thought-machine/please@v12.2.0+incompatible/src/cache/dir_cache_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"runtime"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  
    14  	"core"
    15  )
    16  
    17  var hash = []byte("12345678901234567890")
    18  var b64Hash = base64.URLEncoding.EncodeToString(hash)
    19  
    20  func writeFile(filename string, size int) {
    21  	contents := bytes.Repeat([]byte{'p', 'l', 'z'}, size) // so this is three times the size...
    22  	if err := os.MkdirAll(path.Dir(filename), core.DirPermissions); err != nil {
    23  		panic(err)
    24  	}
    25  	if err := ioutil.WriteFile(filename, contents, 0644); err != nil {
    26  		panic(err)
    27  	}
    28  }
    29  
    30  func cachePath(target *core.BuildTarget) string {
    31  	return path.Join(".plz-cache-"+target.Label.PackageName, target.Label.PackageName, target.Label.Name, b64Hash, target.Outputs()[0])
    32  }
    33  
    34  func inCache(target *core.BuildTarget) bool {
    35  	dest := cachePath(target)
    36  	log.Debug("Checking for %s", dest)
    37  	return core.PathExists(dest)
    38  }
    39  
    40  func TestStoreAndRetrieve(t *testing.T) {
    41  	cache := makeCache(".plz-cache-test1")
    42  	target := makeTarget("//test1:target1", 20)
    43  	cache.Store(target, hash)
    44  	// Should now exist in cache at this path
    45  	assert.True(t, inCache(target))
    46  	assert.True(t, cache.Retrieve(target, hash))
    47  	// Should be able to store it again without problems
    48  	cache.Store(target, hash)
    49  	assert.True(t, inCache(target))
    50  	assert.True(t, cache.Retrieve(target, hash))
    51  }
    52  
    53  func TestCleanNoop(t *testing.T) {
    54  	cache := makeCache(".plz-cache-test2")
    55  	target1 := makeTarget("//test2:target1", 2000)
    56  	cache.Store(target1, hash)
    57  	assert.True(t, inCache(target1))
    58  	target2 := makeTarget("//test2:target2", 2000)
    59  	cache.Store(target2, hash)
    60  	assert.True(t, inCache(target2))
    61  	// Doesn't clean anything this time because the high water mark is sufficiently high
    62  	totalSize := cache.clean(20000, 1000)
    63  	assert.EqualValues(t, 12000, totalSize)
    64  	assert.True(t, inCache(target1))
    65  	assert.True(t, inCache(target2))
    66  }
    67  
    68  func TestCleanNoop2(t *testing.T) {
    69  	cache := makeCache(".plz-cache-test3")
    70  	target1 := makeTarget("//test3:target1", 2000)
    71  	cache.Store(target1, hash)
    72  	assert.True(t, inCache(target1))
    73  	target2 := makeTarget("//test3:target2", 2000)
    74  	cache.Store(target2, hash)
    75  	assert.True(t, inCache(target2))
    76  	// Doesn't clean anything this time, the high water mark is lower but both targets have
    77  	// just been built.
    78  	totalSize := cache.clean(10000, 1000)
    79  	assert.EqualValues(t, 12000, totalSize)
    80  	assert.True(t, inCache(target1))
    81  	assert.True(t, inCache(target2))
    82  }
    83  
    84  func TestCleanForReal(t *testing.T) {
    85  	cache := makeCache(".plz-cache-test4")
    86  	target1 := makeTarget("//test4:target1", 2000)
    87  	cache.Store(target1, hash)
    88  	assert.True(t, inCache(target1))
    89  	target2 := makeTarget("//test4:target2", 2000)
    90  	writeFile(cachePath(target2), 2000)
    91  	assert.True(t, inCache(target2))
    92  	// This time it should clean target2, because target1 has just been stored
    93  	totalSize := cache.clean(10000, 1000)
    94  	assert.EqualValues(t, 6000, totalSize)
    95  	assert.True(t, inCache(target1))
    96  	assert.False(t, inCache(target2))
    97  }
    98  
    99  func TestCleanForReal2(t *testing.T) {
   100  	cache := makeCache(".plz-cache-test5")
   101  	target1 := makeTarget("//test5:target1", 2000)
   102  	writeFile(cachePath(target1), 2000)
   103  	assert.True(t, inCache(target1))
   104  	target2 := makeTarget("//test5:target2", 2000)
   105  	cache.Store(target2, hash)
   106  	assert.True(t, inCache(target2))
   107  	// This time it should clean target1, because target2 has just been stored
   108  	totalSize := cache.clean(10000, 1000)
   109  	assert.EqualValues(t, 6000, totalSize)
   110  	assert.False(t, inCache(target1))
   111  	assert.True(t, inCache(target2))
   112  }
   113  
   114  func TestCleanForReal3(t *testing.T) {
   115  	t.Skip("Failing on CI, not sure why")
   116  	if runtime.GOOS != "linux" {
   117  		// The various sizes that follow assume specific things about Linux's filesystem
   118  		// (specifically that directories will cost 4k - which might also be ext4 specific?).
   119  		t.Skip("assumes things about Linux's filesystem")
   120  	}
   121  	cache := makeCache(".plz-cache-test6")
   122  	target1 := makeTarget("//test6:target1", 2000)
   123  	writeFile(cachePath(target1), 2000)
   124  	assert.True(t, inCache(target1))
   125  	target2 := makeTarget("//test6:target2", 2000)
   126  	writeFile(cachePath(target2), 2000)
   127  	assert.True(t, inCache(target2))
   128  	// This time it should clean one of the two targets, but it is indeterminate which one.
   129  	// N.B. We allow a bit over the 6k you'd expect - each directory costs 4k as well.
   130  	totalSize := cache.clean(12000, 11000)
   131  	assert.EqualValues(t, 10096, totalSize) // again +4k for a directory
   132  	assert.True(t, inCache(target1) != inCache(target2))
   133  }
   134  
   135  func makeCache(dir string) *dirCache {
   136  	config := core.DefaultConfiguration()
   137  	config.Cache.Dir = dir
   138  	config.Cache.DirClean = false // We will do this explicitly
   139  	return newDirCache(config)
   140  }
   141  
   142  func makeTarget(label string, size int) *core.BuildTarget {
   143  	target := core.NewBuildTarget(core.ParseBuildLabel(label, ""))
   144  	target.AddOutput("test.go")
   145  	writeFile(path.Join("plz-out/gen", target.Label.PackageName, "test.go"), size)
   146  	return target
   147  }