mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
151 lines
3.8 KiB
Go
151 lines
3.8 KiB
Go
// Copyright 2017 Pilosa Corp.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package pilosa
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
pnet "github.com/pilosa/pilosa/v2/net"
|
|
"github.com/pilosa/pilosa/v2/roaring"
|
|
"github.com/pilosa/pilosa/v2/testhook"
|
|
"github.com/pilosa/pilosa/v2/topology"
|
|
. "github.com/pilosa/pilosa/v2/vprint" // nolint:staticcheck
|
|
)
|
|
|
|
// utilities used by tests
|
|
|
|
// mustAddR is a helper for calling roaring.Container.Add() in tests to
|
|
// keep the linter happy that we are checking the error.
|
|
func mustAddR(changed bool, err error) {
|
|
PanicOn(err)
|
|
}
|
|
|
|
// mustRemove is a helper for calling Tx.Remove() in tests to
|
|
// keep the linter happy that we are checking the error.
|
|
func mustRemove(changeCount int, err error) {
|
|
PanicOn(err)
|
|
}
|
|
|
|
func getTestBitmapAsRawRoaring(bitsToSet ...uint64) []byte {
|
|
b := roaring.NewBitmap()
|
|
changed := b.DirectAddN(bitsToSet...)
|
|
n := len(bitsToSet)
|
|
if changed != n {
|
|
panic(fmt.Sprintf("changed=%v but bitsToSet len = %v", changed, n))
|
|
}
|
|
buf := bytes.NewBuffer(make([]byte, 0, 100000))
|
|
_, err := b.WriteTo(buf)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
// NewTestCluster returns a cluster with n nodes and uses a mod-based hasher.
|
|
func NewTestCluster(tb testing.TB, n int) *cluster {
|
|
path, err := testhook.TempDir(tb, "pilosa-cluster-")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
availableShardFileFlushDuration.Set(100 * time.Millisecond)
|
|
c := newCluster()
|
|
c.ReplicaN = 1
|
|
c.Hasher = NewTestModHasher()
|
|
c.Path = path
|
|
|
|
for i := 0; i < n; i++ {
|
|
c.noder.AppendNode(&topology.Node{
|
|
ID: fmt.Sprintf("node%d", i),
|
|
URI: NewTestURI("http", fmt.Sprintf("host%d", i), uint16(0)),
|
|
})
|
|
}
|
|
|
|
cNodes := c.noder.Nodes()
|
|
|
|
c.Node = cNodes[0]
|
|
return c
|
|
}
|
|
|
|
// NewTestURI is a test URI creator that intentionally swallows errors.
|
|
func NewTestURI(scheme, host string, port uint16) pnet.URI {
|
|
uri := pnet.DefaultURI()
|
|
_ = uri.SetScheme(scheme)
|
|
_ = uri.SetHost(host)
|
|
uri.SetPort(port)
|
|
return *uri
|
|
}
|
|
|
|
func NewTestURIFromHostPort(host string, port uint16) pnet.URI {
|
|
uri := pnet.DefaultURI()
|
|
_ = uri.SetHost(host)
|
|
uri.SetPort(port)
|
|
return *uri
|
|
}
|
|
|
|
// ModHasher represents a simple, mod-based hashing.
|
|
type TestModHasher struct{}
|
|
|
|
// NewTestModHasher returns a new instance of ModHasher with n buckets.
|
|
func NewTestModHasher() *TestModHasher { return &TestModHasher{} }
|
|
|
|
func (*TestModHasher) Hash(key uint64, n int) int { return int(key) % n }
|
|
|
|
func (*TestModHasher) Name() string { return "mod" }
|
|
|
|
var _ = NewTestClusterWithReplication // happy linter
|
|
|
|
func NewTestClusterWithReplication(tb testing.TB, nNodes, nReplicas, partitionN int) (c *cluster, cleaner func()) {
|
|
path, err := testhook.TempDir(tb, "pilosa-cluster-")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// holder
|
|
h := NewHolder(path, nil)
|
|
|
|
// cluster
|
|
availableShardFileFlushDuration.Set(100 * time.Millisecond)
|
|
c = newCluster()
|
|
c.holder = h
|
|
c.ReplicaN = nReplicas
|
|
c.Hasher = &topology.Jmphasher{}
|
|
c.Path = path
|
|
c.partitionN = partitionN
|
|
|
|
for i := 0; i < nNodes; i++ {
|
|
nodeID := fmt.Sprintf("node%d", i)
|
|
c.noder.AppendNode(&topology.Node{
|
|
ID: nodeID,
|
|
URI: NewTestURI("http", fmt.Sprintf("host%d", i), uint16(0)),
|
|
})
|
|
}
|
|
|
|
cNodes := c.noder.Nodes()
|
|
|
|
c.Node = cNodes[0]
|
|
|
|
if err := c.holder.Open(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return c, func() {
|
|
c.holder.Close()
|
|
c.close()
|
|
}
|
|
}
|