mongotest

package module
v0.2.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2022 License: MIT Imports: 37 Imported by: 0

README

mongotest

mongotest was written with the goal of creating simple, segregated testing mongo environments. The only requirement to use mongotest is to have the docker daemon running (should you wish to use the docker container method).

Example:

func TestFoo(t *testing.T) {
  useDockerContainer := true
  // conn is a mongotest.TestConnection object which embeds an easymongo.Connection object
  conn, err := mongotest.NewTestConnection(useDockerContainer)
  is.NoError(err)
  t.Cleanup(func() {
    conn.KillMongoContainer()
  })
  // Insert a document
  type enemy struct {
    ID   primitive.ObjectID  `bson:"_id"`
    Name string              `bson:"name"`
  }
  id, err := conn.Insert().One(&enemy{
    ID:   primitive.NewObjectID(),
    Name: "The Joker",
  })
}

The above code will spin-up a docker mongo container on a randomly assigned port, insert a document into the collection and when the test exits, the mongo container will be destroyed. In order to ensure that the docker container gracefully exits, it is recommended to run the .KillMongoContainer() command in a t.Cleanup() function.

If you choose to use a defer (rather than t.Cleanup()), note that it is (presently) not possible to automatically cleanup the created container should the test panic.

* I was wondering if a compiler flag might be the way to go to always ensure clean-up, but I truly welcome input on how this might be accomplished cleanly.

Cleaning up rogue containers

Containers are created with a label of mongotest=regression. If you run docker ps and note a lot of unreaped mongo containers, try running:

    docker rm --force $(docker ps -a -q --filter=label=mongotest=regression)

This will thwack any containers that were created via mongotest.

Documentation

Overview

Package mongotest provides helpers for running regressions using mongo. You can find helpers for: - running a database using docker - TODO: importing data to the DB from files - TODO: exporting data from the DB to a file - TODO: cleaning up a database

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrFailedToConnectToDockerDaemon denotes that we couldn't connect to the docker daemon
	// running locally on the machine.
	ErrFailedToConnectToDockerDaemon = errors.New("could not connect to docker daemon")
	// ErrNoAvailablePorts denotes that no ports were available for binding the docker mongo instance to
	ErrNoAvailablePorts = errors.New("no ports are available to bind the docker mongo instance to")
	// ErrMongoContainerAlreadyRunning
	ErrMongoContainerAlreadyRunning = errors.New("the mongo container is already running - an attempt was made to call it a second time")
)
View Source
var ErrNotImplemented = errors.New("function not yet implemented")

Functions

func EasyMongoWithContainer added in v0.0.25

func EasyMongoWithContainer(f func(c *easymongo.Connection) error) (err error)

EasyMongoWithContainer spawns a docker container on an available port, connects to the mongo database, runs the provided function, then kills the mongo container as it exits. A note that the function isn't actually executed inside the container, instead a connection is established to the mongo server from the host system.

Example
type fooRecord struct {
	Name string `bson:"name"`
}
// Spawn a new container with a unique connection
err := EasyMongoWithContainer(func(c *easymongo.Connection) error {
	// Connect to the DB and insert a test record
	coll := c.D("exampleDB").C("exampleCollection")
	record := fooRecord{
		Name: "Topher!",
	}
	_, err := coll.Insert().One(&record)
	if err != nil {
		return err
	}
	// Try to look-up that record
	lookupRecord := fooRecord{}
	err = coll.Find(primitive.M{"name": record.Name}).One(&lookupRecord)
	if err != nil {
		return err
	}
	// Print out the name of that record
	fmt.Println(lookupRecord.Name)
	return nil
})
if err != nil {
	fmt.Println("Issue running queries:")
	fmt.Println(err)
}
Output:

Topher!

func GenerateCARoot added in v0.0.25

func GenerateCARoot() (rootCert *x509.Certificate, rootPEM []byte, privKey *rsa.PrivateKey)

GenerateCARoot generates a new CA root PEM file and private key Huge thanks to Mattemagikern for publishing this code in a random gist https://gist.github.com/Mattemagikern/328cdd650be33bc33105e26db88e487d

func GetAvailablePort

func GetAvailablePort() (port int, err error)

GetAvailablePort returns an available port on the system.

func MongoClientWithContainer added in v0.0.25

func MongoClientWithContainer(f func(m *mongo.Client) error) error

MongoClientWithContainer spawns a docker container on an available port, connects to the mongo database, runs the provided function, then kills the mongo container as it exits. A note that the function isn't actually executed inside the container, instead a connection is established to the mongo server from the host system.

Example
type fooRecord struct {
	Name string `bson:"name"`
}
// Spawn a new container with a unique connection
err := MongoClientWithContainer(func(c *mongo.Client) error {
	// Connect to the DB and insert a test record
	coll := c.Database("exampleDB").Collection("exampleCollection")
	record := fooRecord{
		Name: "Topher!",
	}
	_, err := coll.InsertOne(context.Background(), &record)
	if err != nil {
		return err
	}
	// Try to look-up that record
	lookupRecord := fooRecord{}
	err = coll.FindOne(context.Background(), primitive.M{"name": record.Name}).Decode(
		&lookupRecord)
	if err != nil {
		return err
	}
	// Print out the name of that record
	fmt.Println(lookupRecord.Name)
	return nil
})
if err != nil {
	fmt.Println("Issue running queries:")
	fmt.Println(err)
}
Output:

Topher!

func ReapRunningContainers added in v0.2.0

func ReapRunningContainers()

Types

type DatabaseExporter added in v0.0.25

type DatabaseExporter struct {
	// contains filtered or unexported fields
}

DatabaseExporter is a wrapper to enable easily exporting a live database TODO: Move this into easymongo

func (*DatabaseExporter) Bytes added in v0.0.25

func (de *DatabaseExporter) Bytes() ([]byte, error)

TODO: Bytes

func (*DatabaseExporter) CSVFile added in v0.0.25

func (de *DatabaseExporter) CSVFile() (fpath string, err error)

func (*DatabaseExporter) Collection added in v0.0.25

func (de *DatabaseExporter) Collection(c string) *DatabaseExporter

func (*DatabaseExporter) Database added in v0.0.25

func (de *DatabaseExporter) Database(d string) *DatabaseExporter

func (*DatabaseExporter) Filepath added in v0.0.25

func (de *DatabaseExporter) Filepath(f string) *DatabaseExporter

func (*DatabaseExporter) Limit added in v0.0.25

func (de *DatabaseExporter) Limit(i int) *DatabaseExporter

func (*DatabaseExporter) Query added in v0.0.25

func (*DatabaseExporter) Skip added in v0.0.25

func (de *DatabaseExporter) Skip(i int) *DatabaseExporter

func (*DatabaseExporter) Sort added in v0.0.25

func (*DatabaseExporter) String added in v0.0.25

func (de *DatabaseExporter) String() (string, error)

TODO: String

func (*DatabaseExporter) ToJSONFile added in v0.0.25

func (de *DatabaseExporter) ToJSONFile(prettify, jsonArray, relaxedJSON, compressToGZIP bool) (fpath string, err error)

ToJSONFile writes a JSON formatted file to disk and returns the path the file was written to

func (*DatabaseExporter) UsingStringBuilder added in v0.0.25

func (de *DatabaseExporter) UsingStringBuilder()

TODO: UsingStringBuilder

type MongoTestError

type MongoTestError struct {
	// contains filtered or unexported fields
}

func NewMongoTestError

func NewMongoTestError(err error) *MongoTestError

func (*MongoTestError) Unwrap

func (mte *MongoTestError) Unwrap() error

type TestConnection

type TestConnection struct {
	*easymongo.Connection
	// contains filtered or unexported fields
}

TestConnection contains helpers for creating your own tests with mongo. Each TestConnection corresponds 1-to-1 with a docker container. Each docker container is hosted on a unique port.

func NewReplicaSetContainer added in v0.2.0

func NewReplicaSetContainer(rsName string) (*TestConnection, error)

NewReplicaSetContainer spawns a new docker container and configures it as a 1 member replicaset. The resulting connection is returned.

func NewTestConnection

func NewTestConnection(spinupDockerContainer bool) (*TestConnection, error)

NewTestConnection is the standard method for initializing a TestConnection - it has a side-effect of spawning a new docker container if spinupDockerContainer is set to true. Note that the first time this is called on a new system, the mongo docker container will be pulled. Any subsequent calls on the system should succeed without calls to pull. If spinupDockerContainer is False, then no docker shenanigans occur, instead an attempt is made to connect to a locally running mongo instance (e.g. mongodb://127.0.0.1:27017).

func (*TestConnection) DatabaseExporter added in v0.0.25

func (testConn *TestConnection) DatabaseExporter(dbName, collectionName string) *DatabaseExporter

DatabaseExporter returns an object which can be used to export a DB TODO: Move to easymongo? Some of these seem very close to Query{}

func (*TestConnection) ExecCommandInMongoContainer added in v0.2.0

func (tc *TestConnection) ExecCommandInMongoContainer(cmd []string) (output string, err error)

ExecCommandInMongoContainer attaches to the mongo container and executes the provided command In the case that an error occurs either spawning the docker context or executing the command, an error will be returned. In the case that an error is returned from a malformed/bad command, then output is also populated. It is recommended not to use mongo --eval here as the script does not seem to reliably run. Instead, it's recommended to use

func (*TestConnection) KillMongoContainer

func (tc *TestConnection) KillMongoContainer() (err error)

KillMongoContainer tears down the specified container This is called as part of a finalizer automatically. There is no guarantee that the finalizer will run prior to a program exiting, but a best attempt has been made

func (*TestConnection) MongoContainerID

func (tc *TestConnection) MongoContainerID() string

MongoContainerID returns the ID of the running docker container If no container is running, an empty string will be returned.

func (*TestConnection) RunMongoScriptOnContainer added in v0.2.0

func (tc *TestConnection) RunMongoScriptOnContainer(mongoScript string) (output string, err error)

RunMongoScriptOnContainer takes a string representing a mongo JS script. This can have new lines. This must

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL