1、拉取MongoDB镜像(API方式)
func imagePull(ctx context.Context, refStr string, c *client.Client) {
pullReader, err := c.ImagePull(ctx, refStr, types.ImagePullOptions{
All: false,
RegistryAuth: "",
PrivilegeFunc: nil,
})
if err != nil {
panic(err)
}
defer pullReader.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(pullReader)
s := buf.String()
fmt.Println("imgage info:", s)
}
2、建立测试辅助函数
package mongotesting
import (
"context"
"fmt"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
)
const (
image = "mongo:4.4"
containerPort = "27017/tcp"
)
// RunWithMongoInDocker run the tests with a mongodb instance in a docker container.
func RunWithMongoInDocker(m *testing.M, mongoURI *string) int {
c, err := client.NewEnvClient()
if err != nil {
panic(err)
}
ctx := context.Background()
//创建容器
resp, err := c.ContainerCreate(ctx, &container.Config{
Image: image,
ExposedPorts: nat.PortSet{
containerPort: {},
},
}, &container.HostConfig{
PortBindings: nat.PortMap{
containerPort: []nat.PortBinding{
{
HostIP: "127.0.0.1",
HostPort: "0",
},
},
},
}, nil, nil, "")
if err != nil {
panic(err)
}
containerID := resp.ID
//函数退出之前 remove容器
defer func() {
err = c.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{
Force: true,
})
if err != nil {
panic(err)
}
}()
//启动容器
err = c.ContainerStart(ctx, containerID, types.ContainerStartOptions{})
if err != nil {
panic(err)
}
//查看监听的port
inspRes, err := c.ContainerInspect(ctx, containerID)
if err != nil {
panic(err)
}
hostPort := inspRes.NetworkSettings.Ports[containerPort][0]
//告知外界MongoDB启动的URI
*mongoURI = fmt.Sprintf("mongodb://%s:%s", hostPort.HostIP, hostPort.HostPort)
return m.Run()
}
3、建立测试函数
package dao
import (
"context"
mgo "coolcar/shared/mongo"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const openIDField = "open_id"
// Mongo defines a mongo dao
type Mongo struct {
col *mongo.Collection
newObjID func() primitive.ObjectID // _id生成函数
}
//NewMongo creates a new mongo daos
func NewMongo(db *mongo.Database) *Mongo {
return &Mongo{
col: db.Collection("account"),
newObjID: primitive.NewObjectID,
}
}
//ResolveAccountID resolves an account id from open id.
func (m *Mongo) ResolveAccountID(c context.Context, openID string) (string, error) {
insertedID := m.newObjID()
res := m.col.FindOneAndUpdate(c, bson.M{
openIDField: openID,
}, mgo.SetOnInsert(bson.M{
mgo.IDField: insertedID,
openIDField: openID,
}),
options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After))
if err := res.Err(); err != nil {
return "", fmt.Errorf("cannot findOneAndUpdate:%v", err)
}
var row mgo.ObjID
err := res.Decode(&row)
if err != nil {
return "", fmt.Errorf("cannot decode result: %v", err)
}
return row.ID.Hex(), nil
}