First you need to get familiar with the Architecture guide, which explains from a high perspective how everything works together.
After our experience building the Enterprise MongoDB Kubernetes Operator, we have realized that is is very important to have a clean environment to work, and as such we have adopted a strategy that makes it easier for everyone to contribute.
This strategy is based on using
operator-sdk
for running
the tests, and making the test-runner itself run as a Kubernetes Pod. This
makes it easier to run the tests in environments with access to a Kubernetes
cluster with no go toolchain installed locally, making it easier to reproduce
our local working environments in CI/CD systems.
The operator itself consists of 1 image, that has all the operational logic to deploy and maintain the MongoDB resources in your cluster.
The operator deploys MongoDB in Pods (via a higher-level resource, a StatefulSet), on each Pod there will be multiple images coexisting during the lifetime of the MongoDB server.
-
Agent image: This image includes a binary provided by MongoDB that handles the local operation of a MongoDB server given a series of configurations provided by the operator. The configuration exists as a ConfigMap that's created by the operator and mounted in the Agent's Pod.
-
MongoDB image: Docker image that includes the MongoDB server.
-
Version upgrade post-start hook image: This image includes a binary that helps orchestrate the restarts of the MongoDB Replica Set members, in particular, when dealing with version upgrades, which requires a very precise set of operations to allow for seamless upgrades and downgrades, with no downtime.
Each Pod holds a member of a Replica Set, and each Pod has different components, each one of them in charge of some part of the lifecycle of the MongoDB database.
The operator is built using the latest stable operator-sdk
and golang
. We use a simple
json file that describe some local options that you need to set for the testing environment
to be able to run properly. Create a json file with the following content:
{
"namespace": "default",
"repo_url": "localhost:5000",
"operator_image": "mongodb-kubernetes-operator",
"e2e_image": "e2e",
"version_upgrade_hook_image": "version_upgrade_hook",
"testrunner_image": "test-runner"
}
The namespace
attribute sets the Kubernetes namespace to be used for running
your tests. The repo_url
sets the Docker registry. In my case I have a
local-config.json
file in the root of this repo. For the e2e tests to pick
this file, set the MONGODB_COMMUNITY_CONFIG
env variable to the absolute path
of this file.
Please see here to see how to build and deploy the operator locally.
The build process consist in multiple Docker images being built, you need to specify where you want the locally build images to be pushed. The Docker registry needs to be accessible from your Kubernetes cluster.
You can change the namespace used for tests, if you are using Kind
, for
instance, you can leave this as default
.
The test runner is a Python script, in order to use it a virtualenv needs to be
created. The dependencies of the Python environment are described, as usual, in
a requirements.txt
file:
python -m venv venv
source venv/bin/activate
python -m pip install -r requirements.txt
Unit tests should be run from the root of the project with:
go test ./pkg/...
We have built a simple mechanism to run E2E tests on your cluster using a runner that deploys a series of Kubernetes objects, runs them, and awaits for their completion. If the objects complete with a Success status, it means that the tests were run successfully.
The available tests can be found in the tests/e2e
directory, at the time of this
writting we have:
$ ls -l test/e2e
replica_set
replica_set_change_version
replica_set_readiness_probe
replica_set_scale
...
The tests should run individually using the runner like this:
# python scripts/dev/e2e.py --test <test-name>
# for example
python scripts/dev/e2e.py --test replica_set
This will run the replica_set
E2E test which is a simple test that installs a
MongoDB Replica Set and asserts that the deployed server can be connected to.
The python script has several flags to control its behaviour, please run
python scripts/dev/e2e.py --help
to get a list.
When you run a test locally, if the operator-sdk-test
pod is present, you will have to
first manually delete it; failing to do so will cause the test-runner
pod to fail.
You can start with replica_set
test as an starting point to write a new test.
The tests are written using operator-sdk
.
Adding a new test is as easy as to create a new directory in test/e2e
with the
new E2E test, and to run them:
python scripts/dev/e2e.py --test <new-test>
To set up the pre-commit hooks, please create symbolic links from the provided hooks:
-
Navigate to your
.git/hooks
directory:cd .git/hooks
-
Create a symlink for every file in the
scripts/git-hooks
directory:ln -s -f ../../scripts/git-hooks/* .
You can find it here. This will be required when creating a PR against this repo!