@@ -158,13 +158,13 @@ module VCAP::CloudController
158158 end
159159 end
160160
161- describe '#create_buildpack_droplet ' do
161+ describe '#find_or_create_buildpack_droplet ' do
162162 context 'buildpack lifecycle' do
163163 let! ( :buildpack_lifecycle_data ) { BuildpackLifecycleDataModel . make ( build :) }
164164
165165 it 'sets it on the droplet' do
166166 expect do
167- droplet_create . create_buildpack_droplet ( build )
167+ droplet_create . find_or_create_buildpack_droplet ( build )
168168 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
169169
170170 droplet = DropletModel . last
@@ -195,6 +195,53 @@ module VCAP::CloudController
195195 } )
196196 end
197197
198+ it 'creates the droplet once and attaches lifecycle data' do
199+ expect do
200+ droplet_create . find_or_create_buildpack_droplet ( build )
201+ end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
202+
203+ droplet = DropletModel . last
204+ expect ( droplet . state ) . to eq ( DropletModel ::STAGING_STATE )
205+ expect ( droplet . app ) . to eq ( app )
206+ expect ( droplet . package ) . to eq ( package )
207+ expect ( droplet . build ) . to eq ( build )
208+
209+ buildpack_lifecycle_data . reload
210+ expect ( buildpack_lifecycle_data . droplet ) . to eq ( droplet )
211+ end
212+
213+ it 'is idempotent on repeated calls (no duplicate droplet, same GUID, no extra event)' do
214+ first = droplet_create . find_or_create_buildpack_droplet ( build )
215+
216+ expect do
217+ second = droplet_create . find_or_create_buildpack_droplet ( build )
218+ expect ( second . guid ) . to eq ( first . guid )
219+ end . not_to ( change { [ DropletModel . count , Event . count ] } )
220+
221+ # Ensure still only one droplet for this build
222+ expect ( DropletModel . where ( build_guid : build . guid ) . count ) . to eq ( 1 )
223+
224+ buildpack_lifecycle_data . reload
225+ expect ( buildpack_lifecycle_data . droplet ) . to eq ( first )
226+ end
227+
228+ it 'returns the pre-existing droplet when one already exists for the build' do
229+ existing = DropletModel . make (
230+ app : app ,
231+ package : package ,
232+ build : build ,
233+ state : DropletModel ::STAGING_STATE
234+ )
235+ buildpack_lifecycle_data . update ( droplet : existing )
236+
237+ expect do
238+ returned = droplet_create . find_or_create_buildpack_droplet ( build )
239+ expect ( returned . guid ) . to eq ( existing . guid )
240+ end . not_to ( change { [ DropletModel . count , Event . count ] } )
241+
242+ expect ( DropletModel . where ( build_guid : build . guid ) . first . guid ) . to eq ( existing . guid )
243+ end
244+
198245 context 'when the build does not contain created_by fields' do
199246 let ( :build ) do
200247 BuildModel . make (
@@ -205,7 +252,7 @@ module VCAP::CloudController
205252
206253 it 'sets the actor to UNKNOWN' do
207254 expect do
208- droplet_create . create_buildpack_droplet ( build )
255+ droplet_create . find_or_create_buildpack_droplet ( build )
209256 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
210257
211258 droplet = DropletModel . last
@@ -230,7 +277,7 @@ module VCAP::CloudController
230277
231278 it 'sets it on the droplet' do
232279 expect do
233- droplet_create . create_buildpack_droplet ( build )
280+ droplet_create . find_or_create_buildpack_droplet ( build )
234281 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
235282
236283 droplet = DropletModel . last
@@ -271,7 +318,7 @@ module VCAP::CloudController
271318
272319 it 'sets the actor to UNKNOWN' do
273320 expect do
274- droplet_create . create_buildpack_droplet ( build )
321+ droplet_create . find_or_create_buildpack_droplet ( build )
275322 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
276323
277324 droplet = DropletModel . last
0 commit comments