2020-04-12 17:15:03 +02:00
|
|
|
package inomap
|
2019-11-16 21:35:26 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestTranslate(t *testing.T) {
|
2020-04-19 21:57:53 +02:00
|
|
|
m := New()
|
|
|
|
q := QIno{Ino: 1}
|
2019-11-16 21:35:26 +01:00
|
|
|
out := m.Translate(q)
|
|
|
|
if out != 1 {
|
|
|
|
t.Errorf("expected 1, got %d", out)
|
|
|
|
}
|
2020-04-19 21:57:53 +02:00
|
|
|
q.Ino = maxPassthruIno
|
2019-11-16 21:35:26 +01:00
|
|
|
out = m.Translate(q)
|
2020-04-19 21:57:53 +02:00
|
|
|
if out < maxPassthruIno {
|
2019-11-16 21:35:26 +01:00
|
|
|
t.Errorf("got %d", out)
|
|
|
|
}
|
|
|
|
out2 := m.Translate(q)
|
|
|
|
if out2 != out {
|
|
|
|
t.Errorf("unstable mapping: %d %d", out2, out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTranslateStress(t *testing.T) {
|
|
|
|
const baseDev = 12345
|
2020-04-19 21:57:53 +02:00
|
|
|
m := New()
|
|
|
|
|
|
|
|
// Make sure baseDev gets namespace id zero
|
|
|
|
var q QIno
|
|
|
|
q.Dev = baseDev
|
|
|
|
m.Translate(q)
|
|
|
|
|
2019-11-16 21:35:26 +01:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
wg.Add(4)
|
|
|
|
go func() {
|
2020-04-19 21:57:53 +02:00
|
|
|
// Some normal inode numbers on baseDev
|
|
|
|
var q QIno
|
|
|
|
q.Dev = baseDev
|
2019-11-16 21:35:26 +01:00
|
|
|
for i := uint64(1); i <= 10000; i++ {
|
|
|
|
q.Ino = i
|
|
|
|
out := m.Translate(q)
|
|
|
|
if out != i {
|
2020-04-19 21:57:53 +02:00
|
|
|
t.Errorf("i=%d out=%d", i, out)
|
|
|
|
break
|
2019-11-16 21:35:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
go func() {
|
2020-04-19 21:57:53 +02:00
|
|
|
// Very high (>maxPassthruIno) inode numbers on baseDev
|
|
|
|
var q QIno
|
|
|
|
q.Dev = baseDev
|
2019-11-16 21:35:26 +01:00
|
|
|
for i := uint64(1); i <= 10000; i++ {
|
2020-04-19 21:57:53 +02:00
|
|
|
q.Ino = maxPassthruIno + i
|
2019-11-16 21:35:26 +01:00
|
|
|
out := m.Translate(q)
|
2020-04-19 21:57:53 +02:00
|
|
|
if out < maxPassthruIno {
|
|
|
|
t.Errorf("out=%d", out)
|
|
|
|
break
|
2019-11-16 21:35:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
go func() {
|
2020-04-19 21:57:53 +02:00
|
|
|
// Device 9999999
|
|
|
|
var q QIno
|
|
|
|
q.Dev = 9999999
|
2019-11-16 21:35:26 +01:00
|
|
|
for i := uint64(1); i <= 10000; i++ {
|
|
|
|
q.Ino = i
|
|
|
|
out := m.Translate(q)
|
2020-04-19 21:57:53 +02:00
|
|
|
if out < maxPassthruIno {
|
|
|
|
t.Errorf("out=%d", out)
|
|
|
|
break
|
2019-11-16 21:35:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
go func() {
|
2020-04-19 21:57:53 +02:00
|
|
|
// Device 4444444
|
|
|
|
var q QIno
|
|
|
|
q.Dev = 4444444
|
2019-11-16 21:35:26 +01:00
|
|
|
for i := uint64(1); i <= 10000; i++ {
|
|
|
|
q.Ino = i
|
|
|
|
out := m.Translate(q)
|
2020-04-19 21:57:53 +02:00
|
|
|
if out < maxPassthruIno {
|
|
|
|
t.Errorf("out=%d", out)
|
|
|
|
break
|
2019-11-16 21:35:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
wg.Wait()
|
2020-04-19 21:57:53 +02:00
|
|
|
if len(m.spillMap) != 10000 {
|
|
|
|
t.Errorf("len=%d", len(m.spillMap))
|
|
|
|
}
|
|
|
|
if len(m.namespaceMap) != 3 {
|
|
|
|
t.Errorf("len=%d", len(m.namespaceMap))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 20:21:11 +02:00
|
|
|
func TestSpill(t *testing.T) {
|
|
|
|
m := New()
|
|
|
|
var q QIno
|
|
|
|
q.Ino = maxPassthruIno + 1
|
|
|
|
out1 := m.Translate(q)
|
2020-05-03 20:28:26 +02:00
|
|
|
if out1&spillBit == 0 {
|
2020-05-03 20:21:11 +02:00
|
|
|
t.Error("spill bit not set")
|
|
|
|
}
|
|
|
|
out2 := m.Translate(q)
|
2020-05-03 20:28:26 +02:00
|
|
|
if out2&spillBit == 0 {
|
2020-05-03 20:21:11 +02:00
|
|
|
t.Error("spill bit not set")
|
|
|
|
}
|
|
|
|
if out1 != out2 {
|
|
|
|
t.Errorf("unstable mapping: %d vs %d", out1, out2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-19 21:57:53 +02:00
|
|
|
// TestUniqueness checks that unique (Dev, Flags, Ino) tuples get unique inode
|
|
|
|
// numbers
|
|
|
|
func TestUniqueness(t *testing.T) {
|
|
|
|
m := New()
|
|
|
|
var q QIno
|
|
|
|
outMap := make(map[uint64]struct{})
|
|
|
|
for q.Dev = 0; q.Dev < 10; q.Dev++ {
|
2020-05-03 15:22:10 +02:00
|
|
|
for q.Tag = 0; q.Tag < 10; q.Tag++ {
|
2020-04-19 21:57:53 +02:00
|
|
|
// some go into spill
|
|
|
|
for q.Ino = maxPassthruIno - 100; q.Ino < maxPassthruIno+100; q.Ino++ {
|
|
|
|
out := m.Translate(q)
|
|
|
|
_, found := outMap[out]
|
|
|
|
if found {
|
|
|
|
t.Fatalf("inode number %d already used", out)
|
|
|
|
}
|
|
|
|
outMap[out] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(outMap) != 10*10*200 {
|
|
|
|
t.Errorf("%d", len(outMap))
|
2019-11-16 21:35:26 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-19 21:34:45 +02:00
|
|
|
|
|
|
|
func BenchmarkTranslateSingleDev(b *testing.B) {
|
2020-04-19 21:57:53 +02:00
|
|
|
m := New()
|
2020-04-19 21:34:45 +02:00
|
|
|
var q QIno
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
q.Ino = uint64(n % 1000)
|
|
|
|
m.Translate(q)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkTranslateManyDevs(b *testing.B) {
|
2020-04-19 21:57:53 +02:00
|
|
|
m := New()
|
2020-04-19 21:34:45 +02:00
|
|
|
var q QIno
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
q.Dev = uint64(n % 10)
|
|
|
|
q.Ino = uint64(n % 1000)
|
|
|
|
m.Translate(q)
|
|
|
|
}
|
|
|
|
}
|