github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/integration/assets/service_broker/spec/service_broker_spec.rb (about)

     1  require 'spec_helper'
     2  require 'json'
     3  
     4  describe ServiceBroker do
     5    before do
     6      post '/config/reset'
     7    end
     8  
     9    describe 'GET /v2/catalog' do
    10      it 'returns a non-empty catalog' do
    11        get '/v2/catalog'
    12        response = last_response
    13        expect(response.body).to be
    14        expect(JSON.parse(response.body)).to be
    15      end
    16    end
    17  
    18    describe 'POST /v2/catalog' do
    19      it 'changes the catalog' do
    20        get '/v2/catalog'
    21        first_response = last_response
    22        expect(first_response.body).to be
    23  
    24        post '/v2/catalog'
    25  
    26        get '/v2/catalog'
    27        second_response = last_response
    28        expect(second_response.body).to eq(first_response.body)
    29      end
    30    end
    31  
    32    describe 'PUT /v2/service_instances/:id' do
    33      it 'returns 200 with an empty JSON body' do
    34        put '/v2/service_instances/fakeIDThough', {}.to_json
    35        expect(last_response.status).to eq(200)
    36        expect(JSON.parse(last_response.body)).to be_empty
    37      end
    38  
    39      context 'when the plan is configured as async_only' do
    40        before do
    41          config = {
    42              max_fetch_service_instance_requests: 1,
    43              behaviors: {
    44                  provision: {
    45                      'fake-async-plan-guid' => {
    46                          sleep_seconds: 0,
    47                          async_only: true,
    48                          status: 202,
    49                          body: {}
    50                      },
    51                      default: {
    52                          sleep_seconds: 0,
    53                          status: 202,
    54                          body: {}
    55                      }
    56                  }
    57              }
    58          }.to_json
    59  
    60          post '/config', config
    61        end
    62  
    63  
    64        context 'request is for an async plan' do
    65          it 'returns as usual if it does include accepts_incomplete' do
    66            put '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json
    67  
    68            expect(last_response.status).to eq(202)
    69          end
    70  
    71          it 'rejects request if it does not include accepts_incomplete' do
    72            put '/v2/service_instances/fake-guid', {plan_id: 'fake-async-plan-guid'}.to_json
    73  
    74            expect(last_response.status).to eq(422)
    75            expect(last_response.body).to eq(
    76                                              {
    77                                                  'error' => 'AsyncRequired',
    78                                                  'description' => 'This service plan requires client support for asynchronous service operations.'
    79                                              }.to_json
    80                                          )
    81          end
    82        end
    83  
    84      end
    85    end
    86  
    87    describe 'PATCH /v2/service_instance/:id' do
    88      context 'when updating to an async plan' do
    89        it 'returns a 202' do
    90          patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json
    91          expect(last_response.status).to eq(202)
    92        end
    93      end
    94  
    95      context 'when updating to a sync plan' do
    96        it 'returns a 200' do
    97          patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-plan-guid'}.to_json
    98          expect(last_response.status).to eq(200)
    99        end
   100      end
   101  
   102      context 'when the plan is configured as async_only' do
   103        before do
   104          config = {
   105              max_fetch_service_instance_requests: 1,
   106              behaviors: {
   107                  update: {
   108                      'fake-async-plan-guid' => {
   109                          sleep_seconds: 0,
   110                          async_only: true,
   111                          status: 202,
   112                          body: {}
   113                      },
   114                      default: {
   115                          sleep_seconds: 0,
   116                          status: 202,
   117                          body: {}
   118                      }
   119                  }
   120              }
   121          }.to_json
   122  
   123          post '/config', config
   124        end
   125  
   126  
   127        context 'request is for an async plan' do
   128          it 'returns as usual if it does include accepts_incomplete' do
   129            patch '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json
   130  
   131            expect(last_response.status).to eq(202)
   132          end
   133  
   134          it 'rejects request if it does not include accepts_incomplete' do
   135            patch '/v2/service_instances/fake-guid', {plan_id: 'fake-async-plan-guid'}.to_json
   136  
   137            expect(last_response.status).to eq(422)
   138            expect(last_response.body).to eq(
   139                {
   140                    'error' => 'AsyncRequired',
   141                    'description' => 'This service plan requires client support for asynchronous service operations.'
   142                }.to_json
   143            )
   144          end
   145        end
   146  
   147      end
   148    end
   149  
   150    describe 'DELETE /v2/service_instances/:id' do
   151      before do
   152        put '/v2/service_instances/fake-guid?accepts_incomplete=true', {plan_id: 'fake-async-plan-guid'}.to_json
   153        expect(last_response.status).to eq(202)
   154      end
   155  
   156      context 'when the plan is configured as async_only' do
   157        before do
   158          config = {
   159              max_fetch_service_instance_requests: 1,
   160              behaviors: {
   161                  deprovision: {
   162                      'fake-async-plan-guid' => {
   163                          sleep_seconds: 0,
   164                          async_only: true,
   165                          status: 202,
   166                          body: {}
   167                      },
   168                      default: {
   169                          sleep_seconds: 0,
   170                          status: 202,
   171                          body: {}
   172                      }
   173                  }
   174              }
   175          }.to_json
   176  
   177          post '/config', config
   178        end
   179  
   180  
   181        context 'request is for an async plan' do
   182          it 'returns as usual if it does include accepts_incomplete' do
   183            delete '/v2/service_instances/fake-guid?accepts_incomplete=true'
   184  
   185            expect(last_response.status).to eq(202)
   186          end
   187  
   188          it 'rejects request if it does not include accepts_incomplete' do
   189            delete '/v2/service_instances/fake-guid'
   190  
   191            expect(last_response.status).to eq(422)
   192            expect(last_response.body).to eq(
   193                {
   194                    'error' => 'AsyncRequired',
   195                    'description' => 'This service plan requires client support for asynchronous service operations.'
   196                }.to_json
   197            )
   198          end
   199        end
   200      end
   201    end
   202  
   203    describe 'configuration management' do
   204      before do
   205        post '/config/reset'
   206      end
   207  
   208      def provision
   209        put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json
   210      end
   211  
   212      def deprovision
   213        delete '/v2/service_instances/fake-guid?plan_id=fake-plan-guid', {}.to_json
   214      end
   215  
   216      def update
   217        patch '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json
   218      end
   219  
   220      def bind
   221        put '/v2/service_instances/fake-guid/service_bindings/binding-gui', {plan_id: 'fake-plan-guid'}.to_json
   222      end
   223  
   224      def unbind
   225        delete '/v2/service_instances/fake-guid/service_bindings/binding-gui?plan_id=fake-plan-guid', {}.to_json
   226      end
   227  
   228      [:provision, :deprovision, :update, :bind, :unbind].each do |action|
   229        context "for a #{action} operation" do
   230          before do
   231            put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json unless action == :provision
   232            put '/v2/service_instances/fake-guid/service_bindings/binding-gui', {plan_id: 'fake-plan-guid'}.to_json if action == :unbind
   233          end
   234  
   235          it 'should change the response using a json body' do
   236            config = {
   237              behaviors: {
   238                action => {
   239                  default: {
   240                    status: 400,
   241                    sleep_seconds: 0,
   242                    body: {}
   243                  }
   244                }
   245              }
   246            }.to_json
   247  
   248            post '/config', config
   249  
   250            send(action)
   251            expect(last_response.status).to eq(400)
   252            expect(last_response.body).to eq('{}')
   253          end
   254  
   255          it 'should change the response using an invalid json body' do
   256            config = {
   257              behaviors: {
   258                action => {
   259                  default: {
   260                    status: 201,
   261                    sleep_seconds: 0,
   262                    raw_body: 'foo'
   263                  }
   264                }
   265              }
   266            }.to_json
   267  
   268            post '/config', config
   269  
   270            send(action)
   271            expect(last_response.status).to eq(201)
   272            expect(last_response.body).to eq 'foo'
   273          end
   274  
   275          it 'should cause the action to sleep' do
   276            config = {
   277              behaviors: {
   278                action => {
   279                  default: {
   280                    status: 200,
   281                    sleep_seconds: 1.1,
   282                    body: {}
   283                  }
   284                }
   285              }
   286            }.to_json
   287  
   288            post '/config', config
   289  
   290  
   291            expect do
   292              Timeout::timeout(1) do
   293                send(action)
   294              end
   295            end.to raise_error(TimeoutError)
   296          end
   297  
   298          it 'can be customized on a per-plan basis' do
   299            config = {
   300              behaviors: {
   301                action => {
   302                  'fake-plan-guid' => {
   303                    status: 200,
   304                    sleep_seconds: 0,
   305                    raw_body: 'fake-plan body'
   306                  },
   307                  default: {
   308                    status: 400,
   309                    sleep_seconds: 0,
   310                    body: {}
   311                  }
   312                }
   313              }
   314            }.to_json
   315  
   316            post '/config', config
   317  
   318            send(action)
   319            expect(last_response.status).to eq(200)
   320            expect(last_response.body).to eq('fake-plan body')
   321          end
   322        end
   323      end
   324  
   325      context 'for a fetch operation' do
   326        before do
   327          put '/v2/service_instances/fake-guid', {plan_id: 'fake-plan-guid'}.to_json
   328        end
   329  
   330        it 'should change the response using a json body' do
   331          config = {
   332            max_fetch_service_instance_requests: 1,
   333            behaviors: {
   334              fetch: {
   335                default: {
   336                  in_progress: {
   337                    status: 200,
   338                    sleep_seconds: 0,
   339                    body: {}
   340                  },
   341                  finished: {
   342                    status: 400,
   343                    sleep_seconds: 0,
   344                    body: { foo: :bar }
   345                  }
   346                }
   347              }
   348            }
   349          }.to_json
   350  
   351          post '/config', config
   352  
   353          get '/v2/service_instances/fake-guid/last_operation'
   354          expect(last_response.status).to eq(200)
   355          expect(last_response.body).to eq('{}')
   356  
   357          get '/v2/service_instances/fake-guid/last_operation'
   358          expect(last_response.status).to eq(400)
   359          expect(last_response.body).to eq({ foo: :bar }.to_json)
   360        end
   361  
   362        it 'should change the response using an invalid json body' do
   363          config = {
   364            max_fetch_service_instance_requests: 1,
   365            behaviors: {
   366              fetch: {
   367                default: {
   368                  in_progress: {
   369                    status: 200,
   370                    sleep_seconds: 0,
   371                    raw_body: 'cheese'
   372                  },
   373                  finished: {
   374                    status: 400,
   375                    sleep_seconds: 0,
   376                    raw_body: 'cake'
   377                  }
   378                }
   379              }
   380            }
   381          }.to_json
   382  
   383          post '/config', config
   384  
   385          get '/v2/service_instances/fake-guid/last_operation'
   386          expect(last_response.status).to eq(200)
   387          expect(last_response.body).to eq 'cheese'
   388  
   389          get '/v2/service_instances/fake-guid/last_operation'
   390          expect(last_response.status).to eq(400)
   391          expect(last_response.body).to eq 'cake'
   392        end
   393  
   394        it 'should cause the action to sleep' do
   395          config = {
   396            max_fetch_service_instance_requests: 1,
   397            behaviors: {
   398              fetch: {
   399                default: {
   400                  in_progress: {
   401                    status: 200,
   402                    sleep_seconds: 1.1,
   403                    body: {}
   404                  },
   405                  finished: {
   406                    status: 200,
   407                    sleep_seconds: 0.6,
   408                    body: { }
   409                  }
   410                }
   411              }
   412            }
   413          }.to_json
   414  
   415          post '/config', config
   416  
   417          expect do
   418            Timeout::timeout(1) do
   419              get '/v2/service_instances/fake-guid/last_operation'
   420            end
   421          end.to raise_error(TimeoutError)
   422  
   423          expect do
   424            Timeout::timeout(0.5) do
   425              get '/v2/service_instances/fake-guid/last_operation'
   426            end
   427          end.to raise_error(TimeoutError)
   428        end
   429  
   430        it 'honors max_fetch_service_instance_request' do
   431          config = {
   432            max_fetch_service_instance_requests: 2,
   433            behaviors: {
   434              fetch: {
   435                default: {
   436                  in_progress: {
   437                    status: 200,
   438                    sleep_seconds: 0,
   439                    body: {}
   440                  },
   441                  finished: {
   442                    status: 400,
   443                    sleep_seconds: 0,
   444                    body: { foo: :bar }
   445                  }
   446                }
   447              }
   448            }
   449          }.to_json
   450  
   451          post '/config', config
   452  
   453          get '/v2/service_instances/fake-guid/last_operation'
   454          expect(last_response.status).to eq(200)
   455          expect(last_response.body).to eq('{}')
   456  
   457          get '/v2/service_instances/fake-guid/last_operation'
   458          expect(last_response.status).to eq(200)
   459          expect(last_response.body).to eq('{}')
   460  
   461          get '/v2/service_instances/fake-guid/last_operation'
   462          expect(last_response.status).to eq(400)
   463          expect(last_response.body).to eq({ foo: :bar }.to_json)
   464        end
   465  
   466        it 'can be customized on a per-plan basis' do
   467          config = {
   468            max_fetch_service_instance_requests: 1,
   469            behaviors: {
   470              fetch: {
   471                'fake-plan-guid' => {
   472                  in_progress: {
   473                    status: 200,
   474                    sleep_seconds: 0,
   475                    body: { foo: 'bar' }
   476                  },
   477                  finished: {
   478                    status: 201,
   479                    sleep_seconds: 0,
   480                    body: { foo: 'baz' }
   481                  }
   482                },
   483                default: {
   484                  in_progress: {
   485                    status: 200,
   486                    sleep_seconds: 0,
   487                    body: {}
   488                  },
   489                  finished: {
   490                    status: 400,
   491                    sleep_seconds: 0,
   492                    body: { foo: :bar }
   493                  }
   494                }
   495              }
   496            }
   497          }.to_json
   498  
   499          post '/config', config
   500  
   501          get '/v2/service_instances/fake-guid/last_operation'
   502          expect(last_response.status).to eq(200)
   503          expect(last_response.body).to eq({ foo: 'bar' }.to_json)
   504  
   505          get '/v2/service_instances/fake-guid/last_operation'
   506          expect(last_response.status).to eq(201)
   507          expect(last_response.body).to eq({ foo: 'baz' }.to_json)
   508        end
   509      end
   510  
   511      it 'should allow resetting the configuration to its defaults' do
   512        get '/config'
   513        data = last_response.body
   514  
   515        config = {
   516          behaviors: {
   517            provision: {
   518              default: {
   519                status: 400,
   520                sleep_seconds: 0,
   521                body: {}
   522              }
   523            }
   524          }
   525        }.to_json
   526        post '/config', config
   527  
   528        post '/config/reset'
   529        expect(last_response.status).to eq(200)
   530  
   531        get '/config'
   532        expect(last_response.body).to eq(data)
   533      end
   534  
   535      it 'should be able to restore a previously saved configuration' do
   536        get '/config'
   537        data = last_response.body
   538  
   539        post '/config', data
   540        expect(last_response.status).to eq(200)
   541        expect(last_response.body).to eq(data)
   542      end
   543    end
   544  end