mockserver-client 7.1.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b853b4ba04e3473e6e664a0f1a2f6b4f0a8146f624a2308a19349fe94f536d9e
4
- data.tar.gz: 848eedd40df3e43ac6299250c92d4f30ee1b7fbeedb15699cd7254af20fcb6a4
3
+ metadata.gz: fa28c69e849b63f6fa75a1f57f939a348cf30d3032d6b1dfb040276dbd51eb6b
4
+ data.tar.gz: 188c6469fc18b0ed51b4099a652d68a3b00b0bbccda233265b282e9d08e5c677
5
5
  SHA512:
6
- metadata.gz: a2c283e6f9ed9fb935ff296a84298abc7c73768609c0601b8079e20441ebd25ca1029256a7c21a968578ef3f9ea28777b7d07dd20c7d8b4387031298389c4eb8
7
- data.tar.gz: 77bc8cf3f5e4e919ba758c4c720cbf9795600094d7bfc41faa66b5571c0ea2b7ee39fa3a4f6871726ffc3a6468f84defb34afce05b33203b734e1cc1ac1c3c53
6
+ metadata.gz: c4d3d24b31236d09f8684b10bc114e6cb2154f532ff230453f9e3f566ecbd271ef4c770a8d3f6db6a2476bd89efdd529471ba4fb46ca2ebe0e89e8a97f2fc63e
7
+ data.tar.gz: daef70802e8ee57033d185f74c580c3b61d87eb97fc0c74ab31288f345e9fe86c9823b6ff6f90231d2066c8b9f05a6446d5ba06a7d917bdb61dd1215ef2094ae
data/README.md CHANGED
@@ -99,6 +99,150 @@ All 25 domain model classes are available under the `MockServer` module:
99
99
  - `Ports`
100
100
  - `RequestDefinition` (alias for `HttpRequest`)
101
101
 
102
+ ## LLM Mocking
103
+
104
+ Fluent builders under `MockServer::LLM` mock LLM provider endpoints. They produce
105
+ expectations whose action is carried in the `httpLlmResponse` field; MockServer
106
+ re-encodes the provider-agnostic completion into the configured provider's wire
107
+ shape (OpenAI / Anthropic / Gemini / Bedrock / ...) when serving the request.
108
+
109
+ ```ruby
110
+ require 'mockserver-client'
111
+
112
+ client = MockServer::Client.new('localhost', 1080)
113
+
114
+ # A single completion mock
115
+ MockServer::LLM.llm_mock('/v1/chat/completions')
116
+ .with_provider(MockServer::LLM::Provider::OPENAI)
117
+ .with_model('gpt-4o')
118
+ .responding_with(
119
+ MockServer::LLM.completion
120
+ .with_text('Hello!')
121
+ .with_usage(MockServer::LLM.usage.with_input_tokens(10).with_output_tokens(5))
122
+ )
123
+ .apply_to(client)
124
+ ```
125
+
126
+ Multi-turn **conversations** use MockServer scenario-state advancement so each
127
+ turn is served once, in order. Add per-turn predicates with `when_*` methods and
128
+ optionally isolate per session with `isolate_by`:
129
+
130
+ ```ruby
131
+ MockServer::LLM.conversation
132
+ .with_path('/v1/chat/completions')
133
+ .with_provider(MockServer::LLM::Provider::OPENAI)
134
+ .isolate_by(MockServer::LLM.header('x-session-id'))
135
+ .turn.when_latest_message_contains('weather')
136
+ .responding_with(MockServer::LLM.completion.with_text('It is sunny.'))
137
+ .turn.responding_with(MockServer::LLM.completion.with_text('Anything else?'))
138
+ .apply_to(client)
139
+ ```
140
+
141
+ **Failover** scenarios script N upstream failures (consecutive identical failures
142
+ are coalesced) followed by a success; default JSON error bodies are generated per
143
+ status code unless a custom body is supplied:
144
+
145
+ ```ruby
146
+ MockServer::LLM.llm_failover
147
+ .with_path('/v1/chat/completions')
148
+ .with_provider(MockServer::LLM::Provider::OPENAI)
149
+ .fail_with(429, 2) # two rate-limit failures
150
+ .fail_with(503) # then one service-unavailable
151
+ .then_respond_with(MockServer::LLM.completion.with_text('Recovered'))
152
+ .apply_to(client)
153
+ ```
154
+
155
+ Each builder also exposes `build` to obtain the raw expectation Hash(es) without
156
+ registering them.
157
+
158
+ ## MCP Mocking
159
+
160
+ `MockServer::MCP.mcp_mock` builds the set of expectations needed to emulate a
161
+ Streamable-HTTP MCP (Model Context Protocol) server speaking JSON-RPC 2.0. It
162
+ generates `initialize`, `ping`, `notifications/initialized`, and per-capability
163
+ `tools`, `resources`, and `prompts` handlers.
164
+
165
+ ```ruby
166
+ MockServer::MCP.mcp_mock('/mcp')
167
+ .with_server_name('MyServer')
168
+ .with_tool('get_weather')
169
+ .with_description('Get the weather for a city')
170
+ .with_input_schema('{"type":"object","properties":{"city":{"type":"string"}}}')
171
+ .responding_with('72F and sunny')
172
+ .and_then
173
+ .with_resource('file:///config.json')
174
+ .with_name('config')
175
+ .with_content('{"debug":true}')
176
+ .and_then
177
+ .with_prompt('greet')
178
+ .with_argument('name', 'who to greet', true)
179
+ .responding_with('user', 'Hello there')
180
+ .and_then
181
+ .apply_to(client)
182
+ ```
183
+
184
+ `build` returns the raw expectation Hashes if you prefer to register them yourself.
185
+
186
+ ## A2A Mocking
187
+
188
+ `MockServer::A2A.a2a_mock` builds the set of expectations needed to emulate an
189
+ A2A (Agent-to-Agent) agent: an agent card served at `/.well-known/agent.json`
190
+ plus JSON-RPC 2.0 `tasks/send`, `tasks/get`, and `tasks/cancel` over `POST
191
+ <path>`. It optionally adds SSE streaming, push-notification config + delivery,
192
+ per-message custom task handlers, and advertised skills.
193
+
194
+ ```ruby
195
+ MockServer::A2A.a2a_mock('/a2a')
196
+ .with_agent_name('WeatherAgent')
197
+ .with_agent_description('Forecasts the weather')
198
+ .with_skill('weather')
199
+ .with_name('Weather lookup')
200
+ .with_tag('forecast')
201
+ .with_example('What is the weather in Paris?')
202
+ .and_then
203
+ .with_streaming
204
+ .with_push_notifications('http://localhost:1234/a2a/callback')
205
+ .on_task_send
206
+ .matching_message('forecast')
207
+ .responding_with('Sunny, 25C')
208
+ .and_then
209
+ .apply_to(client)
210
+ ```
211
+
212
+ When push notifications are configured, each `tasks/send` both returns the
213
+ JSON-RPC task response to the caller *and* POSTs the completed task to the
214
+ webhook URL. As with MCP mocking, `build` returns the raw expectation Hashes if
215
+ you prefer to register them yourself.
216
+
217
+ ## SRE Control Plane (SLO + Chaos)
218
+
219
+ Verify service-level objectives and drive scheduled chaos experiments against
220
+ the running MockServer:
221
+
222
+ ```ruby
223
+ # Evaluate SLOs over a window. Returns the verdict Hash on PASS/INCONCLUSIVE;
224
+ # raises MockServer::VerificationError on FAIL (HTTP 406).
225
+ verdict = client.verify_slo(
226
+ 'name' => 'checkout-latency',
227
+ 'window' => 'PT5M',
228
+ 'minimumSampleCount' => 100,
229
+ 'objectives' => [
230
+ { 'sli' => 'p99_latency_ms', 'comparator' => 'LESS_THAN', 'threshold' => 250 }
231
+ ]
232
+ )
233
+
234
+ # Start a scheduled multi-stage chaos experiment (only one may be active).
235
+ client.start_chaos_experiment(
236
+ 'name' => 'payments-brownout',
237
+ 'stages' => [
238
+ { 'durationMillis' => 60_000, 'profiles' => { 'payments.svc' => 'LATENCY' } }
239
+ ]
240
+ )
241
+ ```
242
+
243
+ SLO tracking must be enabled on the server (`sloTrackingEnabled=true`) or
244
+ `verify_slo` raises `MockServer::Error` on HTTP 400.
245
+
102
246
  ## Interactive Breakpoints
103
247
 
104
248
  The client supports matcher-driven interactive breakpoints over the callback WebSocket. Register a breakpoint matcher to pause forwarded/proxied exchanges at specific phases and inspect/modify/continue them via callback handlers.
@@ -172,7 +316,7 @@ launcher_path = MockServer::BinaryLauncher.ensure_launcher
172
316
  ### Specify a version
173
317
 
174
318
  ```ruby
175
- handle = MockServer::BinaryLauncher.start(port: 1080, version: '7.1.0')
319
+ handle = MockServer::BinaryLauncher.start(port: 1080, version: '7.3.0')
176
320
  ```
177
321
 
178
322
  ### API reference
@@ -203,6 +347,34 @@ handle = MockServer::BinaryLauncher.start(port: 1080, version: '7.1.0')
203
347
 
204
348
  By default the launcher downloads the MockServer version matching this client gem (currently `MockServer::VERSION` from `lib/mockserver/version.rb`). Pass an explicit `version:` keyword to override.
205
349
 
350
+ ## Using in tests (RSpec)
351
+
352
+ Require `mockserver/rspec` to get a shared context that provides a fresh
353
+ `MockServer::Client` per example and resets the server before and after each
354
+ example, so recorded requests, expectations and logs never leak between
355
+ examples:
356
+
357
+ ```ruby
358
+ # spec_helper.rb
359
+ require 'mockserver/rspec'
360
+
361
+ # any spec tagged :mockserver gets a reset `mockserver` client
362
+ RSpec.describe 'my integration', :mockserver do
363
+ it 'records the request' do
364
+ # `mockserver` is the shared, reset client
365
+ mockserver.when(
366
+ MockServer::HttpRequest.request(path: '/hello')
367
+ ).respond(
368
+ MockServer::HttpResponse.response(body: 'world', status_code: 200)
369
+ )
370
+ end
371
+ end
372
+ ```
373
+
374
+ Host and port default to `127.0.0.1:1080` and can be overridden with the
375
+ `MOCKSERVER_HOST` / `MOCKSERVER_PORT` environment variables, or by defining a
376
+ `mockserver_host` / `mockserver_port` `let` in your example group.
377
+
206
378
  ## License
207
379
 
208
380
  Apache-2.0