Skip to content

Commit 24a9f85

Browse files
authored
Merge pull request #495 from GSA-TTS/fix-missed-restarts
Post-deploy, explicitly restart apps that were already running
2 parents f291acb + e206680 commit 24a9f85

File tree

2 files changed

+103
-44
lines changed

2 files changed

+103
-44
lines changed

operation/push.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ func (p *AppPushOperation) pushApp(ctx context.Context, space *resource.Space, m
305305
if err != nil {
306306
return nil, err
307307
}
308+
appWasStarted := app.State == "STARTED"
308309

309310
var pkg *resource.Package
310311
// Check if lifecycle is explicitly set in manifest
@@ -342,9 +343,11 @@ func (p *AppPushOperation) pushApp(ctx context.Context, space *resource.Space, m
342343

343344
if p.stopped {
344345
return p.client.Applications.Stop(ctx, app.GUID)
345-
} else {
346-
return p.client.Applications.Start(ctx, app.GUID)
347346
}
347+
if appWasStarted {
348+
return p.client.Applications.Restart(ctx, app.GUID)
349+
}
350+
return p.client.Applications.Start(ctx, app.GUID)
348351
}
349352

350353
func (p *AppPushOperation) applySpaceManifest(ctx context.Context, space *resource.Space, manifest *AppManifest) error {

operation/push_test.go

Lines changed: 98 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,8 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18-
func TestAppPush(t *testing.T) {
19-
serverURL := testutil.SetupFakeAPIServer()
20-
defer testutil.Teardown()
21-
22-
g := testutil.NewObjectJSONGenerator()
23-
org := g.Organization()
24-
space := g.Space()
25-
job := g.Job("COMPLETE")
26-
app := g.Application()
27-
pkg := g.Package("READY")
28-
build := g.Build("STAGED")
29-
droplet := g.Droplet()
30-
dropletAssoc := g.DropletAssociation()
31-
32-
fakeAppZipReader := strings.NewReader("blah zip zip")
33-
var numOfInstances uint = 2
34-
manifest := &AppManifest{
35-
Name: app.Name,
36-
Buildpacks: []string{"java-buildpack-offline"},
37-
38-
AppManifestProcess: AppManifestProcess{
39-
HealthCheckType: "http",
40-
HealthCheckHTTPEndpoint: "/health",
41-
Instances: &numOfInstances,
42-
Memory: "1G",
43-
},
44-
Routes: &AppManifestRoutes{
45-
{
46-
Route: "https://spring-music.cf.apps.example.org",
47-
},
48-
},
49-
Services: &AppManifestServices{{Name: "spring-music-sql"}},
50-
Stack: "cflinuxfs3",
51-
}
52-
53-
testutil.SetupMultiple([]testutil.MockRoute{
18+
func setupAppPushRoutes(t *testing.T, serverURL string, g *testutil.ObjectJSONGenerator, org, space, job, app, pkg, build, droplet, dropletAssoc *testutil.JSONResource, finalAction string) {
19+
routes := []testutil.MockRoute{
5420
{
5521
Method: http.MethodGet,
5622
Endpoint: "/v3/organizations",
@@ -124,13 +90,55 @@ func TestAppPush(t *testing.T) {
12490
Output: g.Single(dropletAssoc.JSON),
12591
Status: http.StatusOK,
12692
},
127-
{
128-
Method: http.MethodPost,
129-
Endpoint: fmt.Sprintf("/v3/apps/%s/actions/start", app.GUID),
130-
Output: g.Single(app.JSON),
131-
Status: http.StatusOK,
93+
}
94+
95+
routes = append(routes, testutil.MockRoute{
96+
Method: http.MethodPost,
97+
Endpoint: fmt.Sprintf("/v3/apps/%s/actions/%s", app.GUID, finalAction),
98+
Output: g.Single(app.JSON),
99+
Status: http.StatusOK,
100+
})
101+
102+
testutil.SetupMultiple(routes, t)
103+
}
104+
105+
func TestAppPushStartsStoppedApp(t *testing.T) {
106+
serverURL := testutil.SetupFakeAPIServer()
107+
defer testutil.Teardown()
108+
109+
g := testutil.NewObjectJSONGenerator()
110+
org := g.Organization()
111+
space := g.Space()
112+
job := g.Job("COMPLETE")
113+
app := g.Application()
114+
app.JSON = strings.Replace(app.JSON, `"state": "STARTED"`, `"state": "STOPPED"`, 1)
115+
pkg := g.Package("READY")
116+
build := g.Build("STAGED")
117+
droplet := g.Droplet()
118+
dropletAssoc := g.DropletAssociation()
119+
120+
fakeAppZipReader := strings.NewReader("blah zip zip")
121+
var numOfInstances uint = 2
122+
manifest := &AppManifest{
123+
Name: app.Name,
124+
Buildpacks: []string{"java-buildpack-offline"},
125+
126+
AppManifestProcess: AppManifestProcess{
127+
HealthCheckType: "http",
128+
HealthCheckHTTPEndpoint: "/health",
129+
Instances: &numOfInstances,
130+
Memory: "1G",
132131
},
133-
}, t)
132+
Routes: &AppManifestRoutes{
133+
{
134+
Route: "https://spring-music.cf.apps.example.org",
135+
},
136+
},
137+
Services: &AppManifestServices{{Name: "spring-music-sql"}},
138+
Stack: "cflinuxfs3",
139+
}
140+
141+
setupAppPushRoutes(t, serverURL, g, org, space, job, app, pkg, build, droplet, dropletAssoc, "start")
134142

135143
c, _ := config.New(serverURL, config.Token("", "fake-refresh-token"), config.SkipTLSValidation())
136144
cf, err := client.New(c)
@@ -144,6 +152,54 @@ func TestAppPush(t *testing.T) {
144152
require.NoError(t, err)
145153
}
146154

155+
func TestAppPushRestartsRunningApp(t *testing.T) {
156+
serverURL := testutil.SetupFakeAPIServer()
157+
defer testutil.Teardown()
158+
159+
g := testutil.NewObjectJSONGenerator()
160+
org := g.Organization()
161+
space := g.Space()
162+
job := g.Job("COMPLETE")
163+
app := g.Application()
164+
pkg := g.Package("READY")
165+
build := g.Build("STAGED")
166+
droplet := g.Droplet()
167+
dropletAssoc := g.DropletAssociation()
168+
169+
fakeAppZipReader := strings.NewReader("blah zip zip")
170+
var numOfInstances uint = 2
171+
manifest := &AppManifest{
172+
Name: app.Name,
173+
Buildpacks: []string{"java-buildpack-offline"},
174+
175+
AppManifestProcess: AppManifestProcess{
176+
HealthCheckType: "http",
177+
HealthCheckHTTPEndpoint: "/health",
178+
Instances: &numOfInstances,
179+
Memory: "1G",
180+
},
181+
Routes: &AppManifestRoutes{
182+
{
183+
Route: "https://spring-music.cf.apps.example.org",
184+
},
185+
},
186+
Services: &AppManifestServices{{Name: "spring-music-sql"}},
187+
Stack: "cflinuxfs3",
188+
}
189+
190+
setupAppPushRoutes(t, serverURL, g, org, space, job, app, pkg, build, droplet, dropletAssoc, "restart")
191+
192+
c, _ := config.New(serverURL, config.Token("", "fake-refresh-token"), config.SkipTLSValidation())
193+
cf, err := client.New(c)
194+
require.NoError(t, err)
195+
196+
pusher := NewAppPushOperation(cf, org.Name, space.Name)
197+
strategy := StrategyMode(10)
198+
pusher.WithStrategy(strategy)
199+
_, err = pusher.Push(context.Background(), manifest, fakeAppZipReader)
200+
require.NoError(t, err)
201+
}
202+
147203
func TestDockerLifecycleBuildCreation(t *testing.T) {
148204
serverURL := testutil.SetupFakeAPIServer()
149205
defer testutil.Teardown()

0 commit comments

Comments
 (0)