mirror of
https://github.com/weaveworks/scope.git
synced 2026-05-06 01:08:03 +00:00
207 lines
4.2 KiB
Go
207 lines
4.2 KiB
Go
package multitenant
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"math/rand"
|
|
"sync"
|
|
"testing"
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
"github.com/weaveworks/scope/app"
|
|
"github.com/weaveworks/scope/common/xfer"
|
|
"github.com/weaveworks/scope/probe/appclient"
|
|
)
|
|
|
|
type adapter struct {
|
|
c appclient.AppClient
|
|
}
|
|
|
|
func (a adapter) PipeConnection(_, pipeID string, pipe xfer.Pipe) error {
|
|
a.c.PipeConnection(pipeID, pipe)
|
|
return nil
|
|
}
|
|
|
|
func (a adapter) PipeClose(_, pipeID string) error {
|
|
return a.c.PipeClose(pipeID)
|
|
}
|
|
|
|
type pipeconn struct {
|
|
id string
|
|
uiPR, probePR app.PipeRouter
|
|
uiPipe, probePipe xfer.Pipe
|
|
uiIO, probeIO io.ReadWriter
|
|
}
|
|
|
|
func (p *pipeconn) test(t *testing.T) {
|
|
msg := []byte("hello " + p.id)
|
|
wait := sync.WaitGroup{}
|
|
wait.Add(2)
|
|
|
|
go func() {
|
|
defer wait.Done()
|
|
|
|
// write something to the probe end
|
|
_, err := p.probeIO.Write(msg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
defer wait.Done()
|
|
|
|
// read it back off the other end
|
|
buf := make([]byte, len(msg))
|
|
n, err := p.uiIO.Read(buf)
|
|
if n != len(buf) {
|
|
t.Fatalf("only read %d", n)
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(buf, msg) {
|
|
t.Fatalf("Got: %v, Expected: %v", buf, msg)
|
|
}
|
|
}()
|
|
|
|
wait.Wait()
|
|
}
|
|
|
|
type pipeTest struct {
|
|
prs []app.PipeRouter
|
|
pipes []*pipeconn
|
|
}
|
|
|
|
func (pt *pipeTest) newPipe(t *testing.T) {
|
|
// make a new pipe id
|
|
id := fmt.Sprintf("pipe-%d", rand.Int63())
|
|
log.Printf(">>>> newPipe %s", id)
|
|
|
|
// pick a random PR to connect app to
|
|
uiIndex := rand.Intn(len(pt.prs))
|
|
uiPR := pt.prs[uiIndex]
|
|
uiPipe, uiIO, err := uiPR.Get(context.Background(), id, app.UIEnd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// pick a random PR to connect probe to
|
|
probeIndex := rand.Intn(len(pt.prs))
|
|
for probeIndex == uiIndex {
|
|
probeIndex = rand.Intn(len(pt.prs))
|
|
}
|
|
probePR := pt.prs[probeIndex]
|
|
probePipe, probeIO, err := probePR.Get(context.Background(), id, app.ProbeEnd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pipe := &pipeconn{
|
|
id: id,
|
|
uiPR: uiPR,
|
|
uiPipe: uiPipe,
|
|
uiIO: uiIO,
|
|
probePR: probePR,
|
|
probePipe: probePipe,
|
|
probeIO: probeIO,
|
|
}
|
|
pipe.test(t)
|
|
pt.pipes = append(pt.pipes, pipe)
|
|
}
|
|
|
|
func (pt *pipeTest) deletePipe(t *testing.T) {
|
|
// pick a random pipe
|
|
i := rand.Intn(len(pt.pipes))
|
|
pipe := pt.pipes[i]
|
|
log.Printf(">>>> deletePipe %s", pipe.id)
|
|
|
|
if err := pipe.uiPR.Release(context.Background(), pipe.id, app.UIEnd); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := pipe.probePR.Release(context.Background(), pipe.id, app.ProbeEnd); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// remove from list
|
|
pt.pipes = pt.pipes[:i+copy(pt.pipes[i:], pt.pipes[i+1:])]
|
|
}
|
|
|
|
func (pt *pipeTest) reconnectPipe(t *testing.T) {
|
|
// pick a random pipe
|
|
pipe := pt.pipes[rand.Intn(len(pt.pipes))]
|
|
log.Printf(">>>> reconnectPipe %s", pipe.id)
|
|
|
|
// pick a random PR to connect to
|
|
newPR := pt.prs[rand.Intn(len(pt.prs))]
|
|
|
|
// pick a random end
|
|
if rand.Float32() < 0.5 {
|
|
if err := pipe.uiPR.Release(context.Background(), pipe.id, app.UIEnd); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
uiPipe, uiIO, err := newPR.Get(context.Background(), pipe.id, app.UIEnd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pipe.uiPR, pipe.uiPipe, pipe.uiIO = newPR, uiPipe, uiIO
|
|
} else {
|
|
if err := pipe.probePR.Release(context.Background(), pipe.id, app.ProbeEnd); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
probePipe, probeIO, err := newPR.Get(context.Background(), pipe.id, app.ProbeEnd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pipe.probePR, pipe.probePipe, pipe.probeIO = newPR, probePipe, probeIO
|
|
}
|
|
}
|
|
|
|
func TestPipeRouter(t *testing.T) {
|
|
var (
|
|
consul = newMockConsulClient()
|
|
replicas = 2
|
|
iterations = 10
|
|
pt = pipeTest{}
|
|
)
|
|
|
|
for i := 0; i < replicas; i++ {
|
|
pr := NewConsulPipeRouter(consul, "", fmt.Sprintf("127.0.0.1:44%02d", i), NoopUserIDer)
|
|
defer pr.Stop()
|
|
pt.prs = append(pt.prs, pr)
|
|
}
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
log.Printf("Iteration %d", i)
|
|
pt.newPipe(t)
|
|
pt.deletePipe(t)
|
|
}
|
|
}
|
|
|
|
//func TestPipeHard(t *testing.T) {
|
|
// if len(pipes) <= 0 {
|
|
// newPipe()
|
|
// continue
|
|
// } else if len(pipes) >= 2 {
|
|
// deletePipe()
|
|
// continue
|
|
// }
|
|
// r := rand.Float32()
|
|
// switch {
|
|
// case 0.0 < r && r <= 0.3:
|
|
// newPipe()
|
|
// case 0.3 < r && r <= 0.6:
|
|
// deletePipe()
|
|
// case 0.6 < r && r <= 1.0:
|
|
// reconnectPipe()
|
|
// }
|
|
//}
|