Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
AlekSi committed Dec 11, 2021
1 parent 0378846 commit 3b6aa3a
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 130 deletions.
207 changes: 77 additions & 130 deletions internal/handlers/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package handlers

import (
"context"
"fmt"
"testing"
"time"
Expand All @@ -27,18 +28,21 @@ import (
"github.com/FerretDB/FerretDB/internal/handlers/jsonb1"
"github.com/FerretDB/FerretDB/internal/handlers/shared"
"github.com/FerretDB/FerretDB/internal/handlers/sql"
"github.com/FerretDB/FerretDB/internal/pg"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/testutil"
"github.com/FerretDB/FerretDB/internal/wire"
)

func TestListDatabases(t *testing.T) {
t.Parallel()
func setup(t *testing.T, poolOpts *testutil.PoolOpts) (context.Context, *Handler, *pg.Pool) {
t.Helper()

if poolOpts == nil {
poolOpts = new(testutil.PoolOpts)
}

ctx := testutil.Ctx(t)
pool := testutil.Pool(ctx, t, &testutil.PoolOpts{
ReadOnly: true,
})
pool := testutil.Pool(ctx, t, poolOpts)
l := zaptest.NewLogger(t)
shared := shared.NewHandler(pool, "127.0.0.1:12345")
sql := sql.NewStorage(pool, l.Sugar())
Expand All @@ -52,96 +56,11 @@ func TestListDatabases(t *testing.T) {
Metrics: NewMetrics(),
})

type testCase struct {
req types.Document
resp types.Document
}

testCases := map[string]testCase{
"listDatabases": {
req: types.MustMakeDocument(
"listDatabases", int32(1),
),
resp: types.MustMakeDocument(
"databases", types.Array{
types.MustMakeDocument(
"name", "monila",
"sizeOnDisk", int64(13238272),
"empty", false,
),
types.MustMakeDocument(
"name", "pagila",
"sizeOnDisk", int64(7184384),
"empty", false,
),
},
"totalSize", int64(30081827),
"totalSizeMb", int64(28),
"ok", float64(1),
),
},
}

for name, tc := range testCases { //nolint:paralleltest // false positive
name, tc := name, tc
t.Run(name, func(t *testing.T) {
t.Parallel()

reqHeader := wire.MsgHeader{
RequestID: 1,
OpCode: wire.OP_MSG,
}

var reqMsg wire.OpMsg
err := reqMsg.SetSections(wire.OpMsgSection{
Documents: []types.Document{tc.req},
})
require.NoError(t, err)

_, resBody, closeConn := handler.Handle(ctx, &reqHeader, &reqMsg)
require.False(t, closeConn, "%s", wire.DumpMsgBody(resBody))

actual, err := resBody.(*wire.OpMsg).Document()
require.NoError(t, err)

expected := tc.resp

assert.Equal(t, actual.Map()["ok"].(float64), expected.Map()["ok"].(float64))
assert.GreaterOrEqual(t, actual.Map()["totalSize"].(int64), int64(5000))
assert.GreaterOrEqual(t, actual.Map()["totalSizeMb"].(int64), int64(1))

actualDatabasesArray := actual.Map()["databases"].(types.Array)
expectedDatabasesArray := expected.Map()["databases"].(types.Array)

for i := range expectedDatabasesArray {
actualDatabase := actualDatabasesArray[i].(types.Document)
expectedDatabase := expectedDatabasesArray[i].(types.Document)
assert.GreaterOrEqual(t, actualDatabase.Map()["sizeOnDisk"].(int64), int64(1000))

actualDatabase.Remove("sizeOnDisk")
expectedDatabase.Remove("sizeOnDisk")
assert.Equal(t, actualDatabase, expectedDatabase)
}
})
}
return ctx, handler, pool
}

func TestDropDatabase(t *testing.T) { //nolint:paralleltest,tparallel // affects a global list of databases
ctx := testutil.Ctx(t)
pool := testutil.Pool(ctx, t, new(testutil.PoolOpts))
l := zaptest.NewLogger(t)
shared := shared.NewHandler(pool, "127.0.0.1:12345")
sql := sql.NewStorage(pool, l.Sugar())
jsonb1 := jsonb1.NewStorage(pool, l)

handler := New(&NewOpts{
PgPool: pool,
Logger: l,
SharedHandler: shared,
SQLStorage: sql,
JSONB1Storage: jsonb1,
Metrics: NewMetrics(),
})
ctx, handler, pool := setup(t, nil)

type testCase struct {
req types.Document
Expand Down Expand Up @@ -238,23 +157,9 @@ func TestDropDatabase(t *testing.T) { //nolint:paralleltest,tparallel // affects

func TestFind(t *testing.T) {
t.Parallel()

ctx := testutil.Ctx(t)
pool := testutil.Pool(ctx, t, &testutil.PoolOpts{
ctx, handler, _ := setup(t, &testutil.PoolOpts{
ReadOnly: true,
})
l := zaptest.NewLogger(t)
shared := shared.NewHandler(pool, "127.0.0.1:12345")
sql := sql.NewStorage(pool, l.Sugar())
jsonb1 := jsonb1.NewStorage(pool, l)
handler := New(&NewOpts{
PgPool: pool,
Logger: l,
SharedHandler: shared,
SQLStorage: sql,
JSONB1Storage: jsonb1,
Metrics: NewMetrics(),
})

lastUpdate := time.Date(2020, 2, 15, 9, 34, 33, 0, time.UTC).Local()

Expand Down Expand Up @@ -587,33 +492,23 @@ func TestFind(t *testing.T) {

func TestReadOnlyHandlers(t *testing.T) {
t.Parallel()

ctx := testutil.Ctx(t)
pool := testutil.Pool(ctx, t, &testutil.PoolOpts{
ctx, handler, _ := setup(t, &testutil.PoolOpts{
ReadOnly: true,
})
l := zaptest.NewLogger(t)
shared := shared.NewHandler(pool, "127.0.0.1:12345")
sql := sql.NewStorage(pool, l.Sugar())
jsonb1 := jsonb1.NewStorage(pool, l)
handler := New(&NewOpts{
PgPool: pool,
Logger: l,
SharedHandler: shared,
SQLStorage: sql,
JSONB1Storage: jsonb1,
Metrics: NewMetrics(),
})

type testCase struct {
req types.Document
resp types.Document
req types.Document
reqSetDB bool
resp types.Document
compareFunc func(t testing.TB, actual, expected any)
}

testCases := map[string]testCase{
"CountAllActors": {
req: types.MustMakeDocument(
"count", "actor",
),
reqSetDB: true,
resp: types.MustMakeDocument(
"n", int32(200),
"ok", float64(1),
Expand All @@ -626,6 +521,7 @@ func TestReadOnlyHandlers(t *testing.T) {
"actor_id", int32(28),
),
),
reqSetDB: true,
resp: types.MustMakeDocument(
"n", int32(1),
"ok", float64(1),
Expand All @@ -638,25 +534,70 @@ func TestReadOnlyHandlers(t *testing.T) {
"last_name", "HOFFMAN",
),
),
reqSetDB: true,
resp: types.MustMakeDocument(
"n", int32(3),
"ok", float64(1),
),
},

"ServerStatus": {
"GetParameter": {
req: types.MustMakeDocument(
"serverStatus", int32(1),
"getParameter", int32(1),
),
resp: types.MustMakeDocument(
"version", "5.0.42",
"ok", float64(1),
),
},

"GetParameter": {
"ListDatabases": {
req: types.MustMakeDocument(
"getParameter", int32(1),
"listDatabases", int32(1),
),
resp: types.MustMakeDocument(
"databases", types.Array{
types.MustMakeDocument(
"name", "monila",
"sizeOnDisk", int64(13516800),
"empty", false,
),
types.MustMakeDocument(
"name", "pagila",
"sizeOnDisk", int64(7127040),
"empty", false,
),
types.MustMakeDocument(
"name", "test",
"sizeOnDisk", int64(0),
"empty", true,
),
},
"totalSize", int64(30114595),
"totalSizeMb", int64(28),
"ok", float64(1),
),
compareFunc: func(t testing.TB, expected, actual any) {
expectedDoc, actualDoc := expected.(types.Document), actual.(types.Document)

testutil.CompareByPath(t, expectedDoc, actualDoc, 1_000_000, "totalSize")
testutil.CompareByPath(t, expectedDoc, actualDoc, 1, "totalSizeMb")

expectedDBs := testutil.GetByPath(t, expectedDoc, "databases").(types.Array)
actualDBs := testutil.GetByPath(t, actualDoc, "databases").(types.Array)
require.Equal(t, len(expectedDBs), len(actualDBs))
for i, actualDB := range actualDBs {
expectedDB := expectedDBs[i]
testutil.CompareByPath(t, expectedDB, actualDB, 100_000, "sizeOnDisk")
}

assert.Equal(t, expectedDoc, actualDoc)
},
},

"ServerStatus": {
req: types.MustMakeDocument(
"serverStatus", int32(1),
),
resp: types.MustMakeDocument(
"version", "5.0.42",
Expand All @@ -672,7 +613,9 @@ func TestReadOnlyHandlers(t *testing.T) {

for _, schema := range []string{"monila", "pagila"} {
t.Run(schema, func(t *testing.T) {
tc.req.Set("$db", schema)
if tc.reqSetDB {
tc.req.Set("$db", schema)
}

reqHeader := wire.MsgHeader{
RequestID: 1,
Expand All @@ -690,7 +633,11 @@ func TestReadOnlyHandlers(t *testing.T) {

actual, err := resBody.(*wire.OpMsg).Document()
require.NoError(t, err)
assert.Equal(t, tc.resp, actual)
if tc.compareFunc == nil {
assert.Equal(t, tc.resp, actual)
} else {
tc.compareFunc(t, tc.resp, actual)
}
})
}
})
Expand Down
31 changes: 31 additions & 0 deletions internal/util/testutil/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,34 @@
package testutil

import (
"fmt"
"strconv"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/FerretDB/FerretDB/internal/types"
)

func GetByPath(tb testing.TB, str any, path ...string) any {
tb.Helper()

var res any
var err error
switch str := str.(type) {
case types.Array:
res, err = str.GetByPath(path...)
case types.Document:
res, err = str.GetByPath(path...)
default:
err = fmt.Errorf("can't access %T by path", str)
}

require.NoError(tb, err)
return res
}

func SetByPath(tb testing.TB, str any, value any, path ...string) {
tb.Helper()

Expand Down Expand Up @@ -57,3 +77,14 @@ func SetByPath(tb testing.TB, str any, value any, path ...string) {
}
}
}

func CompareByPath(tb testing.TB, expected, actual any, delta float64, path ...string) {
tb.Helper()

expectedV := GetByPath(tb, expected, path...)
actualV := GetByPath(tb, actual, path...)
assert.IsType(tb, expectedV, actualV)
assert.InDelta(tb, expectedV, actualV, delta)

SetByPath(tb, expected, actualV, path...)
}

0 comments on commit 3b6aa3a

Please sign in to comment.