mockserver-client 6.0.0 → 7.0.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 +4 -4
- data/lib/mockserver/client.rb +112 -0
- data/lib/mockserver/forward_chain_expectation.rb +95 -0
- data/lib/mockserver/models.rb +528 -12
- data/lib/mockserver/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97517808097f2af911f727db3decbafcab8454285325b141ad5899a53af70be1
|
|
4
|
+
data.tar.gz: 60b5bff4ef90906b229064f23b1593bec547dc428b9d93c61b387d29a2615dd0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d91bb153b43f523a60812dc4f100fb1e7deb04c6ddc6353266d632f8f074df3683e0292d9cd77efb464034e618d4e4d63fafc3b11b333c009098cc5b48b49684
|
|
7
|
+
data.tar.gz: 7484d0dfa3e38edb7ad83dd2bb760a2b17dd2c4f474538e5673630f9fd28c056f4f7c2d2389ddbda2aa56f43eb052915cb4b5a432b4f15e7594e4db54cf92c9f
|
data/lib/mockserver/client.rb
CHANGED
|
@@ -148,6 +148,118 @@ module MockServer
|
|
|
148
148
|
close
|
|
149
149
|
end
|
|
150
150
|
|
|
151
|
+
# -------------------------------------------------------------------
|
|
152
|
+
# Clock Control
|
|
153
|
+
# -------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
# Freeze the server clock at the given ISO-8601 instant.
|
|
156
|
+
# If +instant+ is nil, the clock freezes at the current real time.
|
|
157
|
+
# @param instant [String, nil] ISO-8601 instant (e.g. "2025-01-15T09:30:00Z")
|
|
158
|
+
# @return [Hash] response with status, currentInstant, currentEpochMillis
|
|
159
|
+
def freeze_clock(instant = nil)
|
|
160
|
+
payload = { 'action' => 'freeze' }
|
|
161
|
+
payload['instant'] = instant if instant
|
|
162
|
+
body = JSON.generate(payload)
|
|
163
|
+
status, response_body = request('PUT', '/mockserver/clock', body)
|
|
164
|
+
if status >= 400
|
|
165
|
+
raise Error, "Failed to freeze clock (status=#{status}): #{response_body}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Advance the frozen clock by +duration_millis+ milliseconds.
|
|
172
|
+
# @param duration_millis [Integer]
|
|
173
|
+
# @return [Hash] response with status, currentInstant, currentEpochMillis
|
|
174
|
+
def advance_clock(duration_millis)
|
|
175
|
+
body = JSON.generate({ 'action' => 'advance', 'durationMillis' => duration_millis })
|
|
176
|
+
status, response_body = request('PUT', '/mockserver/clock', body)
|
|
177
|
+
if status >= 400
|
|
178
|
+
raise Error, "Failed to advance clock (status=#{status}): #{response_body}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Reset the server clock to real wall-clock time.
|
|
185
|
+
# @return [Hash] response with status, currentInstant, currentEpochMillis
|
|
186
|
+
def reset_clock
|
|
187
|
+
body = JSON.generate({ 'action' => 'reset' })
|
|
188
|
+
status, response_body = request('PUT', '/mockserver/clock', body)
|
|
189
|
+
if status >= 400
|
|
190
|
+
raise Error, "Failed to reset clock (status=#{status}): #{response_body}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Query the current clock status.
|
|
197
|
+
# @return [Hash] with currentInstant, currentEpochMillis, frozen
|
|
198
|
+
def clock_status
|
|
199
|
+
status, response_body = request('GET', '/mockserver/clock')
|
|
200
|
+
if status >= 400
|
|
201
|
+
raise Error, "Failed to get clock status (status=#{status}): #{response_body}"
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Register a service-scoped HTTP chaos profile for an upstream host. The profile
|
|
208
|
+
# is applied to every matched forward expectation to that host that does not
|
|
209
|
+
# define its own chaos (an expectation's own chaos always wins). The host is
|
|
210
|
+
# matched case-insensitively, ignoring any +:port+.
|
|
211
|
+
# @param host [String] the upstream host to break
|
|
212
|
+
# @param chaos [HttpChaosProfile] the chaos profile to apply
|
|
213
|
+
# @param ttl_millis [Integer, nil] if set, the chaos auto-reverts after this many ms
|
|
214
|
+
# @return [Hash] response with status and host
|
|
215
|
+
def set_service_chaos(host, chaos, ttl_millis = nil)
|
|
216
|
+
payload = { 'host' => host, 'chaos' => chaos.to_h }
|
|
217
|
+
payload['ttlMillis'] = ttl_millis unless ttl_millis.nil?
|
|
218
|
+
body = JSON.generate(payload)
|
|
219
|
+
status, response_body = request('PUT', '/mockserver/serviceChaos', body)
|
|
220
|
+
if status >= 400
|
|
221
|
+
raise Error, "Failed to set service chaos (status=#{status}): #{response_body}"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Remove the service-scoped chaos profile registered for +host+.
|
|
228
|
+
# @param host [String]
|
|
229
|
+
# @return [Hash]
|
|
230
|
+
def remove_service_chaos(host)
|
|
231
|
+
body = JSON.generate({ 'host' => host, 'remove' => true })
|
|
232
|
+
status, response_body = request('PUT', '/mockserver/serviceChaos', body)
|
|
233
|
+
if status >= 400
|
|
234
|
+
raise Error, "Failed to remove service chaos (status=#{status}): #{response_body}"
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Clear all service-scoped chaos profiles.
|
|
241
|
+
# @return [Hash]
|
|
242
|
+
def clear_service_chaos
|
|
243
|
+
body = JSON.generate({ 'clear' => true })
|
|
244
|
+
status, response_body = request('PUT', '/mockserver/serviceChaos', body)
|
|
245
|
+
if status >= 400
|
|
246
|
+
raise Error, "Failed to clear service chaos (status=#{status}): #{response_body}"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Query the current service-scoped chaos registrations.
|
|
253
|
+
# @return [Hash] of the form { "services" => { host => profile, ... } }
|
|
254
|
+
def service_chaos_status
|
|
255
|
+
status, response_body = request('GET', '/mockserver/serviceChaos')
|
|
256
|
+
if status >= 400
|
|
257
|
+
raise Error, "Failed to get service chaos (status=#{status}): #{response_body}"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
response_body && !response_body.empty? ? JSON.parse(response_body) : {}
|
|
261
|
+
end
|
|
262
|
+
|
|
151
263
|
# Verify that a request was received.
|
|
152
264
|
# @param request [HttpRequest]
|
|
153
265
|
# @param times [VerificationTimes, nil]
|
|
@@ -29,6 +29,14 @@ module MockServer
|
|
|
29
29
|
self
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Set a declarative HTTP chaos/fault injection profile.
|
|
33
|
+
# @param chaos [HttpChaosProfile]
|
|
34
|
+
# @return [self]
|
|
35
|
+
def with_chaos(chaos)
|
|
36
|
+
@expectation.chaos = chaos
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
# Set the response action. Accepts an HttpResponse, HttpTemplate, or
|
|
33
41
|
# a Proc/lambda callback.
|
|
34
42
|
# @param response_or_callback [HttpResponse, HttpTemplate, Proc]
|
|
@@ -113,5 +121,92 @@ module MockServer
|
|
|
113
121
|
@expectation.http_websocket_response = websocket_response
|
|
114
122
|
@client.upsert(@expectation)
|
|
115
123
|
end
|
|
124
|
+
|
|
125
|
+
# Set a gRPC stream response action.
|
|
126
|
+
# @param grpc_stream_response [GrpcStreamResponse]
|
|
127
|
+
# @return [Array<Expectation>]
|
|
128
|
+
def respond_with_grpc_stream(grpc_stream_response)
|
|
129
|
+
unless grpc_stream_response.is_a?(GrpcStreamResponse)
|
|
130
|
+
raise TypeError,
|
|
131
|
+
"Expected GrpcStreamResponse, got #{grpc_stream_response.class.name}"
|
|
132
|
+
end
|
|
133
|
+
@expectation.grpc_stream_response = grpc_stream_response
|
|
134
|
+
@client.upsert(@expectation)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Set a gRPC bidi streaming response action.
|
|
138
|
+
# @param grpc_bidi_response [GrpcBidiResponse]
|
|
139
|
+
# @return [Array<Expectation>]
|
|
140
|
+
def respond_with_grpc_bidi(grpc_bidi_response)
|
|
141
|
+
unless grpc_bidi_response.is_a?(GrpcBidiResponse)
|
|
142
|
+
raise TypeError,
|
|
143
|
+
"Expected GrpcBidiResponse, got #{grpc_bidi_response.class.name}"
|
|
144
|
+
end
|
|
145
|
+
@expectation.grpc_bidi_response = grpc_bidi_response
|
|
146
|
+
@client.upsert(@expectation)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Set a binary response action.
|
|
150
|
+
# @param binary_response [BinaryResponse]
|
|
151
|
+
# @return [Array<Expectation>]
|
|
152
|
+
def respond_with_binary(binary_response)
|
|
153
|
+
unless binary_response.is_a?(BinaryResponse)
|
|
154
|
+
raise TypeError,
|
|
155
|
+
"Expected BinaryResponse, got #{binary_response.class.name}"
|
|
156
|
+
end
|
|
157
|
+
@expectation.binary_response = binary_response
|
|
158
|
+
@client.upsert(@expectation)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Set a DNS response action.
|
|
162
|
+
# @param dns_response [DnsResponse]
|
|
163
|
+
# @return [Array<Expectation>]
|
|
164
|
+
def respond_with_dns(dns_response)
|
|
165
|
+
unless dns_response.is_a?(DnsResponse)
|
|
166
|
+
raise TypeError,
|
|
167
|
+
"Expected DnsResponse, got #{dns_response.class.name}"
|
|
168
|
+
end
|
|
169
|
+
@expectation.dns_response = dns_response
|
|
170
|
+
@client.upsert(@expectation)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Set a forward template action.
|
|
174
|
+
# @param template [HttpTemplate]
|
|
175
|
+
# @return [Array<Expectation>]
|
|
176
|
+
def forward_with_template(template)
|
|
177
|
+
unless template.is_a?(HttpTemplate)
|
|
178
|
+
raise TypeError,
|
|
179
|
+
"Expected HttpTemplate, got #{template.class.name}"
|
|
180
|
+
end
|
|
181
|
+
@expectation.http_forward_template = template
|
|
182
|
+
@client.upsert(@expectation)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Set a forward class callback action.
|
|
186
|
+
# @param class_callback [HttpClassCallback]
|
|
187
|
+
# @return [Array<Expectation>]
|
|
188
|
+
def forward_with_class_callback(class_callback)
|
|
189
|
+
unless class_callback.is_a?(HttpClassCallback)
|
|
190
|
+
raise TypeError,
|
|
191
|
+
"Expected HttpClassCallback, got #{class_callback.class.name}"
|
|
192
|
+
end
|
|
193
|
+
@expectation.http_forward_class_callback = class_callback
|
|
194
|
+
@client.upsert(@expectation)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Set an ordered multi-action pipeline of steps.
|
|
198
|
+
#
|
|
199
|
+
# Exactly one step must have +responder: true+; that step produces the
|
|
200
|
+
# HTTP response. All other steps are side-effects executed in order.
|
|
201
|
+
# @param steps [Array<ExpectationStep>]
|
|
202
|
+
# @return [Array<Expectation>]
|
|
203
|
+
def with_steps(steps)
|
|
204
|
+
unless steps.is_a?(Array) && steps.all? { |s| s.is_a?(ExpectationStep) }
|
|
205
|
+
raise TypeError, 'Expected an Array of ExpectationStep objects'
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@expectation.steps = steps
|
|
209
|
+
@client.upsert(@expectation)
|
|
210
|
+
end
|
|
116
211
|
end
|
|
117
212
|
end
|
data/lib/mockserver/models.rb
CHANGED
|
@@ -61,7 +61,27 @@ module MockServer
|
|
|
61
61
|
'base_path' => 'basePath',
|
|
62
62
|
'id_field' => 'idField',
|
|
63
63
|
'id_strategy' => 'idStrategy',
|
|
64
|
-
'initial_data' => 'initialData'
|
|
64
|
+
'initial_data' => 'initialData',
|
|
65
|
+
'error_status' => 'errorStatus',
|
|
66
|
+
'error_probability' => 'errorProbability',
|
|
67
|
+
'drop_connection_probability' => 'dropConnectionProbability',
|
|
68
|
+
'retry_after' => 'retryAfter',
|
|
69
|
+
'succeed_first' => 'succeedFirst',
|
|
70
|
+
'fail_request_count' => 'failRequestCount',
|
|
71
|
+
'outage_after_millis' => 'outageAfterMillis',
|
|
72
|
+
'outage_duration_millis' => 'outageDurationMillis',
|
|
73
|
+
'truncate_body_at_fraction' => 'truncateBodyAtFraction',
|
|
74
|
+
'malformed_body' => 'malformedBody',
|
|
75
|
+
'slow_response_chunk_size' => 'slowResponseChunkSize',
|
|
76
|
+
'slow_response_chunk_delay' => 'slowResponseChunkDelay',
|
|
77
|
+
'quota_name' => 'quotaName',
|
|
78
|
+
'quota_limit' => 'quotaLimit',
|
|
79
|
+
'quota_window_millis' => 'quotaWindowMillis',
|
|
80
|
+
'quota_error_status' => 'quotaErrorStatus',
|
|
81
|
+
'degradation_ramp_millis' => 'degradationRampMillis',
|
|
82
|
+
'http_class_callback' => 'httpClassCallback',
|
|
83
|
+
'http_object_callback' => 'httpObjectCallback',
|
|
84
|
+
'failure_policy' => 'failurePolicy'
|
|
65
85
|
}.freeze
|
|
66
86
|
|
|
67
87
|
REVERSE_FIELD_MAP = FIELD_MAP.invert.freeze
|
|
@@ -1146,14 +1166,396 @@ module MockServer
|
|
|
1146
1166
|
end
|
|
1147
1167
|
end
|
|
1148
1168
|
|
|
1169
|
+
class GrpcStreamMessage
|
|
1170
|
+
attr_accessor :json, :delay
|
|
1171
|
+
|
|
1172
|
+
def initialize(json: nil, delay: nil)
|
|
1173
|
+
@json = json
|
|
1174
|
+
@delay = delay
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
def to_h
|
|
1178
|
+
result = {}
|
|
1179
|
+
result['json'] = @json unless @json.nil?
|
|
1180
|
+
result['delay'] = @delay.to_h if @delay
|
|
1181
|
+
result
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
def self.from_hash(data)
|
|
1185
|
+
return nil if data.nil?
|
|
1186
|
+
|
|
1187
|
+
new(
|
|
1188
|
+
json: data['json'],
|
|
1189
|
+
delay: Delay.from_hash(data['delay'])
|
|
1190
|
+
)
|
|
1191
|
+
end
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
class GrpcStreamResponse
|
|
1195
|
+
attr_accessor :status_name, :status_message, :headers, :messages,
|
|
1196
|
+
:close_connection, :delay, :primary
|
|
1197
|
+
|
|
1198
|
+
def initialize(status_name: nil, status_message: nil, headers: nil,
|
|
1199
|
+
messages: nil, close_connection: nil, delay: nil, primary: nil)
|
|
1200
|
+
@status_name = status_name
|
|
1201
|
+
@status_message = status_message
|
|
1202
|
+
@headers = headers
|
|
1203
|
+
@messages = messages
|
|
1204
|
+
@close_connection = close_connection
|
|
1205
|
+
@delay = delay
|
|
1206
|
+
@primary = primary
|
|
1207
|
+
end
|
|
1208
|
+
|
|
1209
|
+
def to_h
|
|
1210
|
+
result = {}
|
|
1211
|
+
result['statusName'] = @status_name unless @status_name.nil?
|
|
1212
|
+
result['statusMessage'] = @status_message unless @status_message.nil?
|
|
1213
|
+
result['headers'] = MockServer.serialize_key_multi_values(@headers) if @headers
|
|
1214
|
+
result['messages'] = @messages&.map(&:to_h) if @messages
|
|
1215
|
+
result['closeConnection'] = @close_connection unless @close_connection.nil?
|
|
1216
|
+
result['delay'] = @delay.to_h if @delay
|
|
1217
|
+
result['primary'] = @primary unless @primary.nil?
|
|
1218
|
+
result
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
def self.from_hash(data)
|
|
1222
|
+
return nil if data.nil?
|
|
1223
|
+
|
|
1224
|
+
messages_data = data['messages']
|
|
1225
|
+
messages = messages_data&.map { |m| GrpcStreamMessage.from_hash(m) }
|
|
1226
|
+
new(
|
|
1227
|
+
status_name: data['statusName'],
|
|
1228
|
+
status_message: data['statusMessage'],
|
|
1229
|
+
headers: MockServer.deserialize_key_multi_values(data['headers']),
|
|
1230
|
+
messages: messages,
|
|
1231
|
+
close_connection: data['closeConnection'],
|
|
1232
|
+
delay: Delay.from_hash(data['delay']),
|
|
1233
|
+
primary: data['primary']
|
|
1234
|
+
)
|
|
1235
|
+
end
|
|
1236
|
+
end
|
|
1237
|
+
|
|
1238
|
+
class GrpcBidiRule
|
|
1239
|
+
attr_accessor :match_json, :responses
|
|
1240
|
+
|
|
1241
|
+
def initialize(match_json: nil, responses: nil)
|
|
1242
|
+
@match_json = match_json
|
|
1243
|
+
@responses = responses
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
def to_h
|
|
1247
|
+
result = {}
|
|
1248
|
+
result['matchJson'] = @match_json unless @match_json.nil?
|
|
1249
|
+
result['responses'] = @responses&.map(&:to_h) if @responses
|
|
1250
|
+
result
|
|
1251
|
+
end
|
|
1252
|
+
|
|
1253
|
+
def self.from_hash(data)
|
|
1254
|
+
return nil if data.nil?
|
|
1255
|
+
|
|
1256
|
+
responses_data = data['responses']
|
|
1257
|
+
responses = responses_data&.map { |r| GrpcStreamMessage.from_hash(r) }
|
|
1258
|
+
new(
|
|
1259
|
+
match_json: data['matchJson'],
|
|
1260
|
+
responses: responses
|
|
1261
|
+
)
|
|
1262
|
+
end
|
|
1263
|
+
end
|
|
1264
|
+
|
|
1265
|
+
class GrpcBidiResponse
|
|
1266
|
+
attr_accessor :status_name, :status_message, :headers, :messages,
|
|
1267
|
+
:rules, :close_connection, :delay, :primary
|
|
1268
|
+
|
|
1269
|
+
def initialize(status_name: nil, status_message: nil, headers: nil,
|
|
1270
|
+
messages: nil, rules: nil, close_connection: nil, delay: nil, primary: nil)
|
|
1271
|
+
@status_name = status_name
|
|
1272
|
+
@status_message = status_message
|
|
1273
|
+
@headers = headers
|
|
1274
|
+
@messages = messages
|
|
1275
|
+
@rules = rules
|
|
1276
|
+
@close_connection = close_connection
|
|
1277
|
+
@delay = delay
|
|
1278
|
+
@primary = primary
|
|
1279
|
+
end
|
|
1280
|
+
|
|
1281
|
+
def to_h
|
|
1282
|
+
result = {}
|
|
1283
|
+
result['statusName'] = @status_name unless @status_name.nil?
|
|
1284
|
+
result['statusMessage'] = @status_message unless @status_message.nil?
|
|
1285
|
+
result['headers'] = MockServer.serialize_key_multi_values(@headers) if @headers
|
|
1286
|
+
result['messages'] = @messages&.map(&:to_h) if @messages
|
|
1287
|
+
result['rules'] = @rules&.map(&:to_h) if @rules
|
|
1288
|
+
result['closeConnection'] = @close_connection unless @close_connection.nil?
|
|
1289
|
+
result['delay'] = @delay.to_h if @delay
|
|
1290
|
+
result['primary'] = @primary unless @primary.nil?
|
|
1291
|
+
result
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
def self.from_hash(data)
|
|
1295
|
+
return nil if data.nil?
|
|
1296
|
+
|
|
1297
|
+
messages_data = data['messages']
|
|
1298
|
+
messages = messages_data&.map { |m| GrpcStreamMessage.from_hash(m) }
|
|
1299
|
+
rules_data = data['rules']
|
|
1300
|
+
rules = rules_data&.map { |r| GrpcBidiRule.from_hash(r) }
|
|
1301
|
+
new(
|
|
1302
|
+
status_name: data['statusName'],
|
|
1303
|
+
status_message: data['statusMessage'],
|
|
1304
|
+
headers: MockServer.deserialize_key_multi_values(data['headers']),
|
|
1305
|
+
messages: messages,
|
|
1306
|
+
rules: rules,
|
|
1307
|
+
close_connection: data['closeConnection'],
|
|
1308
|
+
delay: Delay.from_hash(data['delay']),
|
|
1309
|
+
primary: data['primary']
|
|
1310
|
+
)
|
|
1311
|
+
end
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
class BinaryResponse
|
|
1315
|
+
attr_accessor :binary_data, :delay, :primary
|
|
1316
|
+
|
|
1317
|
+
def initialize(binary_data: nil, delay: nil, primary: nil)
|
|
1318
|
+
@binary_data = binary_data
|
|
1319
|
+
@delay = delay
|
|
1320
|
+
@primary = primary
|
|
1321
|
+
end
|
|
1322
|
+
|
|
1323
|
+
def to_h
|
|
1324
|
+
result = {}
|
|
1325
|
+
result['binaryData'] = @binary_data unless @binary_data.nil?
|
|
1326
|
+
result['delay'] = @delay.to_h if @delay
|
|
1327
|
+
result['primary'] = @primary unless @primary.nil?
|
|
1328
|
+
result
|
|
1329
|
+
end
|
|
1330
|
+
|
|
1331
|
+
def self.from_hash(data)
|
|
1332
|
+
return nil if data.nil?
|
|
1333
|
+
|
|
1334
|
+
new(
|
|
1335
|
+
binary_data: data['binaryData'],
|
|
1336
|
+
delay: Delay.from_hash(data['delay']),
|
|
1337
|
+
primary: data['primary']
|
|
1338
|
+
)
|
|
1339
|
+
end
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
class DnsRecord
|
|
1343
|
+
attr_accessor :name, :type, :dns_class, :ttl, :value,
|
|
1344
|
+
:priority, :weight, :port
|
|
1345
|
+
|
|
1346
|
+
def initialize(name: nil, type: nil, dns_class: nil, ttl: nil,
|
|
1347
|
+
value: nil, priority: nil, weight: nil, port: nil)
|
|
1348
|
+
@name = name
|
|
1349
|
+
@type = type
|
|
1350
|
+
@dns_class = dns_class
|
|
1351
|
+
@ttl = ttl
|
|
1352
|
+
@value = value
|
|
1353
|
+
@priority = priority
|
|
1354
|
+
@weight = weight
|
|
1355
|
+
@port = port
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1358
|
+
def to_h
|
|
1359
|
+
result = {}
|
|
1360
|
+
result['name'] = @name unless @name.nil?
|
|
1361
|
+
result['type'] = @type unless @type.nil?
|
|
1362
|
+
result['dnsClass'] = @dns_class unless @dns_class.nil?
|
|
1363
|
+
result['ttl'] = @ttl unless @ttl.nil?
|
|
1364
|
+
result['value'] = @value unless @value.nil?
|
|
1365
|
+
result['priority'] = @priority unless @priority.nil?
|
|
1366
|
+
result['weight'] = @weight unless @weight.nil?
|
|
1367
|
+
result['port'] = @port unless @port.nil?
|
|
1368
|
+
result
|
|
1369
|
+
end
|
|
1370
|
+
|
|
1371
|
+
def self.from_hash(data)
|
|
1372
|
+
return nil if data.nil?
|
|
1373
|
+
|
|
1374
|
+
new(
|
|
1375
|
+
name: data['name'],
|
|
1376
|
+
type: data['type'],
|
|
1377
|
+
dns_class: data['dnsClass'],
|
|
1378
|
+
ttl: data['ttl'],
|
|
1379
|
+
value: data['value'],
|
|
1380
|
+
priority: data['priority'],
|
|
1381
|
+
weight: data['weight'],
|
|
1382
|
+
port: data['port']
|
|
1383
|
+
)
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
def self.a_record(name, ip)
|
|
1387
|
+
new(name: name, type: 'A', value: ip)
|
|
1388
|
+
end
|
|
1389
|
+
|
|
1390
|
+
def self.aaaa_record(name, ip)
|
|
1391
|
+
new(name: name, type: 'AAAA', value: ip)
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1394
|
+
def self.cname_record(name, cname)
|
|
1395
|
+
new(name: name, type: 'CNAME', value: cname)
|
|
1396
|
+
end
|
|
1397
|
+
|
|
1398
|
+
def self.mx_record(name, priority, exchange)
|
|
1399
|
+
new(name: name, type: 'MX', priority: priority, value: exchange)
|
|
1400
|
+
end
|
|
1401
|
+
|
|
1402
|
+
def self.srv_record(name, priority, weight, port, target)
|
|
1403
|
+
new(name: name, type: 'SRV', priority: priority, weight: weight, port: port, value: target)
|
|
1404
|
+
end
|
|
1405
|
+
|
|
1406
|
+
def self.txt_record(name, text)
|
|
1407
|
+
new(name: name, type: 'TXT', value: text)
|
|
1408
|
+
end
|
|
1409
|
+
|
|
1410
|
+
def self.ptr_record(name, pointer)
|
|
1411
|
+
new(name: name, type: 'PTR', value: pointer)
|
|
1412
|
+
end
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1415
|
+
class DnsResponse
|
|
1416
|
+
attr_accessor :response_code, :answer_records, :authority_records,
|
|
1417
|
+
:additional_records, :delay, :primary
|
|
1418
|
+
|
|
1419
|
+
def initialize(response_code: nil, answer_records: nil, authority_records: nil,
|
|
1420
|
+
additional_records: nil, delay: nil, primary: nil)
|
|
1421
|
+
@response_code = response_code
|
|
1422
|
+
@answer_records = answer_records
|
|
1423
|
+
@authority_records = authority_records
|
|
1424
|
+
@additional_records = additional_records
|
|
1425
|
+
@delay = delay
|
|
1426
|
+
@primary = primary
|
|
1427
|
+
end
|
|
1428
|
+
|
|
1429
|
+
def to_h
|
|
1430
|
+
result = {}
|
|
1431
|
+
result['responseCode'] = @response_code unless @response_code.nil?
|
|
1432
|
+
result['answerRecords'] = @answer_records.map(&:to_h) if @answer_records
|
|
1433
|
+
result['authorityRecords'] = @authority_records.map(&:to_h) if @authority_records
|
|
1434
|
+
result['additionalRecords'] = @additional_records.map(&:to_h) if @additional_records
|
|
1435
|
+
result['delay'] = @delay.to_h if @delay
|
|
1436
|
+
result['primary'] = @primary unless @primary.nil?
|
|
1437
|
+
result
|
|
1438
|
+
end
|
|
1439
|
+
|
|
1440
|
+
def self.from_hash(data)
|
|
1441
|
+
return nil if data.nil?
|
|
1442
|
+
|
|
1443
|
+
answer_data = data['answerRecords']
|
|
1444
|
+
authority_data = data['authorityRecords']
|
|
1445
|
+
additional_data = data['additionalRecords']
|
|
1446
|
+
new(
|
|
1447
|
+
response_code: data['responseCode'],
|
|
1448
|
+
answer_records: answer_data&.map { |r| DnsRecord.from_hash(r) },
|
|
1449
|
+
authority_records: authority_data&.map { |r| DnsRecord.from_hash(r) },
|
|
1450
|
+
additional_records: additional_data&.map { |r| DnsRecord.from_hash(r) },
|
|
1451
|
+
delay: Delay.from_hash(data['delay']),
|
|
1452
|
+
primary: data['primary']
|
|
1453
|
+
)
|
|
1454
|
+
end
|
|
1455
|
+
end
|
|
1456
|
+
|
|
1457
|
+
class HttpChaosProfile
|
|
1458
|
+
attr_accessor :error_status, :error_probability, :drop_connection_probability,
|
|
1459
|
+
:retry_after, :latency, :seed, :succeed_first, :fail_request_count,
|
|
1460
|
+
:outage_after_millis, :outage_duration_millis,
|
|
1461
|
+
:truncate_body_at_fraction, :malformed_body,
|
|
1462
|
+
:slow_response_chunk_size, :slow_response_chunk_delay,
|
|
1463
|
+
:quota_name, :quota_limit, :quota_window_millis, :quota_error_status,
|
|
1464
|
+
:degradation_ramp_millis
|
|
1465
|
+
|
|
1466
|
+
def initialize(error_status: nil, error_probability: nil, drop_connection_probability: nil,
|
|
1467
|
+
retry_after: nil, latency: nil, seed: nil, succeed_first: nil, fail_request_count: nil,
|
|
1468
|
+
outage_after_millis: nil, outage_duration_millis: nil,
|
|
1469
|
+
truncate_body_at_fraction: nil, malformed_body: nil,
|
|
1470
|
+
slow_response_chunk_size: nil, slow_response_chunk_delay: nil,
|
|
1471
|
+
quota_name: nil, quota_limit: nil, quota_window_millis: nil, quota_error_status: nil,
|
|
1472
|
+
degradation_ramp_millis: nil)
|
|
1473
|
+
@error_status = error_status
|
|
1474
|
+
@error_probability = error_probability
|
|
1475
|
+
@drop_connection_probability = drop_connection_probability
|
|
1476
|
+
@retry_after = retry_after
|
|
1477
|
+
@latency = latency
|
|
1478
|
+
@seed = seed
|
|
1479
|
+
@succeed_first = succeed_first
|
|
1480
|
+
@fail_request_count = fail_request_count
|
|
1481
|
+
@outage_after_millis = outage_after_millis
|
|
1482
|
+
@outage_duration_millis = outage_duration_millis
|
|
1483
|
+
@truncate_body_at_fraction = truncate_body_at_fraction
|
|
1484
|
+
@malformed_body = malformed_body
|
|
1485
|
+
@slow_response_chunk_size = slow_response_chunk_size
|
|
1486
|
+
@slow_response_chunk_delay = slow_response_chunk_delay
|
|
1487
|
+
@quota_name = quota_name
|
|
1488
|
+
@quota_limit = quota_limit
|
|
1489
|
+
@quota_window_millis = quota_window_millis
|
|
1490
|
+
@quota_error_status = quota_error_status
|
|
1491
|
+
@degradation_ramp_millis = degradation_ramp_millis
|
|
1492
|
+
end
|
|
1493
|
+
|
|
1494
|
+
def to_h
|
|
1495
|
+
MockServer.strip_none({
|
|
1496
|
+
'errorStatus' => @error_status,
|
|
1497
|
+
'errorProbability' => @error_probability,
|
|
1498
|
+
'dropConnectionProbability' => @drop_connection_probability,
|
|
1499
|
+
'retryAfter' => @retry_after,
|
|
1500
|
+
'latency' => @latency&.to_h,
|
|
1501
|
+
'seed' => @seed,
|
|
1502
|
+
'succeedFirst' => @succeed_first,
|
|
1503
|
+
'failRequestCount' => @fail_request_count,
|
|
1504
|
+
'outageAfterMillis' => @outage_after_millis,
|
|
1505
|
+
'outageDurationMillis' => @outage_duration_millis,
|
|
1506
|
+
'truncateBodyAtFraction' => @truncate_body_at_fraction,
|
|
1507
|
+
'malformedBody' => @malformed_body,
|
|
1508
|
+
'slowResponseChunkSize' => @slow_response_chunk_size,
|
|
1509
|
+
'slowResponseChunkDelay' => @slow_response_chunk_delay&.to_h,
|
|
1510
|
+
'quotaName' => @quota_name,
|
|
1511
|
+
'quotaLimit' => @quota_limit,
|
|
1512
|
+
'quotaWindowMillis' => @quota_window_millis,
|
|
1513
|
+
'quotaErrorStatus' => @quota_error_status,
|
|
1514
|
+
'degradationRampMillis' => @degradation_ramp_millis
|
|
1515
|
+
})
|
|
1516
|
+
end
|
|
1517
|
+
|
|
1518
|
+
def self.from_hash(data)
|
|
1519
|
+
return nil if data.nil?
|
|
1520
|
+
|
|
1521
|
+
new(
|
|
1522
|
+
error_status: data['errorStatus'],
|
|
1523
|
+
error_probability: data['errorProbability'],
|
|
1524
|
+
drop_connection_probability: data['dropConnectionProbability'],
|
|
1525
|
+
retry_after: data['retryAfter'],
|
|
1526
|
+
latency: Delay.from_hash(data['latency']),
|
|
1527
|
+
seed: data['seed'],
|
|
1528
|
+
succeed_first: data['succeedFirst'],
|
|
1529
|
+
fail_request_count: data['failRequestCount'],
|
|
1530
|
+
outage_after_millis: data['outageAfterMillis'],
|
|
1531
|
+
outage_duration_millis: data['outageDurationMillis'],
|
|
1532
|
+
truncate_body_at_fraction: data['truncateBodyAtFraction'],
|
|
1533
|
+
malformed_body: data['malformedBody'],
|
|
1534
|
+
slow_response_chunk_size: data['slowResponseChunkSize'],
|
|
1535
|
+
slow_response_chunk_delay: Delay.from_hash(data['slowResponseChunkDelay']),
|
|
1536
|
+
quota_name: data['quotaName'],
|
|
1537
|
+
quota_limit: data['quotaLimit'],
|
|
1538
|
+
quota_window_millis: data['quotaWindowMillis'],
|
|
1539
|
+
quota_error_status: data['quotaErrorStatus'],
|
|
1540
|
+
degradation_ramp_millis: data['degradationRampMillis']
|
|
1541
|
+
)
|
|
1542
|
+
end
|
|
1543
|
+
end
|
|
1544
|
+
|
|
1149
1545
|
class AfterAction
|
|
1150
|
-
|
|
1546
|
+
# blocking, timeout and failure_policy are only meaningful for before-actions
|
|
1547
|
+
attr_accessor :http_request, :http_class_callback, :http_object_callback, :delay,
|
|
1548
|
+
:blocking, :timeout, :failure_policy
|
|
1151
1549
|
|
|
1152
|
-
def initialize(http_request: nil, http_class_callback: nil, http_object_callback: nil, delay: nil
|
|
1550
|
+
def initialize(http_request: nil, http_class_callback: nil, http_object_callback: nil, delay: nil,
|
|
1551
|
+
blocking: nil, timeout: nil, failure_policy: nil)
|
|
1153
1552
|
@http_request = http_request
|
|
1154
1553
|
@http_class_callback = http_class_callback
|
|
1155
1554
|
@http_object_callback = http_object_callback
|
|
1156
1555
|
@delay = delay
|
|
1556
|
+
@blocking = blocking
|
|
1557
|
+
@timeout = timeout
|
|
1558
|
+
@failure_policy = failure_policy
|
|
1157
1559
|
end
|
|
1158
1560
|
|
|
1159
1561
|
def to_h
|
|
@@ -1161,7 +1563,10 @@ module MockServer
|
|
|
1161
1563
|
'httpRequest' => @http_request&.to_h,
|
|
1162
1564
|
'httpClassCallback' => @http_class_callback&.to_h,
|
|
1163
1565
|
'httpObjectCallback' => @http_object_callback&.to_h,
|
|
1164
|
-
'delay' => @delay&.to_h
|
|
1566
|
+
'delay' => @delay&.to_h,
|
|
1567
|
+
'blocking' => @blocking,
|
|
1568
|
+
'timeout' => @timeout&.to_h,
|
|
1569
|
+
'failurePolicy' => @failure_policy
|
|
1165
1570
|
})
|
|
1166
1571
|
end
|
|
1167
1572
|
|
|
@@ -1172,7 +1577,77 @@ module MockServer
|
|
|
1172
1577
|
http_request: HttpRequest.from_hash(data['httpRequest']),
|
|
1173
1578
|
http_class_callback: HttpClassCallback.from_hash(data['httpClassCallback']),
|
|
1174
1579
|
http_object_callback: HttpObjectCallback.from_hash(data['httpObjectCallback']),
|
|
1175
|
-
delay: Delay.from_hash(data['delay'])
|
|
1580
|
+
delay: Delay.from_hash(data['delay']),
|
|
1581
|
+
blocking: data['blocking'],
|
|
1582
|
+
timeout: Delay.from_hash(data['timeout']),
|
|
1583
|
+
failure_policy: data['failurePolicy']
|
|
1584
|
+
)
|
|
1585
|
+
end
|
|
1586
|
+
end
|
|
1587
|
+
|
|
1588
|
+
# A single step in an ordered multi-action expectation pipeline.
|
|
1589
|
+
#
|
|
1590
|
+
# Each step carries exactly ONE action target and a +responder+ flag.
|
|
1591
|
+
# Steps without +responder = true+ are side-effects (fire-and-forget
|
|
1592
|
+
# webhooks/callbacks). Exactly one step in the list must be marked as the
|
|
1593
|
+
# responder; that step's action produces the HTTP response.
|
|
1594
|
+
class ExpectationStep
|
|
1595
|
+
attr_accessor :http_request, :http_class_callback, :http_object_callback,
|
|
1596
|
+
:http_forward, :http_override_forwarded_request,
|
|
1597
|
+
:http_response, :http_error,
|
|
1598
|
+
:responder, :delay, :blocking, :timeout, :failure_policy
|
|
1599
|
+
|
|
1600
|
+
def initialize(http_request: nil, http_class_callback: nil, http_object_callback: nil,
|
|
1601
|
+
http_forward: nil, http_override_forwarded_request: nil,
|
|
1602
|
+
http_response: nil, http_error: nil,
|
|
1603
|
+
responder: nil, delay: nil, blocking: nil, timeout: nil, failure_policy: nil)
|
|
1604
|
+
@http_request = http_request
|
|
1605
|
+
@http_class_callback = http_class_callback
|
|
1606
|
+
@http_object_callback = http_object_callback
|
|
1607
|
+
@http_forward = http_forward
|
|
1608
|
+
@http_override_forwarded_request = http_override_forwarded_request
|
|
1609
|
+
@http_response = http_response
|
|
1610
|
+
@http_error = http_error
|
|
1611
|
+
@responder = responder
|
|
1612
|
+
@delay = delay
|
|
1613
|
+
@blocking = blocking
|
|
1614
|
+
@timeout = timeout
|
|
1615
|
+
@failure_policy = failure_policy
|
|
1616
|
+
end
|
|
1617
|
+
|
|
1618
|
+
def to_h
|
|
1619
|
+
MockServer.strip_none({
|
|
1620
|
+
'httpRequest' => @http_request&.to_h,
|
|
1621
|
+
'httpClassCallback' => @http_class_callback&.to_h,
|
|
1622
|
+
'httpObjectCallback' => @http_object_callback&.to_h,
|
|
1623
|
+
'httpForward' => @http_forward&.to_h,
|
|
1624
|
+
'httpOverrideForwardedRequest' => @http_override_forwarded_request&.to_h,
|
|
1625
|
+
'httpResponse' => @http_response&.to_h,
|
|
1626
|
+
'httpError' => @http_error&.to_h,
|
|
1627
|
+
'responder' => @responder,
|
|
1628
|
+
'delay' => @delay&.to_h,
|
|
1629
|
+
'blocking' => @blocking,
|
|
1630
|
+
'timeout' => @timeout&.to_h,
|
|
1631
|
+
'failurePolicy' => @failure_policy
|
|
1632
|
+
})
|
|
1633
|
+
end
|
|
1634
|
+
|
|
1635
|
+
def self.from_hash(data)
|
|
1636
|
+
return nil if data.nil?
|
|
1637
|
+
|
|
1638
|
+
new(
|
|
1639
|
+
http_request: HttpRequest.from_hash(data['httpRequest']),
|
|
1640
|
+
http_class_callback: HttpClassCallback.from_hash(data['httpClassCallback']),
|
|
1641
|
+
http_object_callback: HttpObjectCallback.from_hash(data['httpObjectCallback']),
|
|
1642
|
+
http_forward: HttpForward.from_hash(data['httpForward']),
|
|
1643
|
+
http_override_forwarded_request: HttpOverrideForwardedRequest.from_hash(data['httpOverrideForwardedRequest']),
|
|
1644
|
+
http_response: HttpResponse.from_hash(data['httpResponse']),
|
|
1645
|
+
http_error: HttpError.from_hash(data['httpError']),
|
|
1646
|
+
responder: data['responder'],
|
|
1647
|
+
delay: Delay.from_hash(data['delay']),
|
|
1648
|
+
blocking: data['blocking'],
|
|
1649
|
+
timeout: Delay.from_hash(data['timeout']),
|
|
1650
|
+
failure_policy: data['failurePolicy']
|
|
1176
1651
|
)
|
|
1177
1652
|
end
|
|
1178
1653
|
end
|
|
@@ -1183,9 +1658,12 @@ module MockServer
|
|
|
1183
1658
|
:http_response_object_callback, :http_forward,
|
|
1184
1659
|
:http_forward_template, :http_forward_class_callback,
|
|
1185
1660
|
:http_forward_object_callback, :http_override_forwarded_request,
|
|
1186
|
-
:http_error, :times, :time_to_live,
|
|
1187
|
-
:http_sse_response, :http_websocket_response,
|
|
1188
|
-
:
|
|
1661
|
+
:http_error, :times, :time_to_live, :chaos,
|
|
1662
|
+
:http_sse_response, :http_websocket_response,
|
|
1663
|
+
:grpc_stream_response, :grpc_bidi_response,
|
|
1664
|
+
:binary_response, :dns_response,
|
|
1665
|
+
:before_actions, :after_actions,
|
|
1666
|
+
:http_responses, :response_mode, :steps,
|
|
1189
1667
|
:scenario_name, :scenario_state, :new_scenario_state
|
|
1190
1668
|
|
|
1191
1669
|
def initialize(id: nil, priority: nil, percentage: nil, http_request: nil, http_response: nil,
|
|
@@ -1193,9 +1671,12 @@ module MockServer
|
|
|
1193
1671
|
http_response_object_callback: nil, http_forward: nil,
|
|
1194
1672
|
http_forward_template: nil, http_forward_class_callback: nil,
|
|
1195
1673
|
http_forward_object_callback: nil, http_override_forwarded_request: nil,
|
|
1196
|
-
http_error: nil, times: nil, time_to_live: nil,
|
|
1197
|
-
http_sse_response: nil, http_websocket_response: nil,
|
|
1198
|
-
|
|
1674
|
+
http_error: nil, times: nil, time_to_live: nil, chaos: nil,
|
|
1675
|
+
http_sse_response: nil, http_websocket_response: nil,
|
|
1676
|
+
grpc_stream_response: nil, grpc_bidi_response: nil,
|
|
1677
|
+
binary_response: nil, dns_response: nil,
|
|
1678
|
+
before_actions: nil, after_actions: nil,
|
|
1679
|
+
http_responses: nil, response_mode: nil, steps: nil,
|
|
1199
1680
|
scenario_name: nil, scenario_state: nil, new_scenario_state: nil)
|
|
1200
1681
|
@id = id
|
|
1201
1682
|
@priority = priority
|
|
@@ -1213,17 +1694,31 @@ module MockServer
|
|
|
1213
1694
|
@http_error = http_error
|
|
1214
1695
|
@times = times
|
|
1215
1696
|
@time_to_live = time_to_live
|
|
1697
|
+
@chaos = chaos
|
|
1216
1698
|
@http_sse_response = http_sse_response
|
|
1217
1699
|
@http_websocket_response = http_websocket_response
|
|
1700
|
+
@grpc_stream_response = grpc_stream_response
|
|
1701
|
+
@grpc_bidi_response = grpc_bidi_response
|
|
1702
|
+
@binary_response = binary_response
|
|
1703
|
+
@dns_response = dns_response
|
|
1704
|
+
@before_actions = before_actions
|
|
1218
1705
|
@after_actions = after_actions
|
|
1219
1706
|
@http_responses = http_responses
|
|
1220
1707
|
@response_mode = response_mode
|
|
1708
|
+
@steps = steps
|
|
1221
1709
|
@scenario_name = scenario_name
|
|
1222
1710
|
@scenario_state = scenario_state
|
|
1223
1711
|
@new_scenario_state = new_scenario_state
|
|
1224
1712
|
end
|
|
1225
1713
|
|
|
1226
1714
|
def to_h
|
|
1715
|
+
before_actions_h = nil
|
|
1716
|
+
if @before_actions.is_a?(Array)
|
|
1717
|
+
before_actions_h = @before_actions.map(&:to_h) unless @before_actions.empty?
|
|
1718
|
+
elsif @before_actions
|
|
1719
|
+
before_actions_h = @before_actions.to_h
|
|
1720
|
+
end
|
|
1721
|
+
|
|
1227
1722
|
after_actions_h = nil
|
|
1228
1723
|
if @after_actions.is_a?(Array)
|
|
1229
1724
|
after_actions_h = @after_actions.map(&:to_h) unless @after_actions.empty?
|
|
@@ -1248,11 +1743,18 @@ module MockServer
|
|
|
1248
1743
|
'httpError' => @http_error&.to_h,
|
|
1249
1744
|
'httpSseResponse' => @http_sse_response&.to_h,
|
|
1250
1745
|
'httpWebSocketResponse' => @http_websocket_response&.to_h,
|
|
1746
|
+
'grpcStreamResponse' => @grpc_stream_response&.to_h,
|
|
1747
|
+
'grpcBidiResponse' => @grpc_bidi_response&.to_h,
|
|
1748
|
+
'binaryResponse' => @binary_response&.to_h,
|
|
1749
|
+
'dnsResponse' => @dns_response&.to_h,
|
|
1750
|
+
'beforeActions' => before_actions_h,
|
|
1251
1751
|
'afterActions' => after_actions_h,
|
|
1252
1752
|
'httpResponses' => @http_responses&.map(&:to_h),
|
|
1253
1753
|
'responseMode' => @response_mode,
|
|
1754
|
+
'steps' => @steps&.map(&:to_h),
|
|
1254
1755
|
'times' => @times&.to_h,
|
|
1255
1756
|
'timeToLive' => @time_to_live&.to_h,
|
|
1757
|
+
'chaos' => @chaos&.to_h,
|
|
1256
1758
|
'scenarioName' => @scenario_name,
|
|
1257
1759
|
'scenarioState' => @scenario_state,
|
|
1258
1760
|
'newScenarioState' => @new_scenario_state
|
|
@@ -1262,11 +1764,18 @@ module MockServer
|
|
|
1262
1764
|
def self.from_hash(data)
|
|
1263
1765
|
return nil if data.nil?
|
|
1264
1766
|
|
|
1767
|
+
before_actions_data = data['beforeActions']
|
|
1768
|
+
before_actions = if before_actions_data.is_a?(Array)
|
|
1769
|
+
before_actions_data.map { |a| AfterAction.from_hash(a) }
|
|
1770
|
+
elsif before_actions_data
|
|
1771
|
+
[AfterAction.from_hash(before_actions_data)]
|
|
1772
|
+
end
|
|
1773
|
+
|
|
1265
1774
|
after_actions_data = data['afterActions']
|
|
1266
1775
|
after_actions = if after_actions_data.is_a?(Array)
|
|
1267
1776
|
after_actions_data.map { |a| AfterAction.from_hash(a) }
|
|
1268
1777
|
elsif after_actions_data
|
|
1269
|
-
AfterAction.from_hash(after_actions_data)
|
|
1778
|
+
[AfterAction.from_hash(after_actions_data)]
|
|
1270
1779
|
end
|
|
1271
1780
|
|
|
1272
1781
|
new(
|
|
@@ -1286,11 +1795,18 @@ module MockServer
|
|
|
1286
1795
|
http_error: HttpError.from_hash(data['httpError']),
|
|
1287
1796
|
http_sse_response: HttpSseResponse.from_hash(data['httpSseResponse']),
|
|
1288
1797
|
http_websocket_response: HttpWebSocketResponse.from_hash(data['httpWebSocketResponse']),
|
|
1798
|
+
grpc_stream_response: GrpcStreamResponse.from_hash(data['grpcStreamResponse']),
|
|
1799
|
+
grpc_bidi_response: GrpcBidiResponse.from_hash(data['grpcBidiResponse']),
|
|
1800
|
+
binary_response: BinaryResponse.from_hash(data['binaryResponse']),
|
|
1801
|
+
dns_response: DnsResponse.from_hash(data['dnsResponse']),
|
|
1802
|
+
before_actions: before_actions,
|
|
1289
1803
|
after_actions: after_actions,
|
|
1290
1804
|
http_responses: data['httpResponses']&.map { |r| HttpResponse.from_hash(r) },
|
|
1291
1805
|
response_mode: data['responseMode'],
|
|
1806
|
+
steps: data['steps']&.map { |s| ExpectationStep.from_hash(s) },
|
|
1292
1807
|
times: Times.from_hash(data['times']),
|
|
1293
1808
|
time_to_live: TimeToLive.from_hash(data['timeToLive']),
|
|
1809
|
+
chaos: HttpChaosProfile.from_hash(data['chaos']),
|
|
1294
1810
|
scenario_name: data['scenarioName'],
|
|
1295
1811
|
scenario_state: data['scenarioState'],
|
|
1296
1812
|
new_scenario_state: data['newScenarioState']
|
data/lib/mockserver/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mockserver-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 7.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Bloom
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: logger
|