Class: MockServer::Client
- Inherits:
-
Object
- Object
- MockServer::Client
- Defined in:
- lib/mockserver/client.rb
Overview
Synchronous MockServer client.
Provides the full MockServer REST API plus a fluent builder DSL and WebSocket-based object callback support.
Constant Summary collapse
- HTTP_TIMEOUT =
seconds, matching Python client
60
Instance Method Summary collapse
-
#add_breakpoint(matcher, phases, request_handler: nil, response_handler: nil, stream_frame_handler: nil) ⇒ String
Register a breakpoint matcher with callback handlers.
-
#add_request_and_response_breakpoint(matcher, request_handler, response_handler) ⇒ String
Convenience: register a REQUEST+RESPONSE breakpoint.
-
#add_request_breakpoint(matcher, request_handler) ⇒ String
Convenience: register a REQUEST-only breakpoint.
-
#advance_clock(duration_millis) ⇒ Hash
Advance the frozen clock by
duration_millismilliseconds. -
#bind(*ports) ⇒ Array<Integer>
Bind additional ports.
-
#clear(request = nil, type: nil) ⇒ nil
Clear expectations and/or logs.
-
#clear_breakpoint_matchers ⇒ Hash
Clear all registered breakpoint matchers.
-
#clear_by_id(expectation_id, type: nil) ⇒ nil
Clear by expectation ID.
-
#clear_grpc_descriptors ⇒ nil
Clear all uploaded gRPC descriptor sets and registered services.
-
#clear_load_scenarios ⇒ Hash
Clear all registered load scenarios.
-
#clear_service_chaos ⇒ Hash
Clear all service-scoped chaos profiles.
-
#clock_status ⇒ Hash
Query the current clock status.
-
#close ⇒ nil
Close all WebSocket connections.
-
#delete_load_scenario(name) ⇒ Hash
Remove a single registered load scenario by name.
-
#freeze_clock(instant = nil) ⇒ Hash
Freeze the server clock at the given ISO-8601 instant.
-
#get_load_scenario(name) ⇒ Hash
Fetch a single registered load scenario by name.
-
#has_started?(attempts: 10, timeout: 0.5) ⇒ Boolean
(also: #has_started)
Check if MockServer has started.
-
#initialize(host, port, context_path: '', secure: false, ca_cert_path: nil, tls_verify: true) ⇒ Client
constructor
A new instance of Client.
-
#list_breakpoint_matchers ⇒ Hash
List all registered breakpoint matchers.
-
#load_scenario(scenario) ⇒ Hash
Register (load) a scenario into the registry without running it.
-
#load_scenarios ⇒ Hash
List all registered load scenarios.
-
#mock_with_callback(request, callback, times: nil, time_to_live: nil) ⇒ Array<Expectation>
Register a response callback via WebSocket.
-
#mock_with_forward_callback(request, forward_callback, response_callback = nil, times: nil, time_to_live: nil) ⇒ Array<Expectation>
Register a forward callback via WebSocket.
-
#open_api_expectation(expectation) ⇒ nil
Create an OpenAPI expectation.
-
#remove_breakpoint_matcher(breakpoint_id) ⇒ Hash
Remove a breakpoint matcher by id.
-
#remove_service_chaos(host) ⇒ Hash
Remove the service-scoped chaos profile registered for
host. -
#reset ⇒ nil
Reset all expectations and logs.
-
#reset_clock ⇒ Hash
Reset the server clock to real wall-clock time.
-
#retrieve_active_expectations(request: nil) ⇒ Array<Expectation>
Retrieve active expectations.
-
#retrieve_expectations_as_code(format: 'java', request: nil) ⇒ String
Retrieve the active expectations as MockServer SDK setup code (the builder code that recreates the expectations) in the requested language.
-
#retrieve_grpc_services ⇒ Array<Hash>
Retrieve the gRPC services registered from uploaded descriptor sets.
-
#retrieve_log_messages(request: nil) ⇒ Array<String>
Retrieve log messages.
-
#retrieve_recorded_expectations(request: nil) ⇒ Array<Expectation>
Retrieve recorded expectations.
-
#retrieve_recorded_expectations_as_code(format: 'java', request: nil) ⇒ String
Retrieve the recorded (proxied) request/response pairs as MockServer SDK setup code in the requested language.
-
#retrieve_recorded_requests(request: nil) ⇒ Array<HttpRequest>
Retrieve recorded requests.
-
#retrieve_recorded_requests_and_responses(request: nil) ⇒ Array<HttpRequestAndHttpResponse>
Retrieve recorded requests and responses.
-
#run_load_scenario(scenario) ⇒ Hash
Convenience: register a scenario then immediately start it.
-
#scenario(name) ⇒ ScenarioHandle
Return a handle to the named stateful scenario, wrapping the /mockserver/scenario/{name} control-plane endpoints.
-
#scenario_request(method, path, body = nil) ⇒ Object
private
Issue a control-plane scenario request, parsing the JSON response and raising Error on any >= 400 status.
-
#scenarios ⇒ Array<ScenarioState>
List every known scenario and its current state.
-
#service_chaos_status ⇒ Hash
Query the current service-scoped chaos registrations.
-
#set_service_chaos(host, chaos, ttl_millis = nil) ⇒ Hash
Register a service-scoped HTTP chaos profile for an upstream host.
-
#start_load_scenarios(names) ⇒ Hash
Start one or more registered scenarios.
-
#stop ⇒ nil
Stop the MockServer instance.
-
#stop_load_scenarios(names = nil) ⇒ Hash
Stop running scenarios.
-
#upload_grpc_descriptor(descriptor_bytes) ⇒ nil
Upload a compiled protobuf descriptor set so gRPC requests can be matched.
-
#upsert(*expectations) ⇒ Array<Expectation>
Create or update expectations.
-
#verify(request = nil, times: nil, response: nil) ⇒ nil
Verify that a request (and optionally a response) was received.
-
#verify_sequence(*requests, responses: nil) ⇒ nil
Verify that requests were received in sequence.
-
#verify_zero_interactions ⇒ nil
Verify zero interactions.
-
#when(request, times: nil, time_to_live: nil, priority: nil) ⇒ ForwardChainExpectation
Begin building an expectation via the fluent API.
Constructor Details
#initialize(host, port, context_path: '', secure: false, ca_cert_path: nil, tls_verify: true) ⇒ Client
Returns a new instance of Client.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/mockserver/client.rb', line 37 def initialize(host, port, context_path: '', secure: false, ca_cert_path: nil, tls_verify: true) @host = host @port = port @context_path = context_path @secure = secure @ca_cert_path = ca_cert_path @tls_verify = tls_verify @websocket_clients = [] @websocket_mutex = Mutex.new scheme = secure ? 'https' : 'http' ctx_path = '' if context_path && !context_path.empty? ctx_path = context_path.start_with?('/') ? context_path : "/#{context_path}" end @base_url = "#{scheme}://#{host}:#{port}#{ctx_path}" if block_given? begin yield self ensure close end end end |
Instance Method Details
#add_breakpoint(matcher, phases, request_handler: nil, response_handler: nil, stream_frame_handler: nil) ⇒ String
Register a breakpoint matcher with callback handlers. The callback WebSocket is opened lazily and reused.
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
# File 'lib/mockserver/client.rb', line 785 def add_breakpoint(matcher, phases, request_handler: nil, response_handler: nil, stream_frame_handler: nil) raise ArgumentError, 'add_breakpoint requires a non-nil matcher' if matcher.nil? raise ArgumentError, 'add_breakpoint requires a non-empty phases array' if phases.nil? || phases.empty? ws_client = ensure_breakpoint_websocket client_id = ws_client.client_id body = JSON.generate({ 'httpRequest' => matcher.to_h, 'phases' => phases, 'clientId' => client_id }) status, response_body = request('PUT', '/mockserver/breakpoint/matcher', body) if status >= 400 raise Error, "Failed to register breakpoint matcher (status=#{status}): #{response_body}" end parsed = response_body && !response_body.empty? ? JSON.parse(response_body) : {} breakpoint_id = parsed['id'] raise Error, 'Server did not return a breakpoint id' unless breakpoint_id # Install per-breakpoint-id handlers ws_client.set_breakpoint_request_handler(breakpoint_id, request_handler) if request_handler ws_client.set_breakpoint_response_handler(breakpoint_id, response_handler) if response_handler ws_client.set_breakpoint_stream_frame_handler(breakpoint_id, stream_frame_handler) if stream_frame_handler breakpoint_id end |
#add_request_and_response_breakpoint(matcher, request_handler, response_handler) ⇒ String
Convenience: register a REQUEST+RESPONSE breakpoint.
829 830 831 832 833 |
# File 'lib/mockserver/client.rb', line 829 def add_request_and_response_breakpoint(matcher, request_handler, response_handler) add_breakpoint(matcher, %w[REQUEST RESPONSE], request_handler: request_handler, response_handler: response_handler) end |
#add_request_breakpoint(matcher, request_handler) ⇒ String
Convenience: register a REQUEST-only breakpoint.
820 821 822 |
# File 'lib/mockserver/client.rb', line 820 def add_request_breakpoint(matcher, request_handler) add_breakpoint(matcher, ['REQUEST'], request_handler: request_handler) end |
#advance_clock(duration_millis) ⇒ Hash
Advance the frozen clock by duration_millis milliseconds.
174 175 176 177 178 179 180 181 182 |
# File 'lib/mockserver/client.rb', line 174 def advance_clock(duration_millis) body = JSON.generate({ 'action' => 'advance', 'durationMillis' => duration_millis }) status, response_body = request('PUT', '/mockserver/clock', body) if status >= 400 raise Error, "Failed to advance clock (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#bind(*ports) ⇒ Array<Integer>
Bind additional ports.
708 709 710 711 712 713 714 715 716 717 718 719 720 |
# File 'lib/mockserver/client.rb', line 708 def bind(*ports) body = JSON.generate(Ports.new(ports: ports.flatten).to_h) status, response_body = request('PUT', '/mockserver/bind', body) if status >= 400 raise Error, "Failed to bind ports (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return Ports.from_hash(parsed).ports end [] end |
#clear(request = nil, type: nil) ⇒ nil
Clear expectations and/or logs.
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/mockserver/client.rb', line 106 def clear(request = nil, type: nil) query_params = {} query_params['type'] = type if type body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/clear', body, query_params.empty? ? nil : query_params ) if status >= 400 raise Error, "Failed to clear (status=#{status}): #{response_body}" end nil end |
#clear_breakpoint_matchers ⇒ Hash
Clear all registered breakpoint matchers.
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 |
# File 'lib/mockserver/client.rb', line 870 def clear_breakpoint_matchers status, response_body = request('PUT', '/mockserver/breakpoint/matcher/clear') if status >= 400 raise Error, "Failed to clear breakpoint matchers (status=#{status}): #{response_body}" end # Clear client-side handlers @websocket_mutex.synchronize do @websocket_clients.each do |ws| ws.clear_breakpoint_handlers if ws.respond_to?(:clear_breakpoint_handlers) end end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#clear_by_id(expectation_id, type: nil) ⇒ nil
Clear by expectation ID.
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/mockserver/client.rb', line 124 def clear_by_id(expectation_id, type: nil) query_params = {} query_params['type'] = type if type body = JSON.generate({ 'id' => expectation_id }) status, response_body = do_request( 'PUT', '/mockserver/clear', body, query_params.empty? ? nil : query_params ) if status >= 400 raise Error, "Failed to clear by id (status=#{status}): #{response_body}" end nil end |
#clear_grpc_descriptors ⇒ nil
Clear all uploaded gRPC descriptor sets and registered services.
504 505 506 507 508 509 510 511 |
# File 'lib/mockserver/client.rb', line 504 def clear_grpc_descriptors status, response_body = request('PUT', '/mockserver/grpc/clear') if status >= 400 raise Error, "Failed to clear gRPC descriptors (status=#{status}): #{response_body}" end nil end |
#clear_load_scenarios ⇒ Hash
Clear all registered load scenarios.
343 344 345 346 347 348 349 350 |
# File 'lib/mockserver/client.rb', line 343 def clear_load_scenarios status, response_body = request('DELETE', '/mockserver/loadScenario') if status >= 400 raise Error, "Failed to clear load scenarios (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#clear_service_chaos ⇒ Hash
Clear all service-scoped chaos profiles.
242 243 244 245 246 247 248 249 250 |
# File 'lib/mockserver/client.rb', line 242 def clear_service_chaos body = JSON.generate({ 'clear' => true }) status, response_body = request('PUT', '/mockserver/serviceChaos', body) if status >= 400 raise Error, "Failed to clear service chaos (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#clock_status ⇒ Hash
Query the current clock status.
198 199 200 201 202 203 204 205 |
# File 'lib/mockserver/client.rb', line 198 def clock_status status, response_body = request('GET', '/mockserver/clock') if status >= 400 raise Error, "Failed to get clock status (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#close ⇒ nil
Close all WebSocket connections.
930 931 932 933 934 935 936 |
# File 'lib/mockserver/client.rb', line 930 def close @websocket_mutex.synchronize do @websocket_clients.each(&:close) @websocket_clients.clear end nil end |
#delete_load_scenario(name) ⇒ Hash
Remove a single registered load scenario by name.
331 332 333 334 335 336 337 338 |
# File 'lib/mockserver/client.rb', line 331 def delete_load_scenario(name) status, response_body = request('DELETE', "/mockserver/loadScenario/#{encode_path_segment(name)}") if status >= 400 raise Error, "Failed to delete load scenario (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#freeze_clock(instant = nil) ⇒ Hash
Freeze the server clock at the given ISO-8601 instant. If instant is nil, the clock freezes at the current real time.
159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/mockserver/client.rb', line 159 def freeze_clock(instant = nil) payload = { 'action' => 'freeze' } payload['instant'] = instant if instant body = JSON.generate(payload) status, response_body = request('PUT', '/mockserver/clock', body) if status >= 400 raise Error, "Failed to freeze clock (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#get_load_scenario(name) ⇒ Hash
Fetch a single registered load scenario by name.
315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/mockserver/client.rb', line 315 def get_load_scenario(name) status, response_body = request('GET', "/mockserver/loadScenario/#{encode_path_segment(name)}") if status == 404 raise Error, "Load scenario not found (status=404): #{name}" end if status >= 400 raise Error, "Failed to get load scenario (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#has_started?(attempts: 10, timeout: 0.5) ⇒ Boolean Also known as: has_started
Check if MockServer has started.
737 738 739 740 741 742 743 744 745 746 747 748 |
# File 'lib/mockserver/client.rb', line 737 def has_started?(attempts: 10, timeout: 0.5) attempts.times do |i| begin status, = request('PUT', '/mockserver/status') return true if status == 200 rescue ConnectionError # not yet started end sleep(timeout) if i < attempts - 1 end false end |
#list_breakpoint_matchers ⇒ Hash
List all registered breakpoint matchers.
837 838 839 840 841 842 843 844 |
# File 'lib/mockserver/client.rb', line 837 def list_breakpoint_matchers status, response_body = request('GET', '/mockserver/breakpoint/matchers') if status >= 400 raise Error, "Failed to list breakpoint matchers (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#load_scenario(scenario) ⇒ Hash
Register (load) a scenario into the registry without running it.
scenario may be a LoadScenario model (which responds to to_h) or a plain Hash already shaped to the LoadScenario JSON contract. It must carry a unique name. Registering is permitted even when load generation is disabled on the server.
286 287 288 289 290 291 292 293 294 295 |
# File 'lib/mockserver/client.rb', line 286 def load_scenario(scenario) payload = scenario.respond_to?(:to_h) ? scenario.to_h : scenario body = JSON.generate(payload) status, response_body = request('PUT', '/mockserver/loadScenario', body) if status >= 400 raise Error, "Failed to register load scenario (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#load_scenarios ⇒ Hash
List all registered load scenarios.
301 302 303 304 305 306 307 308 |
# File 'lib/mockserver/client.rb', line 301 def load_scenarios status, response_body = request('GET', '/mockserver/loadScenario') if status >= 400 raise Error, "Failed to list load scenarios (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#mock_with_callback(request, callback, times: nil, time_to_live: nil) ⇒ Array<Expectation>
Register a response callback via WebSocket.
896 897 898 899 900 901 902 903 904 905 |
# File 'lib/mockserver/client.rb', line 896 def mock_with_callback(request, callback, times: nil, time_to_live: nil) client_id = register_websocket_callback('response', callback) expectation = Expectation.new( http_request: request, http_response_object_callback: HttpObjectCallback.new(client_id: client_id), times: times, time_to_live: time_to_live ) upsert(expectation) end |
#mock_with_forward_callback(request, forward_callback, response_callback = nil, times: nil, time_to_live: nil) ⇒ Array<Expectation>
Register a forward callback via WebSocket.
914 915 916 917 918 919 920 921 922 923 924 925 926 |
# File 'lib/mockserver/client.rb', line 914 def mock_with_forward_callback(request, forward_callback, response_callback = nil, times: nil, time_to_live: nil) client_id = register_websocket_callback('forward', forward_callback, response_callback) obj_callback = HttpObjectCallback.new(client_id: client_id) obj_callback.response_callback = true if response_callback expectation = Expectation.new( http_request: request, http_forward_object_callback: obj_callback, times: times, time_to_live: time_to_live ) upsert(expectation) end |
#open_api_expectation(expectation) ⇒ nil
Create an OpenAPI expectation.
92 93 94 95 96 97 98 99 100 |
# File 'lib/mockserver/client.rb', line 92 def open_api_expectation(expectation) body = JSON.generate(expectation.to_h) status, response_body = request('PUT', '/mockserver/openapi', body) if status >= 400 raise Error, "Failed to create OpenAPI expectation (status=#{status}): #{response_body}" end nil end |
#remove_breakpoint_matcher(breakpoint_id) ⇒ Hash
Remove a breakpoint matcher by id.
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
# File 'lib/mockserver/client.rb', line 849 def remove_breakpoint_matcher(breakpoint_id) raise ArgumentError, 'remove_breakpoint_matcher requires a non-empty id' if breakpoint_id.nil? || breakpoint_id.empty? body = JSON.generate({ 'id' => breakpoint_id }) status, response_body = request('PUT', '/mockserver/breakpoint/matcher/remove', body) if status >= 400 raise Error, "Failed to remove breakpoint matcher (status=#{status}): #{response_body}" end # Remove client-side handlers @websocket_mutex.synchronize do @websocket_clients.each do |ws| ws.remove_breakpoint_handlers(breakpoint_id) if ws.respond_to?(:remove_breakpoint_handlers) end end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#remove_service_chaos(host) ⇒ Hash
Remove the service-scoped chaos profile registered for host.
230 231 232 233 234 235 236 237 238 |
# File 'lib/mockserver/client.rb', line 230 def remove_service_chaos(host) body = JSON.generate({ 'host' => host, 'remove' => true }) status, response_body = request('PUT', '/mockserver/serviceChaos', body) if status >= 400 raise Error, "Failed to remove service chaos (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#reset ⇒ nil
Reset all expectations and logs.
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/mockserver/client.rb', line 140 def reset status, response_body = request('PUT', '/mockserver/reset') if status >= 400 raise Error, "Failed to reset (status=#{status}): #{response_body}" end nil ensure close end |
#reset_clock ⇒ Hash
Reset the server clock to real wall-clock time.
186 187 188 189 190 191 192 193 194 |
# File 'lib/mockserver/client.rb', line 186 def reset_clock body = JSON.generate({ 'action' => 'reset' }) status, response_body = request('PUT', '/mockserver/clock', body) if status >= 400 raise Error, "Failed to reset clock (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#retrieve_active_expectations(request: nil) ⇒ Array<Expectation>
Retrieve active expectations.
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
# File 'lib/mockserver/client.rb', line 586 def retrieve_active_expectations(request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'ACTIVE_EXPECTATIONS', 'format' => 'JSON' } ) if status >= 400 raise Error, "Failed to retrieve active expectations (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed.map { |e| Expectation.from_hash(e) } if parsed.is_a?(Array) end [] end |
#retrieve_expectations_as_code(format: 'java', request: nil) ⇒ String
Retrieve the active expectations as MockServer SDK setup code (the builder code that recreates the expectations) in the requested language.
629 630 631 632 633 634 635 636 637 638 639 640 |
# File 'lib/mockserver/client.rb', line 629 def retrieve_expectations_as_code(format: 'java', request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'ACTIVE_EXPECTATIONS', 'format' => format.to_s.upcase } ) if status >= 400 raise Error, "Failed to retrieve expectations as code (status=#{status}): #{response_body}" end response_body || '' end |
#retrieve_grpc_services ⇒ Array<Hash>
Retrieve the gRPC services registered from uploaded descriptor sets.
Returns an array of service hashes, each with a “name” and a list of “methods” (+“name”+, “inputType”, “outputType”, “clientStreaming”, “serverStreaming”).
489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/mockserver/client.rb', line 489 def retrieve_grpc_services status, response_body = request('PUT', '/mockserver/grpc/services') if status >= 400 raise Error, "Failed to retrieve gRPC services (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed if parsed.is_a?(Array) end [] end |
#retrieve_log_messages(request: nil) ⇒ Array<String>
Retrieve log messages.
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'lib/mockserver/client.rb', line 684 def (request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'LOGS' } ) if status >= 400 raise Error, "Failed to retrieve log messages (status=#{status}): #{response_body}" end if response_body && !response_body.empty? begin parsed = JSON.parse(response_body) return parsed if parsed.is_a?(Array) rescue JSON::ParserError return response_body.split("------------------------------------\n") end end [] end |
#retrieve_recorded_expectations(request: nil) ⇒ Array<Expectation>
Retrieve recorded expectations.
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
# File 'lib/mockserver/client.rb', line 606 def retrieve_recorded_expectations(request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'RECORDED_EXPECTATIONS', 'format' => 'JSON' } ) if status >= 400 raise Error, "Failed to retrieve recorded expectations (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed.map { |e| Expectation.from_hash(e) } if parsed.is_a?(Array) end [] end |
#retrieve_recorded_expectations_as_code(format: 'java', request: nil) ⇒ String
Retrieve the recorded (proxied) request/response pairs as MockServer SDK setup code in the requested language.
648 649 650 651 652 653 654 655 656 657 658 659 |
# File 'lib/mockserver/client.rb', line 648 def retrieve_recorded_expectations_as_code(format: 'java', request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'RECORDED_EXPECTATIONS', 'format' => format.to_s.upcase } ) if status >= 400 raise Error, "Failed to retrieve recorded expectations as code (status=#{status}): #{response_body}" end response_body || '' end |
#retrieve_recorded_requests(request: nil) ⇒ Array<HttpRequest>
Retrieve recorded requests.
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
# File 'lib/mockserver/client.rb', line 566 def retrieve_recorded_requests(request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'REQUESTS', 'format' => 'JSON' } ) if status >= 400 raise Error, "Failed to retrieve recorded requests (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed.map { |r| HttpRequest.from_hash(r) } if parsed.is_a?(Array) end [] end |
#retrieve_recorded_requests_and_responses(request: nil) ⇒ Array<HttpRequestAndHttpResponse>
Retrieve recorded requests and responses.
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
# File 'lib/mockserver/client.rb', line 664 def retrieve_recorded_requests_and_responses(request: nil) body = request ? JSON.generate(request.to_h) : '' status, response_body = do_request( 'PUT', '/mockserver/retrieve', body, { 'type' => 'REQUEST_RESPONSES', 'format' => 'JSON' } ) if status >= 400 raise Error, "Failed to retrieve request/responses (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed.map { |rr| HttpRequestAndHttpResponse.from_hash(rr) } if parsed.is_a?(Array) end [] end |
#run_load_scenario(scenario) ⇒ Hash
Convenience: register a scenario then immediately start it.
Equivalent to calling #load_scenario followed by #start_load_scenarios for the scenario’s name. Requires loadGenerationEnabled on the server for the start step.
408 409 410 411 412 413 414 415 416 417 |
# File 'lib/mockserver/client.rb', line 408 def run_load_scenario(scenario) payload = scenario.respond_to?(:to_h) ? scenario.to_h : scenario name = payload.respond_to?(:[]) ? (payload['name'] || payload[:name]) : nil if name.nil? || name.to_s.empty? raise ArgumentError, 'scenario must carry a non-empty name to run' end load_scenario(payload) start_load_scenarios(name) end |
#scenario(name) ⇒ ScenarioHandle
Return a handle to the named stateful scenario, wrapping the /mockserver/scenario/{name} control-plane endpoints.
428 429 430 |
# File 'lib/mockserver/client.rb', line 428 def scenario(name) ScenarioHandle.new(self, name) end |
#scenario_request(method, path, body = nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Issue a control-plane scenario request, parsing the JSON response and raising Error on any >= 400 status. Reuses the same transport (request) as the other /mockserver/... control endpoints.
445 446 447 448 449 450 451 452 |
# File 'lib/mockserver/client.rb', line 445 def scenario_request(method, path, body = nil) status, response_body = request(method, path, body) if status >= 400 raise Error, "Scenario request failed (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#scenarios ⇒ Array<ScenarioState>
List every known scenario and its current state.
435 436 437 438 439 |
# File 'lib/mockserver/client.rb', line 435 def scenarios result = scenario_request('GET', '/mockserver/scenario') list = result.is_a?(Hash) ? (result['scenarios'] || []) : [] list.map { |s| ScenarioState.from_hash(s) } end |
#service_chaos_status ⇒ Hash
Query the current service-scoped chaos registrations.
254 255 256 257 258 259 260 261 |
# File 'lib/mockserver/client.rb', line 254 def service_chaos_status status, response_body = request('GET', '/mockserver/serviceChaos') if status >= 400 raise Error, "Failed to get service chaos (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#set_service_chaos(host, chaos, ttl_millis = nil) ⇒ Hash
Register a service-scoped HTTP chaos profile for an upstream host. The profile is applied to every matched forward expectation to that host that does not define its own chaos (an expectation’s own chaos always wins). The host is matched case-insensitively, ignoring any :port.
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/mockserver/client.rb', line 215 def set_service_chaos(host, chaos, ttl_millis = nil) payload = { 'host' => host, 'chaos' => chaos.to_h } payload['ttlMillis'] = ttl_millis unless ttl_millis.nil? body = JSON.generate(payload) status, response_body = request('PUT', '/mockserver/serviceChaos', body) if status >= 400 raise Error, "Failed to set service chaos (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#start_load_scenarios(names) ⇒ Hash
Start one or more registered scenarios.
names may be a single scenario name (String) or an Array of names; it is always sent as { “names” => […] }. Honours each scenario’s startDelayMillis. Requires loadGenerationEnabled on the server; a 403 response raises a clear error explaining the feature is disabled.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/mockserver/client.rb', line 362 def start_load_scenarios(names) payload = { 'names' => Array(names) } body = JSON.generate(payload) status, response_body = request('PUT', '/mockserver/loadScenario/start', body) if status == 403 raise Error, 'Load scenario start rejected (status=403): load generation is disabled ' \ '(set loadGenerationEnabled=true on the server to enable it)' end if status == 404 raise Error, "Load scenario not found (status=404): #{response_body}" end if status >= 400 raise Error, "Failed to start load scenarios (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#stop ⇒ nil
Stop the MockServer instance.
724 725 726 727 728 729 730 731 |
# File 'lib/mockserver/client.rb', line 724 def stop request('PUT', '/mockserver/stop') nil rescue ConnectionError nil ensure close end |
#stop_load_scenarios(names = nil) ⇒ Hash
Stop running scenarios.
names may be:
* a single scenario name (String) -> { "names" => ["a"] }
* an Array of names -> { "names" => ["a", "b"] }
* nil (the default) -> empty body, which stops all running scenarios
390 391 392 393 394 395 396 397 398 |
# File 'lib/mockserver/client.rb', line 390 def stop_load_scenarios(names = nil) body = names.nil? ? nil : JSON.generate({ 'names' => Array(names) }) status, response_body = request('PUT', '/mockserver/loadScenario/stop', body) if status >= 400 raise Error, "Failed to stop load scenarios (status=#{status}): #{response_body}" end response_body && !response_body.empty? ? JSON.parse(response_body) : {} end |
#upload_grpc_descriptor(descriptor_bytes) ⇒ nil
Upload a compiled protobuf descriptor set so gRPC requests can be matched.
descriptor_bytes must be the raw bytes of a FileDescriptorSet (e.g. the output of protoc –descriptor_set_out=… –include_imports). The bytes are sent verbatim as application/octet-stream (NOT base64-encoded).
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/mockserver/client.rb', line 466 def upload_grpc_descriptor(descriptor_bytes) if descriptor_bytes.nil? || descriptor_bytes.empty? raise ArgumentError, 'descriptor bytes must not be empty' end status, response_body = request( 'PUT', '/mockserver/grpc/descriptors', descriptor_bytes, content_type: 'application/octet-stream' ) if status >= 400 raise Error, "Failed to upload gRPC descriptor (status=#{status}): #{response_body}" end nil end |
#upsert(*expectations) ⇒ Array<Expectation>
Create or update expectations.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/mockserver/client.rb', line 71 def upsert(*expectations) body = JSON.generate(expectations.map(&:to_h)) status, response_body = request('PUT', '/mockserver/expectation', body) if status == 400 raise Error, "Invalid expectation: #{response_body}" end if status >= 400 raise Error, "Failed to upsert expectations (status=#{status}): #{response_body}" end if response_body && !response_body.empty? parsed = JSON.parse(response_body) return parsed.map { |e| Expectation.from_hash(e) } if parsed.is_a?(Array) end expectations.to_a end |
#verify(request = nil, times: nil, response: nil) ⇒ nil
Verify that a request (and optionally a response) was received.
519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
# File 'lib/mockserver/client.rb', line 519 def verify(request = nil, times: nil, response: nil) verification = Verification.new(http_request: request, http_response: response, times: times) body = JSON.generate(verification.to_h) status, response_body = do_request('PUT', '/mockserver/verify', body) if status == 406 raise VerificationError, response_body end if status >= 400 raise Error, "Failed to verify (status=#{status}): #{response_body}" end nil end |
#verify_sequence(*requests, responses: nil) ⇒ nil
Verify that requests were received in sequence.
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
# File 'lib/mockserver/client.rb', line 539 def verify_sequence(*requests, responses: nil) verification = VerificationSequence.new( http_requests: requests.empty? ? nil : requests.to_a, http_responses: responses ) body = JSON.generate(verification.to_h) status, response_body = request('PUT', '/mockserver/verifySequence', body) if status == 406 raise VerificationError, response_body end if status >= 400 raise Error, "Failed to verify sequence (status=#{status}): #{response_body}" end nil end |
#verify_zero_interactions ⇒ nil
Verify zero interactions.
559 560 561 |
# File 'lib/mockserver/client.rb', line 559 def verify_zero_interactions verify(HttpRequest.new, times: VerificationTimes.new(at_most: 0)) end |
#when(request, times: nil, time_to_live: nil, priority: nil) ⇒ ForwardChainExpectation
Begin building an expectation via the fluent API.
762 763 764 765 766 767 768 769 770 |
# File 'lib/mockserver/client.rb', line 762 def when(request, times: nil, time_to_live: nil, priority: nil) expectation = Expectation.new( http_request: request, times: times, time_to_live: time_to_live, priority: priority ) ForwardChainExpectation.new(self, expectation) end |