Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"task_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/aegis/conf:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/up/api/v1:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"rpc_mock.go",
"task.go",
],
importpath = "go-common/app/admin/main/aegis/dao/rpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/aegis/conf:go_default_library",
"//app/admin/main/aegis/model:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/relation/rpc/client:go_default_library",
"//app/service/main/up/api/v1:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"@org_golang_google_grpc//:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,71 @@
package rpc
import (
"context"
"go-common/app/admin/main/aegis/conf"
account "go-common/app/service/main/account/api"
relmod "go-common/app/service/main/relation/model"
relrpc "go-common/app/service/main/relation/rpc/client"
uprpc "go-common/app/service/main/up/api/v1"
"google.golang.org/grpc"
)
// Dao dao
type Dao struct {
c *conf.Config
//gorpc
relRPC RelationRPC
//grpc
AccountClient AccRPC
UpClient UpRPC
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
}
if c.Debug != "local" {
dao.relRPC = relrpc.New(c.RPC.Rel)
var err error
if dao.AccountClient, err = account.NewClient(c.GRPC.AccRPC); err != nil {
panic(err)
}
if dao.UpClient, err = uprpc.NewClient(c.GRPC.UpRPC); err != nil {
panic(err)
}
}
return
}
// Close close the resource.
func (d *Dao) Close() {
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
return nil
}
//RelationRPC .
type RelationRPC interface {
Stats(c context.Context, arg *relmod.ArgMids) (res map[int64]*relmod.Stat, err error)
}
//AccRPC .
type AccRPC interface {
Info3(ctx context.Context, in *account.MidReq, opts ...grpc.CallOption) (*account.InfoReply, error)
Cards3(ctx context.Context, in *account.MidsReq, opts ...grpc.CallOption) (*account.CardsReply, error)
ProfileWithStat3(ctx context.Context, in *account.MidReq, opts ...grpc.CallOption) (*account.ProfileStatReply, error)
}
//UpRPC .
type UpRPC interface {
UpSpecial(ctx context.Context, in *uprpc.UpSpecialReq, opts ...grpc.CallOption) (*uprpc.UpSpecialReply, error)
UpsSpecial(ctx context.Context, in *uprpc.UpsSpecialReq, opts ...grpc.CallOption) (*uprpc.UpsSpecialReply, error)
UpGroups(ctx context.Context, in *uprpc.NoArgReq, opts ...grpc.CallOption) (*uprpc.UpGroupsReply, error)
}

View File

@@ -0,0 +1,132 @@
package rpc
import (
"context"
"flag"
"fmt"
"os"
"testing"
"go-common/app/admin/main/aegis/conf"
api "go-common/app/service/main/account/api"
relmod "go-common/app/service/main/relation/model"
uprpc "go-common/app/service/main/up/api/v1"
"github.com/golang/mock/gomock"
)
var (
d *Dao
cntx context.Context
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.aegis-admin")
flag.Set("conf_token", "cad913269be022e1eb8c45a8d5408d78")
flag.Set("tree_id", "60977")
flag.Set("conf_version", "1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/aegis-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(fmt.Sprintf("conf.Init() error(%v)", err))
}
d = New(conf.Conf)
cntx = context.TODO()
os.Exit(m.Run())
}
var (
_Mid = int64(0)
_Mids = []int64{0, 1, 2}
)
func WithDao(t *testing.T, f func(d *Dao)) func() {
return func() {
mockCtrl := gomock.NewController(t)
accMock := NewMockAccRPC(mockCtrl)
d.AccountClient = accMock
accMock.EXPECT().Cards3(gomock.Any(), &api.MidsReq{Mids: _Mids}).Return(&api.CardsReply{Cards: map[int64]*api.Card{
10086: {
Mid: _Mid,
},
}}, nil).AnyTimes()
relMock := NewMockRelationRPC(mockCtrl)
d.relRPC = relMock
relMock.EXPECT().Stats(gomock.Any(), &relmod.ArgMids{Mids: _Mids}).Return(map[int64]*relmod.Stat{
10086: {
Mid: 10086,
},
}, nil)
f(d)
mockCtrl.Finish()
}
}
func WithMockAccount(t *testing.T, f func(d *Dao)) func() {
return func() {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
accMock := NewMockAccRPC(mockCtrl)
d.AccountClient = accMock
accMock.EXPECT().Info3(gomock.Any(), &api.MidReq{Mid: _Mid}).Return(&api.InfoReply{Info: &api.Info{
Mid: 10086,
}}, nil).AnyTimes()
accMock.EXPECT().Cards3(gomock.Any(), &api.MidsReq{Mids: _Mids}).Return(&api.CardsReply{Cards: map[int64]*api.Card{
10086: {
Mid: _Mid,
},
}}, nil).AnyTimes()
accMock.EXPECT().ProfileWithStat3(gomock.Any(), &api.MidReq{Mid: _Mid}).Return(&api.ProfileStatReply{
Profile: &api.Profile{
Mid: _Mid,
},
}, nil).AnyTimes()
f(d)
}
}
func WithMockRelation(t *testing.T, f func(d *Dao)) func() {
return func() {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
relMock := NewMockRelationRPC(mockCtrl)
d.relRPC = relMock
relMock.EXPECT().Stats(gomock.Any(), &relmod.ArgMids{Mids: _Mids}).Return(map[int64]*relmod.Stat{
10086: {
Mid: 10086,
},
}, nil)
f(d)
}
}
func WithMockUp(t *testing.T, f func(d *Dao)) func() {
return func() {
upspecial := &uprpc.UpSpecial{GroupIDs: []int64{1}}
upspecialreply := &uprpc.UpSpecialReply{UpSpecial: upspecial}
upspecialsreply := &uprpc.UpsSpecialReply{UpSpecials: map[int64]*uprpc.UpSpecial{0: upspecial}}
upgroupsreply := &uprpc.UpGroupsReply{UpGroups: map[int64]*uprpc.UpGroup{0: {ID: 0}}}
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
upMock := NewMockUpRPC(mockCtrl)
d.UpClient = upMock
upMock.EXPECT().UpSpecial(gomock.Any(), &uprpc.UpSpecialReq{Mid: _Mid}).Return(upspecialreply, nil)
upMock.EXPECT().UpsSpecial(gomock.Any(), &uprpc.UpsSpecialReq{Mids: _Mids}).Return(upspecialsreply, nil)
upMock.EXPECT().UpGroups(gomock.Any(), &uprpc.NoArgReq{}).Return(upgroupsreply, nil)
f(d)
}
}

View File

@@ -0,0 +1,207 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: /Users/danbeiti/go/src/go-common/app/admin/main/aegis/dao/rpc/dao.go
// Package mock is a generated GoMock package.
package rpc
import (
context "context"
reflect "reflect"
api "go-common/app/service/main/account/api"
model "go-common/app/service/main/relation/model"
v1 "go-common/app/service/main/up/api/v1"
gomock "github.com/golang/mock/gomock"
grpc "google.golang.org/grpc"
)
// MockRelationRPC is a mock of RelationRPC interface
type MockRelationRPC struct {
ctrl *gomock.Controller
recorder *MockRelationRPCMockRecorder
}
// MockRelationRPCMockRecorder is the mock recorder for MockRelationRPC
type MockRelationRPCMockRecorder struct {
mock *MockRelationRPC
}
// NewMockRelationRPC creates a new mock instance
func NewMockRelationRPC(ctrl *gomock.Controller) *MockRelationRPC {
mock := &MockRelationRPC{ctrl: ctrl}
mock.recorder = &MockRelationRPCMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockRelationRPC) EXPECT() *MockRelationRPCMockRecorder {
return m.recorder
}
// Stats mocks base method
func (m *MockRelationRPC) Stats(c context.Context, arg *model.ArgMids) (map[int64]*model.Stat, error) {
ret := m.ctrl.Call(m, "Stats", c, arg)
ret0, _ := ret[0].(map[int64]*model.Stat)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Stats indicates an expected call of Stats
func (mr *MockRelationRPCMockRecorder) Stats(c, arg interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockRelationRPC)(nil).Stats), c, arg)
}
// MockAccRPC is a mock of AccRPC interface
type MockAccRPC struct {
ctrl *gomock.Controller
recorder *MockAccRPCMockRecorder
}
// MockAccRPCMockRecorder is the mock recorder for MockAccRPC
type MockAccRPCMockRecorder struct {
mock *MockAccRPC
}
// NewMockAccRPC creates a new mock instance
func NewMockAccRPC(ctrl *gomock.Controller) *MockAccRPC {
mock := &MockAccRPC{ctrl: ctrl}
mock.recorder = &MockAccRPCMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockAccRPC) EXPECT() *MockAccRPCMockRecorder {
return m.recorder
}
// Info3 mocks base method
func (m *MockAccRPC) Info3(ctx context.Context, in *api.MidReq, opts ...grpc.CallOption) (*api.InfoReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Info3", varargs...)
ret0, _ := ret[0].(*api.InfoReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Info3 indicates an expected call of Info3
func (mr *MockAccRPCMockRecorder) Info3(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info3", reflect.TypeOf((*MockAccRPC)(nil).Info3), varargs...)
}
// Cards3 mocks base method
func (m *MockAccRPC) Cards3(ctx context.Context, in *api.MidsReq, opts ...grpc.CallOption) (*api.CardsReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Cards3", varargs...)
ret0, _ := ret[0].(*api.CardsReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Cards3 indicates an expected call of Cards3
func (mr *MockAccRPCMockRecorder) Cards3(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cards3", reflect.TypeOf((*MockAccRPC)(nil).Cards3), varargs...)
}
// ProfileWithStat3 mocks base method
func (m *MockAccRPC) ProfileWithStat3(ctx context.Context, in *api.MidReq, opts ...grpc.CallOption) (*api.ProfileStatReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ProfileWithStat3", varargs...)
ret0, _ := ret[0].(*api.ProfileStatReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ProfileWithStat3 indicates an expected call of ProfileWithStat3
func (mr *MockAccRPCMockRecorder) ProfileWithStat3(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProfileWithStat3", reflect.TypeOf((*MockAccRPC)(nil).ProfileWithStat3), varargs...)
}
// MockUpRPC is a mock of UpRPC interface
type MockUpRPC struct {
ctrl *gomock.Controller
recorder *MockUpRPCMockRecorder
}
// MockUpRPCMockRecorder is the mock recorder for MockUpRPC
type MockUpRPCMockRecorder struct {
mock *MockUpRPC
}
// NewMockUpRPC creates a new mock instance
func NewMockUpRPC(ctrl *gomock.Controller) *MockUpRPC {
mock := &MockUpRPC{ctrl: ctrl}
mock.recorder = &MockUpRPCMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockUpRPC) EXPECT() *MockUpRPCMockRecorder {
return m.recorder
}
// UpSpecial mocks base method
func (m *MockUpRPC) UpSpecial(ctx context.Context, in *v1.UpSpecialReq, opts ...grpc.CallOption) (*v1.UpSpecialReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpSpecial", varargs...)
ret0, _ := ret[0].(*v1.UpSpecialReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpSpecial indicates an expected call of UpSpecial
func (mr *MockUpRPCMockRecorder) UpSpecial(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpSpecial", reflect.TypeOf((*MockUpRPC)(nil).UpSpecial), varargs...)
}
// UpsSpecial mocks base method
func (m *MockUpRPC) UpsSpecial(ctx context.Context, in *v1.UpsSpecialReq, opts ...grpc.CallOption) (*v1.UpsSpecialReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpsSpecial", varargs...)
ret0, _ := ret[0].(*v1.UpsSpecialReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpsSpecial indicates an expected call of UpsSpecial
func (mr *MockUpRPCMockRecorder) UpsSpecial(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsSpecial", reflect.TypeOf((*MockUpRPC)(nil).UpsSpecial), varargs...)
}
// UpGroups mocks base method
func (m *MockUpRPC) UpGroups(ctx context.Context, in *v1.NoArgReq, opts ...grpc.CallOption) (*v1.UpGroupsReply, error) {
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpGroups", varargs...)
ret0, _ := ret[0].(*v1.UpGroupsReply)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpGroups indicates an expected call of UpGroups
func (mr *MockUpRPCMockRecorder) UpGroups(ctx, in interface{}, opts ...interface{}) *gomock.Call {
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpGroups", reflect.TypeOf((*MockUpRPC)(nil).UpGroups), varargs...)
}

View File

@@ -0,0 +1,181 @@
package rpc
import (
"context"
"errors"
"go-common/app/admin/main/aegis/model"
acc "go-common/app/service/main/account/api"
relmod "go-common/app/service/main/relation/model"
uprpc "go-common/app/service/main/up/api/v1"
"go-common/library/log"
"go-common/library/net/metadata"
terrors "github.com/pkg/errors"
)
//ERROR
var (
ErrEmptyReply = errors.New("rpc empty reply")
)
// FansCount 粉丝数
func (d *Dao) FansCount(c context.Context, mids []int64) (fans map[int64]int64, err error) {
arg := &relmod.ArgMids{Mids: mids}
stats, err := d.relRPC.Stats(c, arg)
if err != nil {
log.Error("FansCount error(%v)", terrors.WithStack(err))
return
}
fans = make(map[int64]int64)
for mid, item := range stats {
fans[mid] = item.Follower
}
log.Info("FansCount fans(%+v)", fans)
return
}
// UserInfos 提供给资源列表批量查
func (d *Dao) UserInfos(c context.Context, mids []int64) (res map[int64]*model.UserInfo, err error) {
arg1 := &relmod.ArgMids{Mids: mids}
stats, err := d.relRPC.Stats(c, arg1)
if err != nil {
log.Error("Stats error(%v)", terrors.WithStack(err))
return
}
midsReq := &acc.MidsReq{
Mids: mids,
RealIp: metadata.String(c, metadata.RemoteIP),
}
cardsreply, err := d.AccountClient.Cards3(c, midsReq)
if err != nil {
log.Error("Cards3(%+v) error(%v)", mids, terrors.WithStack(err))
return
}
if cardsreply == nil {
err = ErrEmptyReply
log.Error("Cards3(%+v) error(%v)", mids, terrors.WithStack(err))
return
}
cards := cardsreply.Cards
res = make(map[int64]*model.UserInfo)
for _, mid := range mids {
userinfo := &model.UserInfo{Mid: mid}
if card, ok := cards[mid]; ok {
userinfo.Name = card.Name
userinfo.Official = card.Official
}
if stat, ok := stats[mid]; ok {
userinfo.Follower = stat.Follower
}
res[mid] = userinfo
}
return
}
// Profile get account.
func (d *Dao) Profile(c context.Context, mid int64) (userinfo *model.UserInfo, err error) {
if mid <= 0 {
return
}
midReq := &acc.MidReq{
Mid: mid,
RealIp: metadata.String(c, metadata.RemoteIP),
}
res, err := d.AccountClient.ProfileWithStat3(c, midReq)
if err != nil {
log.Error("d.acc.ProfileWithStat3() error(%v) arg(%+v)", err, midReq)
}
if res == nil {
err = ErrEmptyReply
log.Error("ProfileWithStat3(%+v) error(%v)", mid, terrors.WithStack(err))
return
}
userinfo = &model.UserInfo{
Mid: mid,
Follower: res.Follower,
}
if res.Profile != nil {
userinfo.Official = res.Profile.Official
userinfo.Name = res.Profile.Name
}
return
}
// Info3 get Name.
func (d *Dao) Info3(c context.Context, mid int64) (res *acc.Info, err error) {
midReq := &acc.MidReq{
Mid: mid,
RealIp: metadata.String(c, metadata.RemoteIP),
}
info, err := d.AccountClient.Info3(c, midReq)
if err != nil {
log.Error("query info3 failed,mid(%v), err(%v)", mid, err)
return
}
if info == nil {
err = ErrEmptyReply
log.Error("Info3(%+v) error(%v)", mid, terrors.WithStack(err))
return
}
res = info.Info
log.Info("getUserInfo userbase (%v)", res)
return
}
// UpSpecial 分组信息
func (d *Dao) UpSpecial(c context.Context, mid int64) (ups *uprpc.UpSpecial, err error) {
midReq := &uprpc.UpSpecialReq{
Mid: mid,
}
var reply *uprpc.UpSpecialReply
if reply, err = d.UpClient.UpSpecial(c, midReq); err != nil {
log.Error("UpSpecial(%d) error(%v)", mid, terrors.WithStack(err))
return
}
if reply == nil {
err = ErrEmptyReply
log.Error("UpSpecial(%+v) error(%v)", mid, terrors.WithStack(err))
return
}
ups = reply.UpSpecial
return
}
//UpsSpecial 分组信息
func (d *Dao) UpsSpecial(c context.Context, mids []int64) (ups map[int64]*uprpc.UpSpecial, err error) {
midReq := &uprpc.UpsSpecialReq{
Mids: mids,
}
var reply *uprpc.UpsSpecialReply
if reply, err = d.UpClient.UpsSpecial(c, midReq); err != nil {
log.Error("UpsSpecial(%d) error(%v)", mids, terrors.WithStack(err))
return
}
if reply == nil {
err = ErrEmptyReply
log.Error("UpsSpecial(%+v) error(%v)", mids, terrors.WithStack(err))
return
}
ups = reply.UpSpecials
return
}
//UpGroups 所有分组
func (d *Dao) UpGroups(c context.Context) (upgs map[int64]*uprpc.UpGroup, err error) {
noReq := &uprpc.NoArgReq{}
var reply *uprpc.UpGroupsReply
if reply, err = d.UpClient.UpGroups(c, noReq); err != nil {
log.Error("UpGroups error(%v)", terrors.WithStack(err))
return
}
if reply == nil {
err = ErrEmptyReply
log.Error("UpGroups error(%v)", terrors.WithStack(err))
return
}
upgs = reply.UpGroups
return
}

View File

@@ -0,0 +1,53 @@
package rpc
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestRpcFansCount(t *testing.T) {
Convey("FansCount", t, WithMockRelation(t, func(d *Dao) {
res, err := d.FansCount(context.TODO(), _Mids)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
}))
}
func TestRpcUserInfos(t *testing.T) {
Convey("UserInfos", t, WithDao(t, func(d *Dao) {
res, err := d.UserInfos(context.TODO(), _Mids)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
}))
}
func TestRpcProfile(t *testing.T) {
Convey("Profile", t, WithMockAccount(t, func(d *Dao) {
res, err := d.Profile(context.TODO(), _Mid)
So(err, ShouldBeNil)
So(res, ShouldBeNil)
}))
}
func TestRpcInfo3(t *testing.T) {
Convey("Info3", t, WithMockAccount(t, func(d *Dao) {
res, err := d.Info3(context.TODO(), _Mid)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
}))
}
func TestRpcUpSpecial(t *testing.T) {
Convey("UpSpecial", t, WithMockUp(t, func(d *Dao) {
res1, err := d.UpSpecial(context.TODO(), _Mid)
So(err, ShouldBeNil)
So(res1, ShouldNotBeNil)
res2, err := d.UpsSpecial(context.TODO(), _Mids)
So(err, ShouldBeNil)
So(res2, ShouldNotBeNil)
res3, err := d.UpGroups(context.TODO())
So(err, ShouldBeNil)
So(res3, ShouldNotBeNil)
}))
}