feat: add Docker Swarm support (MODE=swarm) #4
@@ -56,7 +56,12 @@ func (h *Handlers) Update(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
jobs, err := h.finder.FindJobs(r.Context(), req.Image)
|
||||
requestedImage := req.Image
|
||||
if req.Tag != "" {
|
||||
requestedImage = req.Image + ":" + req.Tag
|
||||
}
|
||||
|
||||
jobs, err := h.finder.FindJobs(r.Context(), requestedImage)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "discovery failed: "+err.Error())
|
||||
return
|
||||
|
||||
@@ -21,9 +21,21 @@ import (
|
||||
type fakeFinder struct {
|
||||
jobs []discovery.Job
|
||||
err error
|
||||
|
||||
// gotImage records the image argument passed to FindJobs, for
|
||||
// assertions on the exact reference the handler built.
|
||||
gotImage string
|
||||
// swarmShaped, when true, makes FindJobs return a Job whose Image
|
||||
// field carries the received image argument, simulating
|
||||
// discovery.SwarmDiscovery.FindJobs.
|
||||
swarmShaped bool
|
||||
}
|
||||
|
||||
func (f *fakeFinder) FindJobs(_ context.Context, _ string) ([]discovery.Job, error) {
|
||||
func (f *fakeFinder) FindJobs(_ context.Context, image string) ([]discovery.Job, error) {
|
||||
f.gotImage = image
|
||||
if f.swarmShaped {
|
||||
return []discovery.Job{{Service: "myapp_web", ServiceID: "svc1", Image: image}}, f.err
|
||||
}
|
||||
return f.jobs, f.err
|
||||
}
|
||||
|
||||
@@ -157,6 +169,42 @@ func TestHealthz_503WhenDockerDown(t *testing.T) {
|
||||
require.Equal(t, http.StatusServiceUnavailable, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdate_FindJobsCalledWithTaggedImage(t *testing.T) {
|
||||
finder := &fakeFinder{}
|
||||
h := api.NewHandlers(finder, &fakeSubmitter{}, &fakePinger{}, "v0.0.0", "abc", "now", nil)
|
||||
body, _ := json.Marshal(api.UpdateRequest{Image: "registry.example.com/myapp", Tag: "v2"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/update", bytes.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
h.Update(w, req)
|
||||
require.Equal(t, "registry.example.com/myapp:v2", finder.gotImage)
|
||||
}
|
||||
|
||||
func TestUpdate_FindJobsCalledWithBareImageWhenNoTag(t *testing.T) {
|
||||
finder := &fakeFinder{}
|
||||
h := api.NewHandlers(finder, &fakeSubmitter{}, &fakePinger{}, "v0.0.0", "abc", "now", nil)
|
||||
body, _ := json.Marshal(api.UpdateRequest{Image: "registry.example.com/myapp"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/update", bytes.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
h.Update(w, req)
|
||||
require.Equal(t, "registry.example.com/myapp", finder.gotImage)
|
||||
}
|
||||
|
||||
func TestUpdate_SwarmModeThreadsTagThroughDiscovery(t *testing.T) {
|
||||
finder := &fakeFinder{swarmShaped: true}
|
||||
h := api.NewHandlers(finder, &fakeSubmitter{}, &fakePinger{}, "v0.0.0", "abc", "now", nil)
|
||||
body, _ := json.Marshal(api.UpdateRequest{Image: "registry.example.com/myapp", Tag: "v2"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/update", bytes.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
h.Update(w, req)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
// The fake Finder's returned Job.Image (as SwarmDiscovery would build
|
||||
// it) reflects the image argument it received from the handler.
|
||||
// Asserting on the captured argument proves the full request ->
|
||||
// discovery flow carries the tag through to what would reach the
|
||||
// SwarmExecutor.
|
||||
require.Equal(t, "registry.example.com/myapp:v2", finder.gotImage)
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
h := api.NewHandlers(&fakeFinder{}, &fakeSubmitter{}, &fakePinger{}, "v1.2.3", "abcdef", "2026-05-22T00:00:00Z", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/version", nil)
|
||||
|
||||
Reference in New Issue
Block a user