blob: 7e41a07f93ee06e40da2a3064e90c55b915873d2 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal_test
import (
"fmt"
"math/rand"
"sync"
"testing"
"time"
"v.io/v23/naming"
"v.io/v23/verror"
)
func TestConcurrentMountUnmount(t *testing.T) {
rootCtx, _, _, shutdown := initTest()
defer shutdown()
stop, mtAddr, bt, _ := newMT(t, "", rootCtx, nil)
defer stop()
var wg sync.WaitGroup
busyMountUnmount := func(name string) {
defer wg.Done()
for i := 0; i < 250; i++ {
n := fmt.Sprintf("%s/%d", name, rand.Intn(10))
doMount(t, rootCtx, mtAddr, n, "/example.com:12345", true)
if _, err := resolve(rootCtx, naming.JoinAddressName(mtAddr, n)); err != nil {
t.Errorf("resolve(%q) failed: %v", n, err)
}
doUnmount(t, rootCtx, mtAddr, n, "", true)
}
}
for i := 1; i <= 5; i++ {
wg.Add(3)
go busyMountUnmount(fmt.Sprintf("a/%d", i))
go busyMountUnmount(fmt.Sprintf("a/b/%d", i))
go busyMountUnmount(fmt.Sprintf("a/c/d/e/%d", i))
}
wg.Wait()
checkMatch(t, []string{}, doGlob(t, rootCtx, mtAddr, "", "*"))
count, err := bt.CountRows(rootCtx)
if err != nil {
t.Errorf("bt.CountRows failed: %v", err)
}
if expected := 1; count != expected {
t.Errorf("Unexpected number of rows. Got %d, expected %d", count, expected)
bt.DumpTable(rootCtx)
}
}
func TestConcurrentMountDelete(t *testing.T) {
rootCtx, _, _, shutdown := initTest()
defer shutdown()
stop, mtAddr, bt, _ := newMT(t, "", rootCtx, nil)
defer stop()
var wg sync.WaitGroup
busyMount := func(name string) {
defer wg.Done()
for i := 0; i < 250; i++ {
doMount(t, rootCtx, mtAddr, name, "/example.com:12345", true)
}
}
busyDelete := func(name string) {
defer wg.Done()
for i := 0; i < 250; i++ {
doDeleteSubtree(t, rootCtx, mtAddr, name, true)
}
}
for i := 1; i <= 5; i++ {
wg.Add(4)
go busyMount(fmt.Sprintf("a/%d", i))
go busyDelete(fmt.Sprintf("a/%d", i))
go busyMount(fmt.Sprintf("b/%d/c/d/e/f/g/h/i", i))
go busyDelete(fmt.Sprintf("b/%d", i))
}
wg.Wait()
doDeleteSubtree(t, rootCtx, mtAddr, "a", true)
doDeleteSubtree(t, rootCtx, mtAddr, "b", true)
count, err := bt.CountRows(rootCtx)
if err != nil {
t.Errorf("bt.CountRows failed: %v", err)
}
if expected := 1; count != expected {
t.Errorf("Unexpected number of rows. Got %d, expected %d", count, expected)
bt.DumpTable(rootCtx)
}
}
func TestConcurrentExpiry(t *testing.T) {
rootCtx, _, _, shutdown := initTest()
defer shutdown()
stop, mtAddr, bt, clock := newMT(t, "", rootCtx, nil)
defer stop()
const N = 100
name := func(i int) string { return fmt.Sprintf("a/b/c/d/e/f/g/h/i/j/k/l/%05d/%05d", i, i) }
for i := 0; i < N; i++ {
doMount(t, rootCtx, mtAddr, name(i), "/example.com:12345", true)
}
clock.AdvanceTime(time.Duration(ttlSecs+4) * time.Second)
var wg sync.WaitGroup
concurrentResolve := func(name string) {
defer wg.Done()
if _, err := resolve(rootCtx, naming.JoinAddressName(mtAddr, name)); verror.ErrorID(err) != naming.ErrNoSuchName.ID {
t.Errorf("resolve(%q) returned unexpected error: %v", name, err)
}
}
for i := 0; i < N; i++ {
wg.Add(2)
go concurrentResolve(name(i))
go concurrentResolve(name(i))
}
wg.Wait()
count, err := bt.CountRows(rootCtx)
if err != nil {
t.Errorf("bt.CountRows failed: %v", err)
}
if expected := 1; count != expected {
t.Errorf("Unexpected number of rows. Got %d, expected %d", count, expected)
bt.DumpTable(rootCtx)
}
}