@@ -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,55 @@ module VCAP::CloudController
195195 } )
196196 end
197197
198+ it 'creates the droplet once and attaches lifecycle data' do
199+ expect {
200+ droplet_create . find_or_create_buildpack_droplet ( build )
201+ } . 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 {
217+ second = droplet_create . find_or_create_buildpack_droplet ( build )
218+ expect ( second . guid ) . to eq ( first . guid )
219+ } . to change ( DropletModel , :count ) . by ( 0 )
220+ . and change ( Event , :count ) . by ( 0 )
221+
222+ # Ensure still only one droplet for this build
223+ expect ( DropletModel . where ( build_guid : build . guid ) . count ) . to eq ( 1 )
224+
225+ buildpack_lifecycle_data . reload
226+ expect ( buildpack_lifecycle_data . droplet ) . to eq ( first )
227+ end
228+
229+ it 'returns the pre-existing droplet when one already exists for the build' do
230+ existing = DropletModel . make (
231+ app : app ,
232+ package : package ,
233+ build : build ,
234+ state : DropletModel ::STAGING_STATE
235+ )
236+ buildpack_lifecycle_data . update ( droplet : existing )
237+
238+ expect {
239+ returned = droplet_create . find_or_create_buildpack_droplet ( build )
240+ expect ( returned . guid ) . to eq ( existing . guid )
241+ } . to change ( DropletModel , :count ) . by ( 0 )
242+ . and change ( Event , :count ) . by ( 0 )
243+
244+ expect ( DropletModel . where ( build_guid : build . guid ) . first . guid ) . to eq ( existing . guid )
245+ end
246+
198247 context 'when the build does not contain created_by fields' do
199248 let ( :build ) do
200249 BuildModel . make (
@@ -205,7 +254,7 @@ module VCAP::CloudController
205254
206255 it 'sets the actor to UNKNOWN' do
207256 expect do
208- droplet_create . create_buildpack_droplet ( build )
257+ droplet_create . find_or_create_buildpack_droplet ( build )
209258 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
210259
211260 droplet = DropletModel . last
@@ -230,7 +279,7 @@ module VCAP::CloudController
230279
231280 it 'sets it on the droplet' do
232281 expect do
233- droplet_create . create_buildpack_droplet ( build )
282+ droplet_create . find_or_create_buildpack_droplet ( build )
234283 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
235284
236285 droplet = DropletModel . last
@@ -271,7 +320,7 @@ module VCAP::CloudController
271320
272321 it 'sets the actor to UNKNOWN' do
273322 expect do
274- droplet_create . create_buildpack_droplet ( build )
323+ droplet_create . find_or_create_buildpack_droplet ( build )
275324 end . to change { [ DropletModel . count , Event . count ] } . by ( [ 1 , 1 ] )
276325
277326 droplet = DropletModel . last
0 commit comments