@@ -3,12 +3,15 @@ package mocks
33import (
44 "encoding/json"
55 "fmt"
6- "io/ioutil "
6+ "github.com/onsi/ginkgo "
77 "net/http"
88 "net/url"
9+ "os"
910 "path/filepath"
1011 "strings"
1112
13+ t "github.com/containrrr/watchtower/pkg/types"
14+
1215 "github.com/docker/docker/api/types"
1316 "github.com/docker/docker/api/types/filters"
1417 O "github.com/onsi/gomega"
@@ -17,10 +20,9 @@ import (
1720
1821func getMockJSONFile (relPath string ) ([]byte , error ) {
1922 absPath , _ := filepath .Abs (relPath )
20- buf , err := ioutil .ReadFile (absPath )
23+ buf , err := os .ReadFile (absPath )
2124 if err != nil {
22- // logrus.WithError(err).WithField("file", absPath).Error(err)
23- return nil , err
25+ return nil , fmt .Errorf ("mock JSON file %q not found: %e" , absPath , err )
2426 }
2527 return buf , nil
2628}
@@ -41,19 +43,22 @@ func respondWithJSONFile(relPath string, statusCode int, optionalHeader ...http.
4143}
4244
4345// GetContainerHandlers returns the handlers serving lookups for the supplied container mock files
44- func GetContainerHandlers (containerFiles ... string ) []http.HandlerFunc {
45- handlers := make ([]http.HandlerFunc , 0 , len (containerFiles ) * 2 )
46- for _ , file := range containerFiles {
47- handlers = append (handlers , getContainerFileHandler (file ))
46+ func GetContainerHandlers (containerRefs ... * ContainerRef ) []http.HandlerFunc {
47+ handlers := make ([]http.HandlerFunc , 0 , len (containerRefs ) * 3 )
48+ for _ , containerRef := range containerRefs {
49+ handlers = append (handlers , getContainerFileHandler (containerRef ))
4850
49- // Also append the image request since that will be called for every container
50- if file == "running" {
51- // The "running" container is the only one using image02
52- handlers = append (handlers , getImageFileHandler (1 ))
53- } else {
54- handlers = append (handlers , getImageFileHandler (0 ))
51+ // Also append any containers that the container references, if any
52+ for _ , ref := range containerRef .references {
53+ handlers = append (handlers , getContainerFileHandler (ref ))
5554 }
55+
56+ // Also append the image request since that will be called for every container
57+ handlers = append (handlers , getImageHandler (containerRef .image .id ,
58+ RespondWithJSONFile (containerRef .image .getFileName (), http .StatusOK ),
59+ ))
5660 }
61+
5762 return handlers
5863}
5964
@@ -65,24 +70,90 @@ func createFilterArgs(statuses []string) filters.Args {
6570 return args
6671}
6772
68- var containerFileIds = map [string ]string {
69- "stopped" : "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b65" ,
70- "watchtower" : "3d88e0e3543281c747d88b27e246578b65ae8964ba86c7cd7522cf84e0978134" ,
71- "running" : "b978af0b858aa8855cce46b628817d4ed58e58f2c4f66c9b9c5449134ed4c008" ,
72- "restarting" : "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b67" ,
73+ var defaultImage = imageRef {
74+ // watchtower
75+ id : t .ImageID ("sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa" ),
76+ file : "default" ,
77+ }
78+
79+ var Watchtower = ContainerRef {
80+ name : "watchtower" ,
81+ id : "3d88e0e3543281c747d88b27e246578b65ae8964ba86c7cd7522cf84e0978134" ,
82+ image : & defaultImage ,
83+ }
84+ var Stopped = ContainerRef {
85+ name : "stopped" ,
86+ id : "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b65" ,
87+ image : & defaultImage ,
88+ }
89+ var Running = ContainerRef {
90+ name : "running" ,
91+ id : "b978af0b858aa8855cce46b628817d4ed58e58f2c4f66c9b9c5449134ed4c008" ,
92+ image : & imageRef {
93+ // portainer
94+ id : t .ImageID ("sha256:19d07168491a3f9e2798a9bed96544e34d57ddc4757a4ac5bb199dea896c87fd" ),
95+ file : "running" ,
96+ },
97+ }
98+ var Restarting = ContainerRef {
99+ name : "restarting" ,
100+ id : "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b67" ,
101+ image : & defaultImage ,
102+ }
103+
104+ var netSupplierOK = ContainerRef {
105+ id : "25e75393800b5c450a6841212a3b92ed28fa35414a586dec9f2c8a520d4910c2" ,
106+ name : "net_supplier" ,
107+ image : & imageRef {
108+ // gluetun
109+ id : t .ImageID ("sha256:c22b543d33bfdcb9992cbef23961677133cdf09da71d782468ae2517138bad51" ),
110+ file : "net_producer" ,
111+ },
112+ }
113+ var netSupplierNotFound = ContainerRef {
114+ id : NetSupplierNotFoundID ,
115+ name : netSupplierOK .name ,
116+ isMissing : true ,
117+ }
118+
119+ // NetConsumerOK is used for testing `container` networking mode
120+ // returns a container that consumes an existing supplier container
121+ var NetConsumerOK = ContainerRef {
122+ id : "1f6b79d2aff23244382026c76f4995851322bed5f9c50631620162f6f9aafbd6" ,
123+ name : "net_consumer" ,
124+ image : & imageRef {
125+ id : t .ImageID ("sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8" ), // nginx
126+ file : "net_consumer" ,
127+ },
128+ references : []* ContainerRef {& netSupplierOK },
73129}
74130
75- var imageIds = []string {
76- "sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa" ,
77- "sha256:19d07168491a3f9e2798a9bed96544e34d57ddc4757a4ac5bb199dea896c87fd" ,
131+ // NetConsumerInvalidSupplier is used for testing `container` networking mode
132+ // returns a container that references a supplying container that does not exist
133+ var NetConsumerInvalidSupplier = ContainerRef {
134+ id : NetConsumerOK .id ,
135+ name : "net_consumer-missing_supplier" ,
136+ image : NetConsumerOK .image ,
137+ references : []* ContainerRef {& netSupplierNotFound },
78138}
79139
80- func getContainerFileHandler (file string ) http.HandlerFunc {
81- id , ok := containerFileIds [file ]
82- failTestUnless (ok )
140+ const NetSupplierNotFoundID = "badc1dbadc1dbadc1dbadc1dbadc1dbadc1dbadc1dbadc1dbadc1dbadc1dbadc"
141+ const NetSupplierContainerName = "/wt-contnet-producer-1"
142+
143+ func getContainerFileHandler (cr * ContainerRef ) http.HandlerFunc {
144+
145+ if cr .isMissing {
146+ return containerNotFoundResponse (string (cr .id ))
147+ }
148+
149+ containerFile , err := cr .getContainerFile ()
150+ if err != nil {
151+ ginkgo .Fail (fmt .Sprintf ("Failed to get container mock file: %v" , err ))
152+ }
153+
83154 return getContainerHandler (
84- id ,
85- RespondWithJSONFile (fmt . Sprintf ( "./mocks/data/container_%v.json" , file ) , http .StatusOK ),
155+ string ( cr . id ) ,
156+ RespondWithJSONFile (containerFile , http .StatusOK ),
86157 )
87158}
88159
@@ -104,7 +175,7 @@ func GetContainerHandler(containerID string, containerInfo *types.ContainerJSON)
104175
105176// GetImageHandler mocks the GET images/{id}/json endpoint
106177func GetImageHandler (imageInfo * types.ImageInspect ) http.HandlerFunc {
107- return getImageHandler (imageInfo .ID , ghttp .RespondWithJSONEncoded (http .StatusOK , imageInfo ))
178+ return getImageHandler (t . ImageID ( imageInfo .ID ) , ghttp .RespondWithJSONEncoded (http .StatusOK , imageInfo ))
108179}
109180
110181// ListContainersHandler mocks the GET containers/json endpoint, filtering the returned containers based on statuses
@@ -138,23 +209,13 @@ func respondWithFilteredContainers(filters filters.Args) http.HandlerFunc {
138209 return ghttp .RespondWithJSONEncoded (http .StatusOK , filteredContainers )
139210}
140211
141- func getImageHandler (imageId string , responseHandler http.HandlerFunc ) http.HandlerFunc {
212+ func getImageHandler (imageId t. ImageID , responseHandler http.HandlerFunc ) http.HandlerFunc {
142213 return ghttp .CombineHandlers (
143214 ghttp .VerifyRequest ("GET" , O .HaveSuffix ("/images/%s/json" , imageId )),
144215 responseHandler ,
145216 )
146217}
147218
148- func getImageFileHandler (index int ) http.HandlerFunc {
149- return getImageHandler (imageIds [index ],
150- RespondWithJSONFile (fmt .Sprintf ("./mocks/data/image%02d.json" , index + 1 ), http .StatusOK ),
151- )
152- }
153-
154- func failTestUnless (ok bool ) {
155- O .ExpectWithOffset (2 , ok ).To (O .BeTrue (), "test setup failed" )
156- }
157-
158219// KillContainerHandler mocks the POST containers/{id}/kill endpoint
159220func KillContainerHandler (containerID string , found FoundStatus ) http.HandlerFunc {
160221 responseHandler := noContentStatusResponse
@@ -180,7 +241,7 @@ func RemoveContainerHandler(containerID string, found FoundStatus) http.HandlerF
180241}
181242
182243func containerNotFoundResponse (containerID string ) http.HandlerFunc {
183- return ghttp .RespondWithJSONEncoded (http .StatusNotFound , struct { message string }{message : "No such container: " + containerID })
244+ return ghttp .RespondWithJSONEncoded (http .StatusNotFound , struct { message string }{message : "No such container: " + string ( containerID ) })
184245}
185246
186247var noContentStatusResponse = ghttp .RespondWith (http .StatusNoContent , nil )
0 commit comments