watchtower/pkg/container/mocks/ApiServer.go
nils måsén 26fba69169 test: refactor client tests
should not be explicitly telling what they are testing and the requirements
fixed the test data so that it doesn't contain discrepancies
fully reset the mock client (no shared state) and only support the calls that is expected
2021-11-01 19:26:41 +01:00

125 lines
3.9 KiB
Go

package mocks
import (
"encoding/json"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
)
func getMockJSONFile(relPath string) ([]byte, error) {
absPath, _ := filepath.Abs(relPath)
buf, err := ioutil.ReadFile(absPath)
if err != nil {
// logrus.WithError(err).WithField("file", absPath).Error(err)
return nil, err
}
return buf, nil
}
func RespondWithJSONFile(relPath string, statusCode int, optionalHeader ...http.Header) http.HandlerFunc {
handler, err := respondWithJSONFile(relPath, statusCode, optionalHeader...)
ExpectWithOffset(1, err).ShouldNot(HaveOccurred())
return handler
}
func respondWithJSONFile(relPath string, statusCode int, optionalHeader ...http.Header) (http.HandlerFunc, error) {
buf, err := getMockJSONFile(relPath)
if err != nil {
return nil, err
}
return ghttp.RespondWith(statusCode, buf, optionalHeader...), nil
}
func GetContainerHandlers(containerFiles ...string) []http.HandlerFunc {
handlers := make([]http.HandlerFunc, 0, len(containerFiles)*2)
for _, file := range containerFiles {
handlers = append(handlers, getContainerHandler(file))
// Also append the image request since that will be called for every container
if file == "running" {
// The "running" container is the only one using image02
handlers = append(handlers, getImageHandler(1))
} else {
handlers = append(handlers, getImageHandler(0))
}
}
return handlers
}
func createFilterArgs(statuses []string) filters.Args {
args := filters.NewArgs()
for _, status := range statuses {
args.Add("status", status)
}
return args
}
var containerFileIds = map[string]string{
"stopped": "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b65",
"watchtower": "3d88e0e3543281c747d88b27e246578b65ae8964ba86c7cd7522cf84e0978134",
"running": "b978af0b858aa8855cce46b628817d4ed58e58f2c4f66c9b9c5449134ed4c008",
"restarting": "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b67",
}
var imageIds = []string{
"sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa",
"sha256:19d07168491a3f9e2798a9bed96544e34d57ddc4757a4ac5bb199dea896c87fd",
}
func getContainerHandler(file string) http.HandlerFunc {
id, ok := containerFileIds[file]
failTestUnless(ok)
return ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", HaveSuffix("/containers/%v/json", id)),
RespondWithJSONFile(fmt.Sprintf("./mocks/data/container_%v.json", file), http.StatusOK),
)
}
func ListContainersHandler(statuses ...string) http.HandlerFunc {
filterArgs := createFilterArgs(statuses)
bytes, err := filterArgs.MarshalJSON()
ExpectWithOffset(1, err).ShouldNot(HaveOccurred())
query := url.Values{
"limit": []string{"0"},
"filters": []string{string(bytes)},
}
return ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", HaveSuffix("containers/json"), query.Encode()),
respondWithFilteredContainers(filterArgs),
)
}
func respondWithFilteredContainers(filters filters.Args) http.HandlerFunc {
containersJson, err := getMockJSONFile("./mocks/data/containers.json")
ExpectWithOffset(2, err).ShouldNot(HaveOccurred())
var filteredContainers []types.Container
var containers []types.Container
ExpectWithOffset(2, json.Unmarshal(containersJson, &containers)).To(Succeed())
for _, v := range containers {
for _, key := range filters.Get("status") {
if v.State == key {
filteredContainers = append(filteredContainers, v)
}
}
}
return ghttp.RespondWithJSONEncoded(http.StatusOK, filteredContainers)
}
func getImageHandler(index int) http.HandlerFunc {
return ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", HaveSuffix("/images/%v/json", imageIds[index])),
RespondWithJSONFile(fmt.Sprintf("./mocks/data/image%02d.json", index+1), http.StatusOK),
)
}
func failTestUnless(ok bool) {
ExpectWithOffset(2, ok).To(BeTrue(), "test setup failed")
}