mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-11 05:29:30 +00:00
385 lines
8.7 KiB
Go
385 lines
8.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
|
"gopkg.in/mgo.v2/dbtest"
|
|
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/percona/percona-toolkit/src/go/lib/tutil"
|
|
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
|
"github.com/percona/pmgo"
|
|
"github.com/percona/pmgo/pmgomock"
|
|
)
|
|
|
|
func TestGetOpCounterStats(t *testing.T) {
|
|
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
session := pmgomock.NewMockSessionManager(ctrl)
|
|
database := pmgomock.NewMockDatabaseManager(ctrl)
|
|
|
|
ss := proto.ServerStatus{}
|
|
tutil.LoadJson("test/sample/serverstatus.json", &ss)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
ss = addToCounters(ss, 1)
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"serverStatus", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, ss)
|
|
|
|
var sampleCount int = 5
|
|
var sampleRate time.Duration = 10 * time.Millisecond // in seconds
|
|
expect := TimedStats{Min: 0, Max: 0, Total: 0, Avg: 0}
|
|
|
|
os, err := GetOpCountersStats(session, sampleCount, sampleRate)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if !reflect.DeepEqual(expect, os.Command) {
|
|
t.Errorf("getOpCountersStats. got: %+v\nexpect: %+v\n", os.Command, expect)
|
|
}
|
|
|
|
}
|
|
|
|
func TestSecurityOpts(t *testing.T) {
|
|
cmdopts := []proto.CommandLineOptions{
|
|
// 1
|
|
proto.CommandLineOptions{
|
|
Parsed: proto.Parsed{
|
|
Net: proto.Net{
|
|
SSL: proto.SSL{
|
|
Mode: "",
|
|
},
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "",
|
|
Authorization: "",
|
|
},
|
|
},
|
|
// 2
|
|
proto.CommandLineOptions{
|
|
Parsed: proto.Parsed{
|
|
Net: proto.Net{
|
|
SSL: proto.SSL{
|
|
Mode: "",
|
|
},
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "a file",
|
|
Authorization: "",
|
|
},
|
|
},
|
|
// 3
|
|
proto.CommandLineOptions{
|
|
Parsed: proto.Parsed{
|
|
Net: proto.Net{
|
|
SSL: proto.SSL{
|
|
Mode: "",
|
|
},
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "",
|
|
Authorization: "something here",
|
|
},
|
|
},
|
|
// 4
|
|
proto.CommandLineOptions{
|
|
Parsed: proto.Parsed{
|
|
Net: proto.Net{
|
|
SSL: proto.SSL{
|
|
Mode: "super secure",
|
|
},
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "",
|
|
Authorization: "",
|
|
},
|
|
},
|
|
// 5
|
|
proto.CommandLineOptions{
|
|
Parsed: proto.Parsed{
|
|
Net: proto.Net{
|
|
SSL: proto.SSL{
|
|
Mode: "",
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "/home/plavi/psmdb/percona-server-mongodb-3.4.0-1.0-beta-6320ac4/data/keyfile",
|
|
},
|
|
},
|
|
Security: proto.Security{
|
|
KeyFile: "",
|
|
Authorization: "",
|
|
},
|
|
},
|
|
}
|
|
|
|
expect := []*security{
|
|
// 1
|
|
&security{
|
|
Users: 1,
|
|
Roles: 2,
|
|
Auth: "disabled",
|
|
SSL: "disabled",
|
|
BindIP: "",
|
|
Port: 0,
|
|
WarningMsgs: nil,
|
|
},
|
|
// 2
|
|
&security{
|
|
Users: 1,
|
|
Roles: 2,
|
|
Auth: "enabled",
|
|
SSL: "disabled",
|
|
BindIP: "", Port: 0,
|
|
WarningMsgs: nil,
|
|
},
|
|
// 3
|
|
&security{
|
|
Users: 1,
|
|
Roles: 2,
|
|
Auth: "enabled",
|
|
SSL: "disabled",
|
|
BindIP: "",
|
|
Port: 0,
|
|
WarningMsgs: nil,
|
|
},
|
|
// 4
|
|
&security{
|
|
Users: 1,
|
|
Roles: 2,
|
|
Auth: "disabled",
|
|
SSL: "super secure",
|
|
BindIP: "",
|
|
Port: 0,
|
|
WarningMsgs: nil,
|
|
},
|
|
// 5
|
|
&security{
|
|
Users: 1,
|
|
Roles: 2,
|
|
Auth: "enabled",
|
|
SSL: "disabled",
|
|
BindIP: "",
|
|
Port: 0,
|
|
WarningMsgs: nil,
|
|
},
|
|
}
|
|
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
session := pmgomock.NewMockSessionManager(ctrl)
|
|
database := pmgomock.NewMockDatabaseManager(ctrl)
|
|
|
|
usersCol := pmgomock.NewMockCollectionManager(ctrl)
|
|
rolesCol := pmgomock.NewMockCollectionManager(ctrl)
|
|
|
|
for i, cmd := range cmdopts {
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().Run(bson.D{{"getCmdLineOpts", 1}, {"recordStats", 1}}, gomock.Any()).SetArg(1, cmd)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().C("system.users").Return(usersCol)
|
|
usersCol.EXPECT().Count().Return(1, nil)
|
|
|
|
session.EXPECT().DB("admin").Return(database)
|
|
database.EXPECT().C("system.roles").Return(rolesCol)
|
|
rolesCol.EXPECT().Count().Return(2, nil)
|
|
|
|
got, err := GetSecuritySettings(session, "3.2")
|
|
|
|
if err != nil {
|
|
t.Errorf("cannot get sec settings: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(got, expect[i]) {
|
|
t.Errorf("Test # %d,\ngot: %#v\nwant: %#v\n", i+1, got, expect[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetNodeType(t *testing.T) {
|
|
md := []struct {
|
|
in proto.MasterDoc
|
|
out string
|
|
}{
|
|
{proto.MasterDoc{SetName: "name"}, "replset"},
|
|
{proto.MasterDoc{Msg: "isdbgrid"}, "mongos"},
|
|
{proto.MasterDoc{Msg: "a msg"}, "mongod"},
|
|
}
|
|
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
session := pmgomock.NewMockSessionManager(ctrl)
|
|
for _, m := range md {
|
|
session.EXPECT().Run("isMaster", gomock.Any()).SetArg(1, m.in)
|
|
nodeType, err := getNodeType(session)
|
|
if err != nil {
|
|
t.Errorf("cannot get node type: %+v, error: %s\n", m.in, err)
|
|
}
|
|
if nodeType != m.out {
|
|
t.Errorf("invalid node type. got %s, expect: %s\n", nodeType, m.out)
|
|
}
|
|
}
|
|
session.EXPECT().Run("isMaster", gomock.Any()).Return(fmt.Errorf("some fake error"))
|
|
nodeType, err := getNodeType(session)
|
|
if err == nil {
|
|
t.Errorf("error expected, got nil")
|
|
}
|
|
if nodeType != "" {
|
|
t.Errorf("expected blank node type, got %s", nodeType)
|
|
}
|
|
|
|
}
|
|
|
|
func TestIsPrivateNetwork(t *testing.T) {
|
|
//privateCIDRs := []string{"10.0.0.0/24", "172.16.0.0/20", "192.168.0.0/16"}
|
|
testdata :=
|
|
[]struct {
|
|
ip string
|
|
want bool
|
|
err error
|
|
}{
|
|
{
|
|
ip: "127.0.0.1",
|
|
want: true,
|
|
err: nil,
|
|
},
|
|
{
|
|
ip: "10.0.0.1",
|
|
want: true,
|
|
err: nil,
|
|
},
|
|
{
|
|
ip: "10.0.1.1",
|
|
want: false,
|
|
err: nil,
|
|
},
|
|
{
|
|
ip: "172.16.1.2",
|
|
want: true,
|
|
err: nil,
|
|
},
|
|
{
|
|
ip: "192.168.1.2",
|
|
want: true,
|
|
err: nil,
|
|
},
|
|
{
|
|
ip: "8.8.8.8",
|
|
want: false,
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, in := range testdata {
|
|
got, err := isPrivateNetwork(in.ip)
|
|
if err != in.err {
|
|
t.Errorf("ip %s. got err: %s, want err: %v", in.ip, err, in.err)
|
|
}
|
|
if got != in.want {
|
|
t.Errorf("ip %s. got: %v, want : %v", in.ip, got, in.want)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetChunks(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
session := pmgomock.NewMockSessionManager(ctrl)
|
|
database := pmgomock.NewMockDatabaseManager(ctrl)
|
|
pipe := pmgomock.NewMockPipeManager(ctrl)
|
|
col := pmgomock.NewMockCollectionManager(ctrl)
|
|
|
|
var res []proto.ChunksByCollection
|
|
tutil.LoadJson("test/sample/chunks.json", &res)
|
|
|
|
pipe.EXPECT().All(gomock.Any()).SetArg(0, res)
|
|
|
|
col.EXPECT().Pipe(gomock.Any()).Return(pipe)
|
|
|
|
database.EXPECT().C("chunks").Return(col)
|
|
|
|
session.EXPECT().DB("config").Return(database)
|
|
|
|
want := []proto.ChunksByCollection{
|
|
{ID: "samples.col2", Count: 5},
|
|
}
|
|
|
|
got, err := getChunksCount(session)
|
|
if err != nil {
|
|
t.Errorf("Cannot get chunks: %s", err.Error())
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("Invalid getChunksCount response.\ngot: %+v\nwant: %+v\n", got, want)
|
|
}
|
|
}
|
|
|
|
func TestIntegrationGetChunks(t *testing.T) {
|
|
var server dbtest.DBServer
|
|
os.Setenv("CHECK_SESSIONS", "0")
|
|
tempDir, _ := ioutil.TempDir("", "testing")
|
|
server.SetPath(tempDir)
|
|
|
|
session := pmgo.NewSessionManager(server.Session())
|
|
session.DB("config").C("chunks").Insert(bson.M{"ns": "samples.col1", "count": 2})
|
|
|
|
want := []proto.ChunksByCollection{
|
|
proto.ChunksByCollection{
|
|
ID: "samples.col1",
|
|
Count: 1,
|
|
},
|
|
}
|
|
got, err := getChunksCount(session)
|
|
if err != nil {
|
|
t.Errorf("Error in integration chunks count: %s", err.Error())
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("Invalid integration chunks count.\ngot: %+v\nwant: %+v", got, want)
|
|
}
|
|
|
|
server.Session().DB("config").DropDatabase()
|
|
server.Session().Close()
|
|
server.Stop()
|
|
|
|
}
|
|
|
|
func addToCounters(ss proto.ServerStatus, increment int64) proto.ServerStatus {
|
|
ss.Opcounters.Command += increment
|
|
ss.Opcounters.Delete += increment
|
|
ss.Opcounters.GetMore += increment
|
|
ss.Opcounters.Insert += increment
|
|
ss.Opcounters.Query += increment
|
|
ss.Opcounters.Update += increment
|
|
return ss
|
|
}
|