@@ -206,7 +206,7 @@ def run_job(job, successes: 1, failures: 0)
206206 end
207207 end
208208
209- context 'when the broker responds with state is `in progress`' do
209+ context 'when the broker responds with state `in progress`' do
210210 let ( :state ) { 'in progress' }
211211
212212 it 'fetches and updates the service instance state' do
@@ -248,6 +248,92 @@ def run_job(job, successes: 1, failures: 0)
248248 end
249249 end
250250
251+ context 'when the broker responds with state `failed`' do
252+ let ( :state ) { 'failed' }
253+ let ( :description ) { 'soz' }
254+
255+ it 'fetches and updates the service instance state' do
256+ run_job ( job , successes : 0 , failures : 1 )
257+
258+ db_service_instance = ManagedServiceInstance . first ( guid : service_instance . guid )
259+ expect ( db_service_instance . last_operation . state ) . to eq ( 'failed' )
260+ end
261+
262+ it 'fails with an appropriate message' do
263+ run_job ( job , successes : 0 , failures : 1 )
264+
265+ pollable_job . reload
266+
267+ expect ( pollable_job . state ) . to eq ( PollableJobModel ::FAILED_STATE )
268+ expect ( pollable_job . cf_api_error ) .
269+ to include ( 'The service broker reported an error during provisioning: soz' )
270+ end
271+
272+ it 'should not enqueue another fetch job' do
273+ run_job ( job , successes : 0 , failures : 1 )
274+ expect ( Delayed ::Job . all ) . to have ( 1 ) . jobs
275+ expect ( Delayed ::Job . where ( failed_at : nil ) . all ) . to have ( 0 ) . jobs
276+ end
277+
278+ it 'does not apply the instance attributes that were proposed in the operation' do
279+ run_job ( job , successes : 0 , failures : 1 )
280+
281+ db_service_instance = ManagedServiceInstance . first ( guid : service_instance . guid )
282+ expect ( db_service_instance . service_plan ) . to_not eq ( proposed_service_plan )
283+ expect ( db_service_instance . name ) . to eq ( service_instance . name )
284+ end
285+
286+ it 'should not create an audit event' do
287+ run_job ( job , successes : 0 , failures : 1 )
288+
289+ expect ( Event . find ( type : 'audit.service_instance.create' ) ) . to be_nil
290+ end
291+ end
292+
293+ context 'when the job has fetched for more than the max poll duration' do
294+ let ( :state ) { 'in progress' }
295+
296+ before do
297+ run_job ( job )
298+ Timecop . travel ( Time . now + max_duration . minutes + 1 . minute ) do
299+ execute_all_jobs ( expected_successes : 0 , expected_failures : 1 )
300+ end
301+ end
302+
303+ it 'should not enqueue another fetch job' do
304+ Timecop . freeze ( Time . now + max_duration . minutes + 1 . minute ) do
305+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
306+ end
307+ end
308+
309+ it 'should mark the service instance operation as failed' do
310+ service_instance . reload
311+
312+ expect ( service_instance . last_operation . state ) . to eq ( 'failed' )
313+ expect ( service_instance . last_operation . description ) . to eq ( 'Service Broker failed to provision within the required time.' )
314+ end
315+
316+ it 'fails the job with an appropriate message' do
317+ pollable_job . reload
318+
319+ expect ( pollable_job . state ) . to eq ( PollableJobModel ::FAILED_STATE )
320+ expect ( pollable_job . cf_api_error ) .
321+ to include ( 'The job execution has timed out.' )
322+ end
323+ end
324+
325+ context 'when enqueuing the job would exceed the max poll duration by the time it runs' do
326+ let ( :state ) { 'in progress' }
327+
328+ it 'should not enqueue another fetch job' do
329+ Timecop . freeze ( job . end_timestamp - ( job . poll_interval * 0.5 ) )
330+ run_job ( job , failures : 1 , successes : 0 )
331+
332+ Timecop . freeze ( Time . now + job . poll_interval * 2 )
333+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
334+ end
335+ end
336+
251337 context 'failures' do
252338 context 'when fetching the last operation from the broker fails' do
253339 context 'due to an HttpRequestError' do
@@ -407,43 +493,6 @@ def run_job(job, successes: 1, failures: 0)
407493 end
408494 end
409495
410- context 'when the last operation type is `create`' do
411- before do
412- service_instance . save_with_new_operation ( { } , { type : 'create' } )
413- end
414-
415- context 'when during create, a delete operation was started' do
416- before do
417- allow ( client ) . to receive ( :fetch_service_instance_last_operation ) do
418- service_instance . save_with_new_operation (
419- { } ,
420- {
421- type : 'delete' ,
422- state : 'in progress'
423- }
424- )
425-
426- last_operation_response
427- end
428-
429- run_job ( job )
430- end
431-
432- let ( :db_service_instance ) { ManagedServiceInstance . first ( guid : service_instance . guid ) }
433-
434- it 'does not finish creating' do
435- expect ( db_service_instance . last_operation . type ) . to eq ( 'delete' )
436- expect ( db_service_instance . last_operation . state ) . to eq ( 'in progress' )
437- expect ( Event . find ( type : 'audit.service_instance.create' ) ) . not_to be
438- end
439-
440- it 'does not delete' do
441- expect ( db_service_instance ) . not_to be_nil
442- expect ( Event . find ( type : 'audit.service_instance.delete' ) ) . not_to be
443- end
444- end
445- end
446-
447496 context 'when the last operation type is `update`' do
448497 before do
449498 service_instance . last_operation . type = 'update'
@@ -485,101 +534,6 @@ def run_job(job, successes: 1, failures: 0)
485534 end
486535 end
487536
488- context 'when the state is `failed`' do
489- pending ( 'do not run' )
490- let ( :state ) { 'failed' }
491-
492- it 'does not apply the instance attributes that were proposed in the operation' do
493- run_job ( job )
494-
495- db_service_instance = ManagedServiceInstance . first ( guid : service_instance . guid )
496- expect ( db_service_instance . service_plan ) . to_not eq ( proposed_service_plan )
497- expect ( db_service_instance . name ) . to eq ( service_instance . name )
498- end
499-
500- it 'fetches and updates the service instance state' do
501- run_job ( job )
502-
503- db_service_instance = ManagedServiceInstance . first ( guid : service_instance . guid )
504- expect ( db_service_instance . last_operation . state ) . to eq ( 'failed' )
505- end
506-
507- it 'should not enqueue another fetch job' do
508- run_job ( job )
509-
510- expect ( Delayed ::Job . count ) . to eq 0
511- end
512-
513- it 'should not create an audit event' do
514- run_job ( job )
515-
516- expect ( Event . find ( type : 'audit.service_instance.create' ) ) . to be_nil
517- end
518- end
519-
520- context 'when the job has fetched for more than the max poll duration' do
521- let ( :state ) { 'in progress' }
522-
523- before do
524- run_job ( job )
525- Timecop . travel ( Time . now + max_duration . minutes + 1 . minute ) do
526- execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
527- end
528- end
529-
530- it 'should not enqueue another fetch job' do
531- Timecop . freeze ( Time . now + max_duration . minutes + 1 . minute ) do
532- execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
533- end
534- end
535-
536- it 'should mark the service instance operation as failed' do
537- service_instance . reload
538-
539- expect ( service_instance . last_operation . state ) . to eq ( 'failed' )
540- expect ( service_instance . last_operation . description ) . to eq ( 'Service Broker failed to provision within the required time.' )
541- end
542- end
543-
544- context 'when enqueuing the job would exceed the max poll duration by the time it runs' do
545- let ( :state ) { 'in progress' }
546-
547- it 'should not enqueue another fetch job' do
548- Timecop . freeze ( job . end_timestamp - ( job . poll_interval * 0.5 ) )
549- run_job ( job )
550-
551- Timecop . freeze ( Time . now + job . poll_interval * 2 )
552- execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
553- end
554- end
555-
556- context 'when the job was migrated before the addition of end_timestamp' do
557- let ( :state ) { 'in progress' }
558-
559- it 'should compute the end_timestamp based on the current time' do
560- Timecop . freeze ( Time . now )
561-
562- run_job ( job )
563-
564- # should run enqueued job
565- Timecop . travel ( Time . now + max_duration . minutes - 1 . minute ) do
566- execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
567- end
568-
569- # should not run enqueued job
570- Timecop . travel ( Time . now + max_duration . minutes ) do
571- execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
572- end
573- end
574-
575- it 'should enqueue another fetch job' do
576- run_job ( job )
577-
578- expect ( Delayed ::Job . count ) . to eq 1
579- expect ( Delayed ::Job . first ) . to be_a_fully_wrapped_job_of ( FetchLastOperationJob )
580- end
581- end
582-
583537 context 'when the poll_interval is changed after the job was created' do
584538 let ( :default_polling_interval ) { VCAP ::CloudController ::Config . config . get ( :broker_client_default_async_poll_interval_seconds ) }
585539 let ( :new_polling_interval ) { default_polling_interval * 2 }
0 commit comments