212 lines
5.1 KiB
Go
212 lines
5.1 KiB
Go
|
package solver
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func checkEmpty(t *testing.T, ei *edgeIndex) {
|
||
|
require.Equal(t, len(ei.items), 0)
|
||
|
require.Equal(t, len(ei.backRefs), 0)
|
||
|
}
|
||
|
|
||
|
func TestIndexSimple(t *testing.T) {
|
||
|
idx := newEdgeIndex()
|
||
|
|
||
|
e1 := &edge{}
|
||
|
e2 := &edge{}
|
||
|
e3 := &edge{}
|
||
|
|
||
|
k1 := NewCacheKey(dgst("foo"), 0)
|
||
|
v := idx.LoadOrStore(k1, e1)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
k2 := NewCacheKey(dgst("bar"), 0)
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
v = idx.LoadOrStore(NewCacheKey(dgst("bar"), 0), e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
v = idx.LoadOrStore(NewCacheKey(dgst("bar"), 0), e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
v = idx.LoadOrStore(NewCacheKey(dgst("foo"), 0), e3)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
idx.Release(e1)
|
||
|
idx.Release(e2)
|
||
|
checkEmpty(t, idx)
|
||
|
}
|
||
|
|
||
|
func TestIndexMultiLevelSimple(t *testing.T) {
|
||
|
idx := newEdgeIndex()
|
||
|
|
||
|
e1 := &edge{}
|
||
|
e2 := &edge{}
|
||
|
e3 := &edge{}
|
||
|
|
||
|
k1 := testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")}},
|
||
|
})
|
||
|
|
||
|
v := idx.LoadOrStore(k1, e1)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
k2 := testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")}},
|
||
|
})
|
||
|
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, k1.Deps())
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
v = idx.LoadOrStore(k1, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
// update selector
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0))}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
// add one dep to e1
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")},
|
||
|
{CacheKey: expKey(NewCacheKey("s1", 1))},
|
||
|
},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
// recheck with only the new dep key
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("s1", 1))},
|
||
|
},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
// combine e1 and e2
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("s0", 0))},
|
||
|
{CacheKey: expKey(NewCacheKey("s1", 1))},
|
||
|
},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
// initial e2 now points to e1
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0))}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
idx.Release(e1)
|
||
|
|
||
|
// e2 still remains after e1 is gone
|
||
|
k2 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0))}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
idx.Release(e2)
|
||
|
checkEmpty(t, idx)
|
||
|
}
|
||
|
|
||
|
func TestIndexThreeLevels(t *testing.T) {
|
||
|
idx := newEdgeIndex()
|
||
|
|
||
|
e1 := &edge{}
|
||
|
e2 := &edge{}
|
||
|
e3 := &edge{}
|
||
|
|
||
|
k1 := testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")}},
|
||
|
})
|
||
|
|
||
|
v := idx.LoadOrStore(k1, e1)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
v = idx.LoadOrStore(k1, e2)
|
||
|
require.Equal(t, v, e1)
|
||
|
|
||
|
k2 := testCacheKeyWithDeps(dgst("bar"), 0, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(k1)}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
k2 = testCacheKeyWithDeps(dgst("bar"), 0, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{
|
||
|
{CacheKey: expKey(k1)},
|
||
|
{CacheKey: expKey(NewCacheKey("alt", 0))},
|
||
|
},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e2)
|
||
|
require.Nil(t, v)
|
||
|
|
||
|
k2 = testCacheKeyWithDeps(dgst("bar"), 0, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("alt", 0))},
|
||
|
},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
// change dep in a low key
|
||
|
k1 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("f0", 0))},
|
||
|
{CacheKey: expKey(NewCacheKey("f0_", 0))},
|
||
|
},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")}},
|
||
|
})
|
||
|
k2 = testCacheKeyWithDeps(dgst("bar"), 0, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(k1)}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
// reload with only f0_ still matches
|
||
|
k1 = testCacheKeyWithDeps(dgst("foo"), 1, [][]CacheKeyWithSelector{
|
||
|
{
|
||
|
{CacheKey: expKey(NewCacheKey("f0_", 0))},
|
||
|
},
|
||
|
{{CacheKey: expKey(NewCacheKey("s0", 0)), Selector: dgst("s0")}},
|
||
|
})
|
||
|
k2 = testCacheKeyWithDeps(dgst("bar"), 0, [][]CacheKeyWithSelector{
|
||
|
{{CacheKey: expKey(NewCacheKey("f0", 0))}},
|
||
|
{{CacheKey: expKey(k1)}},
|
||
|
})
|
||
|
v = idx.LoadOrStore(k2, e3)
|
||
|
require.Equal(t, v, e2)
|
||
|
|
||
|
idx.Release(e1)
|
||
|
idx.Release(e2)
|
||
|
checkEmpty(t, idx)
|
||
|
}
|