本文整理匯總了Golang中github.com/cockroachdb/cockroach/gossip/simulation.NewNetwork函數的典型用法代碼示例。如果您正苦於以下問題:Golang NewNetwork函數的具體用法?Golang NewNetwork怎麽用?Golang NewNetwork使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了NewNetwork函數的14個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: makeTestGossip
func makeTestGossip(t *testing.T) (*gossip.Gossip, func()) {
n := simulation.NewNetwork(1, "tcp", gossip.TestInterval)
g := n.Nodes[0].Gossip
permConfig := &config.PermConfig{
Read: []string{""},
Write: []string{""},
}
configMap, err := config.NewPrefixConfigMap([]*config.PrefixConfig{
{proto.KeyMin, nil, permConfig},
})
if err != nil {
t.Fatalf("failed to make prefix config map, err: %s", err.Error())
}
if err := g.AddInfo(gossip.KeySentinel, "cluster1", time.Hour); err != nil {
t.Fatal(err)
}
if err := g.AddInfo(gossip.KeyConfigPermission, configMap, time.Hour); err != nil {
t.Fatal(err)
}
if err := g.AddInfo(gossip.KeyFirstRangeDescriptor, testRangeDescriptor, time.Hour); err != nil {
t.Fatal(err)
}
nodeIDKey := gossip.MakeNodeIDKey(1)
if err := g.AddInfo(nodeIDKey, &proto.NodeDescriptor{
NodeID: 1,
Address: util.MakeUnresolvedAddr(testAddress.Network(), testAddress.String()),
Attrs: proto.Attributes{Attrs: []string{"attr1", "attr2"}},
}, time.Hour); err != nil {
t.Fatal(err)
}
return g, n.Stop
}
示例2: TestGetFirstRangeDescriptor
func TestGetFirstRangeDescriptor(t *testing.T) {
n := simulation.NewNetwork(3, "unix", gossip.TestInterval, gossip.TestBootstrap)
ds := NewDistSender(n.Nodes[0].Gossip)
if _, err := ds.getFirstRangeDescriptor(); err == nil {
t.Errorf("expected not to find first range descriptor")
}
expectedDesc := &proto.RangeDescriptor{}
expectedDesc.StartKey = proto.Key("a")
expectedDesc.EndKey = proto.Key("c")
// Add first RangeDescriptor to a node different from the node for
// this dist sender and ensure that this dist sender has the
// information within a given time.
n.Nodes[1].Gossip.AddInfo(
gossip.KeyFirstRangeDescriptor, *expectedDesc, time.Hour)
maxCycles := 10
n.SimulateNetwork(func(cycle int, network *simulation.Network) bool {
desc, err := ds.getFirstRangeDescriptor()
if err != nil {
if cycle >= maxCycles {
t.Errorf("could not get range descriptor after %d cycles", cycle)
return false
}
return true
}
if !bytes.Equal(desc.StartKey, expectedDesc.StartKey) ||
!bytes.Equal(desc.EndKey, expectedDesc.EndKey) {
t.Errorf("expected first range descriptor %v, instead was %v",
expectedDesc, desc)
}
return false
})
n.Stop()
}
示例3: verifyConvergence
// verifyConvergence verifies that info from each node is visible from
// every node in the network within numCycles cycles of the gossip protocol.
func verifyConvergence(numNodes, maxCycles int, _ *testing.T) {
network := simulation.NewNetwork(numNodes)
if connectedCycle := network.RunUntilFullyConnected(); connectedCycle > maxCycles {
log.Warningf("expected a fully-connected network within %d cycles; took %d",
maxCycles, connectedCycle)
}
network.Stop()
}
示例4: verifyConvergence
// verifyConvergence verifies that info from each node is visible from
// every node in the network within numCycles cycles of the gossip protocol.
// NOTE: This test is non-deterministic because it involves multiple goroutines
// that may not all be able to keep up if the given interval is too small.
// As a rule of thumb, increase the interval until the same number of cycles are used
// for both race and non-race tests; this indicates that no goroutines are being
// left behind by CPU limits.
// TODO(spencer): figure out a more deterministic setup, advancing the clock
// manually and counting cycles accurately instead of relying on real-time sleeps.
func verifyConvergence(numNodes, maxCycles int, interval time.Duration, t *testing.T) {
network := simulation.NewNetwork(numNodes, "tcp", interval)
if connectedCycle := network.RunUntilFullyConnected(); connectedCycle > maxCycles {
t.Errorf("expected a fully-connected network within %d cycles; took %d",
maxCycles, connectedCycle)
}
network.Stop()
}
示例5: main
func main() {
// Seed the random number generator for non-determinism across
// multiple runs.
randutil.SeedForTests()
if f := flag.Lookup("alsologtostderr"); f != nil {
fmt.Println("Starting simulation. Add -alsologtostderr to see progress.")
}
flag.Parse()
dirName, err := ioutil.TempDir("", "gossip-simulation-")
if err != nil {
log.Fatalf(context.TODO(), "could not create temporary directory for gossip simulation output: %s", err)
}
// Simulation callbacks to run the simulation for cycleCount
// cycles. At each cycle % outputEvery, a dot file showing the
// state of the network graph is output.
nodeCount := 3
switch *size {
case "tiny":
// Use default parameters.
case "small":
nodeCount = 10
case "medium":
nodeCount = 25
case "large":
nodeCount = 50
case "huge":
nodeCount = 100
case "ginormous":
nodeCount = 250
default:
log.Fatalf(context.TODO(), "unknown simulation size: %s", *size)
}
edgeSet := make(map[string]edge)
stopper := stop.NewStopper()
defer stopper.Stop()
n := simulation.NewNetwork(stopper, nodeCount, true)
n.SimulateNetwork(
func(cycle int, network *simulation.Network) bool {
// Output dot graph.
dotFN := fmt.Sprintf("%s/sim-cycle-%03d.dot", dirName, cycle)
_, quiescent := outputDotFile(dotFN, cycle, network, edgeSet)
// Run until network has quiesced.
return !quiescent
},
)
// Output instructions for viewing graphs.
fmt.Printf("To view simulation graph output run (you must install graphviz):\n\nfor f in %s/*.dot ; do circo $f -Tpng -o $f.png ; echo $f.png ; done\n", dirName)
}
示例6: TestGossipStorageCleanup
// TestGossipStorageCleanup verifies that bad resolvers are purged
// from the bootstrap info after gossip has successfully connected.
func TestGossipStorageCleanup(t *testing.T) {
defer leaktest.AfterTest(t)()
stopper := stop.NewStopper()
defer stopper.Stop()
const numNodes = 3
network := simulation.NewNetwork(stopper, numNodes, false)
const notReachableAddr = "localhost:0"
const invalidAddr = "10.0.0.1000:3333333"
// Set storage for each of the nodes.
addresses := make(unresolvedAddrSlice, len(network.Nodes))
stores := make([]testStorage, len(network.Nodes))
for i, n := range network.Nodes {
addresses[i] = util.MakeUnresolvedAddr(n.Addr().Network(), n.Addr().String())
// Pre-add an invalid address to each gossip storage.
if err := stores[i].WriteBootstrapInfo(&gossip.BootstrapInfo{
Addresses: []util.UnresolvedAddr{
util.MakeUnresolvedAddr("tcp", network.Nodes[(i+1)%numNodes].Addr().String()), // node i+1 address
util.MakeUnresolvedAddr("tcp", notReachableAddr), // unreachable address
util.MakeUnresolvedAddr("tcp", invalidAddr), // invalid address
},
}); err != nil {
t.Fatal(err)
}
if err := n.Gossip.SetStorage(&stores[i]); err != nil {
t.Fatal(err)
}
n.Gossip.SetStallInterval(1 * time.Millisecond)
n.Gossip.SetBootstrapInterval(1 * time.Millisecond)
}
// Wait for the gossip network to connect.
network.RunUntilFullyConnected()
// Wait long enough for storage to get the expected number of
// addresses and no pending cleanups.
util.SucceedsSoon(t, func() error {
for i := range stores {
p := &stores[i]
if expected, actual := len(network.Nodes)-1 /* -1 is ourself */, p.Len(); expected != actual {
return errors.Errorf("expected %v, got %v (info: %#v)", expected, actual, p.Info().Addresses)
}
for _, addr := range p.Info().Addresses {
if addr.String() == invalidAddr {
return errors.Errorf("node %d still needs bootstrap cleanup", i)
}
}
}
return nil
})
}
示例7: TestConvergence
// TestConvergence verifies a 10 node gossip network converges within
// a fixed number of simulation cycles. It's really difficult to
// determine the right number for cycles because different things can
// happen during a single cycle, depending on how much CPU time is
// available. Eliminating this variability by getting more
// synchronization primitives in place for the simulation is possible,
// though two attempts so far have introduced more complexity into the
// actual production gossip code than seems worthwhile for a unittest.
func TestConvergence(t *testing.T) {
defer leaktest.AfterTest(t)()
stopper := stop.NewStopper()
defer stopper.Stop()
network := simulation.NewNetwork(stopper, 10, true)
const maxCycles = 100
if connectedCycle := network.RunUntilFullyConnected(); connectedCycle > maxCycles {
log.Warningf(context.TODO(), "expected a fully-connected network within %d cycles; took %d",
maxCycles, connectedCycle)
}
}
示例8: makeTestGossip
func makeTestGossip(t *testing.T) (*gossip.Gossip, func()) {
n := simulation.NewNetwork(1)
g := n.Nodes[0].Gossip
if err := g.AddInfo(gossip.KeySentinel, nil, time.Hour); err != nil {
t.Fatal(err)
}
if err := g.AddInfoProto(gossip.KeyFirstRangeDescriptor, &testRangeDescriptor, time.Hour); err != nil {
t.Fatal(err)
}
nodeIDKey := gossip.MakeNodeIDKey(1)
if err := g.AddInfoProto(nodeIDKey, &roachpb.NodeDescriptor{
NodeID: 1,
Address: util.MakeUnresolvedAddr(testAddress.Network(), testAddress.String()),
Attrs: roachpb.Attributes{Attrs: []string{"attr1", "attr2"}},
}, time.Hour); err != nil {
t.Fatal(err)
}
return g, n.Stop
}
示例9: TestGetFirstRangeDescriptor
func TestGetFirstRangeDescriptor(t *testing.T) {
defer leaktest.AfterTest(t)()
n := simulation.NewNetwork(3)
ds := NewDistSender(nil, n.Nodes[0].Gossip)
if _, err := ds.FirstRange(); err == nil {
t.Errorf("expected not to find first range descriptor")
}
expectedDesc := &roachpb.RangeDescriptor{}
expectedDesc.StartKey = roachpb.RKey("a")
expectedDesc.EndKey = roachpb.RKey("c")
// Add first RangeDescriptor to a node different from the node for
// this dist sender and ensure that this dist sender has the
// information within a given time.
if err := n.Nodes[1].Gossip.AddInfoProto(gossip.KeyFirstRangeDescriptor, expectedDesc, time.Hour); err != nil {
t.Fatal(err)
}
maxCycles := 10
n.SimulateNetwork(func(cycle int, network *simulation.Network) bool {
desc, err := ds.FirstRange()
if err != nil {
if cycle >= maxCycles {
t.Errorf("could not get range descriptor after %d cycles", cycle)
return false
}
return true
}
if !bytes.Equal(desc.StartKey, expectedDesc.StartKey) ||
!bytes.Equal(desc.EndKey, expectedDesc.EndKey) {
t.Errorf("expected first range descriptor %v, instead was %v",
expectedDesc, desc)
}
return false
})
n.Stop()
}
示例10: main
func main() {
// Seed the random number generator for non-determinism across
// multiple runs.
rand.Seed(time.Now().UnixNano())
if f := flag.Lookup("alsologtostderr"); f != nil {
fmt.Println("Starting simulation. Add -alsologtostderr to see progress.")
}
flag.Parse()
dirName, err := ioutil.TempDir("", "gossip-simulation-")
if err != nil {
log.Fatalf("could not create temporary directory for gossip simulation output: %s", err)
}
// Simulation callbacks to run the simulation for cycleCount
// cycles. At each cycle % outputEvery, a dot file showing the
// state of the network graph is output.
nodeCount := 3
gossipInterval := simGossipInterval
numCycles := 10
outputEvery := 1
switch *size {
case "tiny":
// Use default parameters.
case "small":
nodeCount = 10
case "medium":
nodeCount = 25
case "large":
nodeCount = 50
gossipInterval = time.Millisecond * 250
case "huge":
nodeCount = 100
gossipInterval = time.Second
numCycles = 20
outputEvery = 2
case "ginormous":
nodeCount = 250
gossipInterval = time.Second * 3
numCycles = 20
outputEvery = 2
default:
log.Fatalf("unknown simulation size: %s", *size)
}
edgeSet := make(map[string]edge)
n := simulation.NewNetwork(nodeCount, *networkType, gossipInterval)
n.SimulateNetwork(
func(cycle int, network *simulation.Network) bool {
if cycle == numCycles {
return false
}
// Update infos.
nodes := network.Nodes
for i := 0; i < len(nodes); i++ {
node := nodes[i].Gossip
if err := node.AddInfo(nodes[i].Addr.String(), int64(cycle), time.Hour); err != nil {
log.Infof("error updating infos addr: %s cycle: %v: %s",
nodes[i].Addr.String(), cycle, err)
}
}
// Output dot graph periodically.
if (cycle+1)%outputEvery == 0 {
dotFN := fmt.Sprintf("%s/sim-cycle-%d.dot", dirName, cycle)
outputDotFile(dotFN, cycle, network, edgeSet)
}
return true
})
n.Stop()
// Output instructions for viewing graphs.
fmt.Printf("To view simulation graph output run (you must install graphviz):\n\nfor f in %s/*.dot ; do circo $f -Tpng -o $f.png ; echo $f.png ; done\n", dirName)
}
示例11: TestGossipStorage
// TestGossipStorage verifies that a gossip node can join the cluster
// using the bootstrap hosts in a gossip.Storage object.
func TestGossipStorage(t *testing.T) {
defer leaktest.AfterTest(t)()
network := simulation.NewNetwork(3)
defer network.Stop()
// Set storage for each of the nodes.
addresses := make(unresolvedAddrSlice, len(network.Nodes))
stores := make([]*testStorage, len(network.Nodes))
for i, n := range network.Nodes {
addresses[i] = util.MakeUnresolvedAddr(n.Addr.Network(), n.Addr.String())
stores[i] = new(testStorage)
if err := n.Gossip.SetStorage(stores[i]); err != nil {
t.Fatal(err)
}
}
// Wait for the gossip network to connect.
network.RunUntilFullyConnected()
// Wait long enough for storage to get the expected number of addresses.
util.SucceedsSoon(t, func() error {
for _, p := range stores {
if p.Len() != 2 {
return util.Errorf("incorrect number of addresses: expected 2; got %d", p.Len())
}
}
return nil
})
for i, p := range stores {
if !p.isRead() {
t.Errorf("%d: expected read from storage", i)
}
if !p.isWrite() {
t.Errorf("%d: expected write from storage", i)
}
p.Lock()
gotAddresses := unresolvedAddrSlice(p.info.Addresses)
sort.Sort(gotAddresses)
var expectedAddresses unresolvedAddrSlice
for j, addr := range addresses {
if i != j { // skip node's own address
expectedAddresses = append(expectedAddresses, addr)
}
}
sort.Sort(expectedAddresses)
// Verify all gossip addresses are written to each persistent store.
if !reflect.DeepEqual(gotAddresses, expectedAddresses) {
t.Errorf("%d: expected addresses: %s, got: %s", i, expectedAddresses, gotAddresses)
}
p.Unlock()
}
// Create an unaffiliated gossip node with only itself as a resolver,
// leaving it no way to reach the gossip network.
node, err := network.CreateNode()
if err != nil {
t.Fatal(err)
}
node.Gossip.SetBootstrapInterval(1 * time.Millisecond)
r, err := resolver.NewResolverFromAddress(node.Addr)
if err != nil {
t.Fatal(err)
}
node.Gossip.SetResolvers([]resolver.Resolver{r})
if err := network.StartNode(node); err != nil {
t.Fatal(err)
}
// Wait for a bit to ensure no connection.
select {
case <-time.After(10 * time.Millisecond):
// expected outcome...
case <-node.Gossip.Connected:
t.Fatal("unexpectedly connected to gossip")
}
// Give the new node storage with info established from a node
// in the established network.
var ts2 testStorage
if err := stores[0].ReadBootstrapInfo(&ts2.info); err != nil {
t.Fatal(err)
}
if err := node.Gossip.SetStorage(&ts2); err != nil {
t.Fatal(err)
}
network.SimulateNetwork(func(cycle int, network *simulation.Network) bool {
if cycle > 1000 {
t.Fatal("failed to connect to gossip")
}
select {
case <-node.Gossip.Connected:
return false
//.........這裏部分代碼省略.........
示例12: TestVerifyPermissions
// TestVerifyPermissions verifies permissions are checked for single
// zones and across multiple zones. It also verifies that permissions
// are checked hierarchically.
func TestVerifyPermissions(t *testing.T) {
defer leaktest.AfterTest(t)
n := simulation.NewNetwork(1, "tcp", gossip.TestInterval)
ds := NewDistSender(nil, n.Nodes[0].Gossip)
config1 := &proto.PermConfig{
Read: []string{"read1", "readAll", "rw1", "rwAll"},
Write: []string{"write1", "writeAll", "rw1", "rwAll"}}
config2 := &proto.PermConfig{
Read: []string{"read2", "readAll", "rw2", "rwAll"},
Write: []string{"write2", "writeAll", "rw2", "rwAll"}}
configs := []*storage.PrefixConfig{
{proto.KeyMin, nil, config1},
{proto.Key("a"), nil, config2},
}
configMap, err := storage.NewPrefixConfigMap(configs)
if err != nil {
t.Fatalf("failed to make prefix config map, err: %s", err.Error())
}
if err := ds.gossip.AddInfo(gossip.KeyConfigPermission, configMap, time.Hour); err != nil {
t.Fatal(err)
}
allRequestTypes := []proto.Request{
&proto.GetRequest{},
&proto.PutRequest{},
&proto.ConditionalPutRequest{},
&proto.IncrementRequest{},
&proto.DeleteRequest{},
&proto.DeleteRangeRequest{},
&proto.ScanRequest{},
&proto.EndTransactionRequest{},
&proto.BatchRequest{},
&proto.AdminSplitRequest{},
&proto.AdminMergeRequest{},
&proto.InternalHeartbeatTxnRequest{},
&proto.InternalGCRequest{},
&proto.InternalPushTxnRequest{},
&proto.InternalRangeLookupRequest{},
&proto.InternalResolveIntentRequest{},
&proto.InternalResolveIntentRangeRequest{},
&proto.InternalMergeRequest{},
&proto.InternalTruncateLogRequest{},
&proto.InternalLeaderLeaseRequest{},
&proto.InternalBatchRequest{},
}
var readOnlyRequests []proto.Request
var writeOnlyRequests []proto.Request
var readWriteRequests []proto.Request
for _, r := range allRequestTypes {
if proto.IsRead(r) && !proto.IsWrite(r) {
readOnlyRequests = append(readOnlyRequests, r)
}
if proto.IsWrite(r) && !proto.IsRead(r) {
writeOnlyRequests = append(writeOnlyRequests, r)
}
if proto.IsRead(r) && proto.IsWrite(r) {
readWriteRequests = append(readWriteRequests, r)
}
}
testData := []struct {
// Permission-based db methods from the storage package.
requests []proto.Request
user string
startKey, endKey proto.Key
hasPermission bool
}{
// Test permissions within a single range
{readOnlyRequests, "read1", proto.KeyMin, proto.KeyMin, true},
{readOnlyRequests, "rw1", proto.KeyMin, proto.KeyMin, true},
{readOnlyRequests, "write1", proto.KeyMin, proto.KeyMin, false},
{readOnlyRequests, "random", proto.KeyMin, proto.KeyMin, false},
{readWriteRequests, "rw1", proto.KeyMin, proto.KeyMin, true},
{readWriteRequests, "read1", proto.KeyMin, proto.KeyMin, false},
{readWriteRequests, "write1", proto.KeyMin, proto.KeyMin, false},
{writeOnlyRequests, "write1", proto.KeyMin, proto.KeyMin, true},
{writeOnlyRequests, "rw1", proto.KeyMin, proto.KeyMin, true},
{writeOnlyRequests, "read1", proto.KeyMin, proto.KeyMin, false},
{writeOnlyRequests, "random", proto.KeyMin, proto.KeyMin, false},
// Test permissions hierarchically.
{readOnlyRequests, "read1", proto.Key("a"), proto.Key("a1"), true},
{readWriteRequests, "rw1", proto.Key("a"), proto.Key("a1"), true},
{writeOnlyRequests, "write1", proto.Key("a"), proto.Key("a1"), true},
// Test permissions across both ranges.
{readOnlyRequests, "readAll", proto.KeyMin, proto.Key("b"), true},
{readOnlyRequests, "read1", proto.KeyMin, proto.Key("b"), true},
{readOnlyRequests, "read2", proto.KeyMin, proto.Key("b"), false},
{readOnlyRequests, "random", proto.KeyMin, proto.Key("b"), false},
{readWriteRequests, "rwAll", proto.KeyMin, proto.Key("b"), true},
{readWriteRequests, "rw1", proto.KeyMin, proto.Key("b"), true},
{readWriteRequests, "random", proto.KeyMin, proto.Key("b"), false},
{writeOnlyRequests, "writeAll", proto.KeyMin, proto.Key("b"), true},
{writeOnlyRequests, "write1", proto.KeyMin, proto.Key("b"), true},
{writeOnlyRequests, "write2", proto.KeyMin, proto.Key("b"), false},
{writeOnlyRequests, "random", proto.KeyMin, proto.Key("b"), false},
//.........這裏部分代碼省略.........
示例13: TestGossipStorage
// TestGossipStorage verifies that a gossip node can join the cluster
// using the bootstrap hosts in a gossip.Storage object.
func TestGossipStorage(t *testing.T) {
defer leaktest.AfterTest(t)
const numNodes = 3
network := simulation.NewNetwork(3)
defer network.Stop()
// Set storage for each of the nodes.
stores := []*testStorage{}
for _, n := range network.Nodes {
tp := &testStorage{}
stores = append(stores, tp)
if err := n.Gossip.SetStorage(tp); err != nil {
t.Fatal(err)
}
}
// Wait for the gossip network to connect.
network.RunUntilFullyConnected()
for i, p := range stores {
if !p.read {
t.Errorf("%d: expected read from storage", i)
}
if !p.write {
t.Errorf("%d: expected write from storage", i)
}
// Verify all gossip addresses are written to each persistent store.
if len(p.info.Addresses) != 3 {
t.Errorf("%d: expected 3 addresses, have: %s", i, p.info.Addresses)
}
}
// Create an unaffiliated gossip node with only itself as a resolver,
// leaving it no way to reach the gossip network.
node, err := network.CreateNode()
if err != nil {
t.Fatal(err)
}
node.Gossip.SetBootstrapInterval(1 * time.Millisecond)
r, err := resolver.NewResolverFromAddress(node.Addr)
if err != nil {
t.Fatal(err)
}
node.Gossip.SetResolvers([]resolver.Resolver{r})
if err := network.StartNode(node); err != nil {
t.Fatal(err)
}
// Wait for a bit to ensure no connection.
select {
case <-time.After(10 * time.Millisecond):
// expected outcome...
case <-node.Gossip.Connected:
t.Fatal("unexpectedly connected to gossip")
}
// Give the new node storage with info established from a node
// in the established network.
tp := &testStorage{
info: stores[0].info,
}
if err := node.Gossip.SetStorage(tp); err != nil {
t.Fatal(err)
}
network.SimulateNetwork(func(cycle int, network *simulation.Network) bool {
if cycle > 100 {
t.Fatal("failed to connect to gossip")
}
select {
case <-node.Gossip.Connected:
return false
default:
return true
}
})
}
示例14: TestVerifyPermissions
// TestVerifyPermissions verifies permissions are checked for single
// zones and across multiple zones. It also verifies that permissions
// are checked hierarchically.
func TestVerifyPermissions(t *testing.T) {
n := simulation.NewNetwork(1, "unix", gossip.TestInterval, gossip.TestBootstrap)
ds := NewDistSender(n.Nodes[0].Gossip)
config1 := &proto.PermConfig{
Read: []string{"read1", "readAll", "rw1", "rwAll"},
Write: []string{"write1", "writeAll", "rw1", "rwAll"}}
config2 := &proto.PermConfig{
Read: []string{"read2", "readAll", "rw2", "rwAll"},
Write: []string{"write2", "writeAll", "rw2", "rwAll"}}
configs := []*storage.PrefixConfig{
{engine.KeyMin, nil, config1},
{proto.Key("a"), nil, config2},
}
configMap, err := storage.NewPrefixConfigMap(configs)
if err != nil {
t.Fatalf("failed to make prefix config map, err: %s", err.Error())
}
ds.gossip.AddInfo(gossip.KeyConfigPermission, configMap, time.Hour)
readOnlyMethods := make([]string, 0, len(proto.ReadMethods))
writeOnlyMethods := make([]string, 0, len(proto.WriteMethods))
readWriteMethods := make([]string, 0, len(proto.ReadMethods)+len(proto.WriteMethods))
for readM := range proto.ReadMethods {
if proto.IsReadOnly(readM) {
readOnlyMethods = append(readOnlyMethods, readM)
} else {
readWriteMethods = append(readWriteMethods, readM)
}
}
for writeM := range proto.WriteMethods {
if !proto.NeedReadPerm(writeM) {
writeOnlyMethods = append(writeOnlyMethods, writeM)
}
}
testData := []struct {
// Permission-based db methods from the storage package.
methods []string
user string
startKey, endKey proto.Key
hasPermission bool
}{
// Test permissions within a single range
{readOnlyMethods, "read1", engine.KeyMin, engine.KeyMin, true},
{readOnlyMethods, "rw1", engine.KeyMin, engine.KeyMin, true},
{readOnlyMethods, "write1", engine.KeyMin, engine.KeyMin, false},
{readOnlyMethods, "random", engine.KeyMin, engine.KeyMin, false},
{readWriteMethods, "rw1", engine.KeyMin, engine.KeyMin, true},
{readWriteMethods, "read1", engine.KeyMin, engine.KeyMin, false},
{readWriteMethods, "write1", engine.KeyMin, engine.KeyMin, false},
{writeOnlyMethods, "write1", engine.KeyMin, engine.KeyMin, true},
{writeOnlyMethods, "rw1", engine.KeyMin, engine.KeyMin, true},
{writeOnlyMethods, "read1", engine.KeyMin, engine.KeyMin, false},
{writeOnlyMethods, "random", engine.KeyMin, engine.KeyMin, false},
// Test permissions hierarchically.
{readOnlyMethods, "read1", proto.Key("a"), proto.Key("a1"), true},
{readWriteMethods, "rw1", proto.Key("a"), proto.Key("a1"), true},
{writeOnlyMethods, "write1", proto.Key("a"), proto.Key("a1"), true},
// Test permissions across both ranges.
{readOnlyMethods, "readAll", engine.KeyMin, proto.Key("b"), true},
{readOnlyMethods, "read1", engine.KeyMin, proto.Key("b"), true},
{readOnlyMethods, "read2", engine.KeyMin, proto.Key("b"), false},
{readOnlyMethods, "random", engine.KeyMin, proto.Key("b"), false},
{readWriteMethods, "rwAll", engine.KeyMin, proto.Key("b"), true},
{readWriteMethods, "rw1", engine.KeyMin, proto.Key("b"), true},
{readWriteMethods, "random", engine.KeyMin, proto.Key("b"), false},
{writeOnlyMethods, "writeAll", engine.KeyMin, proto.Key("b"), true},
{writeOnlyMethods, "write1", engine.KeyMin, proto.Key("b"), true},
{writeOnlyMethods, "write2", engine.KeyMin, proto.Key("b"), false},
{writeOnlyMethods, "random", engine.KeyMin, proto.Key("b"), false},
// Test permissions within and around the boundaries of a range,
// representatively using rw methods.
{readWriteMethods, "rw2", proto.Key("a"), proto.Key("b"), true},
{readWriteMethods, "rwAll", proto.Key("a"), proto.Key("b"), true},
{readWriteMethods, "rw2", proto.Key("a"), proto.Key("a"), true},
{readWriteMethods, "rw2", proto.Key("a"), proto.Key("a1"), true},
{readWriteMethods, "rw2", proto.Key("a"), proto.Key("b1"), false},
{readWriteMethods, "rw2", proto.Key("a3"), proto.Key("a4"), true},
{readWriteMethods, "rw2", proto.Key("a3"), proto.Key("b1"), false},
}
for i, test := range testData {
for _, method := range test.methods {
err := ds.verifyPermissions(
method,
&proto.RequestHeader{
User: test.user, Key: test.startKey, EndKey: test.endKey})
if err != nil && test.hasPermission {
t.Errorf("test %d: user %s should have had permission to %s, err: %s",
i, test.user, method, err.Error())
break
} else if err == nil && !test.hasPermission {
t.Errorf("test %d: user %s should not have had permission to %s",
i, test.user, method)
break
}
}
//.........這裏部分代碼省略.........