hastci 0.1.0 → 0.1.1
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/devenv.lock +10 -10
- data/lib/hastci/api_client.rb +33 -20
- data/lib/hastci/config.rb +1 -1
- data/lib/hastci/heartbeat.rb +3 -2
- data/lib/hastci/session.rb +2 -1
- data/lib/hastci/version.rb +1 -1
- data/spec/pacts/hastci_rspec-hastci_api.json +139 -28
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7d454a50c04ff233b5cb379678b92e0aeaa04f9e7b116307a7e89678fbe26be
|
|
4
|
+
data.tar.gz: 1228b92fd4be4ba6717af33b0c0c771cb1e17315eb8648b04397d4b13ab74d6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d731397122285e81f9bc3b410474bf7ff828b2d16f32320d2150c055e46b245a86f50a7e15f67bcd943365549de360e61783f49794db2ff901c193cb131e9ce7
|
|
7
|
+
data.tar.gz: 7e25b68ce224aae1953c5eb797b073dc4900fad52d3537cc497543ef7cb5215d319edef657d3f6a9a6f3358d5ec5b2d8aa8f816b8f85bb672c682cb45f8b016c
|
data/devenv.lock
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"devenv": {
|
|
4
4
|
"locked": {
|
|
5
5
|
"dir": "src/modules",
|
|
6
|
-
"lastModified":
|
|
6
|
+
"lastModified": 1766921574,
|
|
7
7
|
"owner": "cachix",
|
|
8
8
|
"repo": "devenv",
|
|
9
|
-
"rev": "
|
|
9
|
+
"rev": "02c9dcf3e050400d8101057f9f00ec458af7c959",
|
|
10
10
|
"type": "github"
|
|
11
11
|
},
|
|
12
12
|
"original": {
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"flake-compat": {
|
|
20
20
|
"flake": false,
|
|
21
21
|
"locked": {
|
|
22
|
-
"lastModified":
|
|
22
|
+
"lastModified": 1766929376,
|
|
23
23
|
"owner": "edolstra",
|
|
24
24
|
"repo": "flake-compat",
|
|
25
|
-
"rev": "
|
|
25
|
+
"rev": "236f248441a986331cda53b039e7f9fd96e03635",
|
|
26
26
|
"type": "github"
|
|
27
27
|
},
|
|
28
28
|
"original": {
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"flake-compat_2": {
|
|
35
35
|
"flake": false,
|
|
36
36
|
"locked": {
|
|
37
|
-
"lastModified":
|
|
37
|
+
"lastModified": 1766929376,
|
|
38
38
|
"owner": "edolstra",
|
|
39
39
|
"repo": "flake-compat",
|
|
40
|
-
"rev": "
|
|
40
|
+
"rev": "236f248441a986331cda53b039e7f9fd96e03635",
|
|
41
41
|
"type": "github"
|
|
42
42
|
},
|
|
43
43
|
"original": {
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
"locked": {
|
|
75
|
-
"lastModified":
|
|
75
|
+
"lastModified": 1765911976,
|
|
76
76
|
"owner": "cachix",
|
|
77
77
|
"repo": "git-hooks.nix",
|
|
78
|
-
"rev": "
|
|
78
|
+
"rev": "b68b780b69702a090c8bb1b973bab13756cc7a27",
|
|
79
79
|
"type": "github"
|
|
80
80
|
},
|
|
81
81
|
"original": {
|
|
@@ -128,10 +128,10 @@
|
|
|
128
128
|
]
|
|
129
129
|
},
|
|
130
130
|
"locked": {
|
|
131
|
-
"lastModified":
|
|
131
|
+
"lastModified": 1766728475,
|
|
132
132
|
"owner": "bobvanderlinden",
|
|
133
133
|
"repo": "nixpkgs-ruby",
|
|
134
|
-
"rev": "
|
|
134
|
+
"rev": "f167828eab19c3a7e3faa066a140d92e307f7b16",
|
|
135
135
|
"type": "github"
|
|
136
136
|
},
|
|
137
137
|
"original": {
|
data/lib/hastci/api_client.rb
CHANGED
|
@@ -18,13 +18,15 @@ module HastCI
|
|
|
18
18
|
private_constant :DEFAULT_MAX_RETRIES, :DEFAULT_INITIAL_BACKOFF, :DEFAULT_MAX_BACKOFF,
|
|
19
19
|
:DEFAULT_KEEP_ALIVE_TIMEOUT, :DEFAULT_OPEN_TIMEOUT, :DEFAULT_READ_TIMEOUT, :DEFAULT_WRITE_TIMEOUT
|
|
20
20
|
|
|
21
|
+
API_PATH_PREFIX = "/api/v1"
|
|
22
|
+
|
|
21
23
|
# Separate connections allow concurrent operations without blocking.
|
|
22
24
|
# E.g., heartbeat can continue while the main thread waits on a claim.
|
|
23
25
|
CONNECTION_DEFAULT = :default
|
|
24
26
|
CONNECTION_HEARTBEAT = :heartbeat
|
|
25
27
|
CONNECTION_ACK = :ack
|
|
26
28
|
|
|
27
|
-
private_constant :CONNECTION_DEFAULT, :CONNECTION_HEARTBEAT, :CONNECTION_ACK
|
|
29
|
+
private_constant :API_PATH_PREFIX, :CONNECTION_DEFAULT, :CONNECTION_HEARTBEAT, :CONNECTION_ACK
|
|
28
30
|
|
|
29
31
|
def initialize(config:, sleeper: Kernel.method(:sleep), max_retries: nil, random: Random.new)
|
|
30
32
|
@config = config
|
|
@@ -56,52 +58,54 @@ module HastCI
|
|
|
56
58
|
commit_sha: @config.commit_sha
|
|
57
59
|
)
|
|
58
60
|
response = ensure_hash_response(
|
|
59
|
-
post_json("/runs
|
|
61
|
+
post_json("#{API_PATH_PREFIX}/runs", {
|
|
60
62
|
run_key: run_key,
|
|
61
63
|
worker_id: worker_id,
|
|
62
64
|
commit_sha: commit_sha
|
|
63
65
|
}),
|
|
64
|
-
context: "/runs
|
|
66
|
+
context: "#{API_PATH_PREFIX}/runs"
|
|
65
67
|
)
|
|
66
68
|
|
|
67
69
|
{
|
|
68
|
-
run_id: fetch_required(response, "run_id", context: "/runs
|
|
69
|
-
status: fetch_required(response, "status", context: "/runs
|
|
70
|
-
role: fetch_required(response, "role", context: "/runs
|
|
70
|
+
run_id: fetch_required(response, "run_id", context: "#{API_PATH_PREFIX}/runs"),
|
|
71
|
+
status: fetch_required(response, "status", context: "#{API_PATH_PREFIX}/runs").to_sym,
|
|
72
|
+
role: fetch_required(response, "role", context: "#{API_PATH_PREFIX}/runs").to_sym
|
|
71
73
|
}
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def seed(run_id:, tasks:)
|
|
75
|
-
post_json("/runs/#{run_id}/seed", {
|
|
77
|
+
post_json("#{API_PATH_PREFIX}/runs/#{run_id}/seed", {
|
|
76
78
|
tasks: tasks.map { |name| {name: name} }
|
|
77
79
|
})
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def run_status(run_id:)
|
|
81
|
-
response = ensure_hash_response(
|
|
83
|
+
response = ensure_hash_response(
|
|
84
|
+
get_json("#{API_PATH_PREFIX}/runs/#{run_id}"),
|
|
85
|
+
context: "#{API_PATH_PREFIX}/runs/:run_id"
|
|
86
|
+
)
|
|
82
87
|
|
|
83
88
|
{
|
|
84
|
-
status: fetch_required(response, "status", context: "/runs
|
|
89
|
+
status: fetch_required(response, "status", context: "#{API_PATH_PREFIX}/runs/:run_id").to_sym
|
|
85
90
|
}
|
|
86
91
|
end
|
|
87
92
|
|
|
88
93
|
def claim(
|
|
89
|
-
|
|
94
|
+
run_id:,
|
|
90
95
|
worker_id: @config.worker_id,
|
|
91
96
|
batch: @config.claim_batch_size
|
|
92
97
|
)
|
|
93
98
|
response = ensure_hash_response(
|
|
94
|
-
post_json("/
|
|
95
|
-
run_key: run_key,
|
|
99
|
+
post_json("#{API_PATH_PREFIX}/runs/#{run_id}/claims?batch=#{batch}", {
|
|
96
100
|
worker_id: worker_id
|
|
97
101
|
}),
|
|
98
|
-
context: "/
|
|
102
|
+
context: "#{API_PATH_PREFIX}/runs/:run_id/claims"
|
|
99
103
|
)
|
|
100
104
|
|
|
101
105
|
tasks = Array(response.fetch("tasks", [])).map do |task_data|
|
|
102
106
|
Task.new(
|
|
103
|
-
id: fetch_required(task_data, "id", context: "/
|
|
104
|
-
name: fetch_required(task_data, "name", context: "/
|
|
107
|
+
id: fetch_required(task_data, "id", context: "#{API_PATH_PREFIX}/runs/:run_id/claims"),
|
|
108
|
+
name: fetch_required(task_data, "name", context: "#{API_PATH_PREFIX}/runs/:run_id/claims")
|
|
105
109
|
)
|
|
106
110
|
end
|
|
107
111
|
|
|
@@ -114,7 +118,7 @@ module HastCI
|
|
|
114
118
|
end
|
|
115
119
|
|
|
116
120
|
def ack(task_id:, status:, duration_s:, logs:)
|
|
117
|
-
post_json("/tasks/#{task_id}/
|
|
121
|
+
post_json("#{API_PATH_PREFIX}/tasks/#{task_id}/acknowledgment", {
|
|
118
122
|
status: status.to_s,
|
|
119
123
|
duration_s: duration_s,
|
|
120
124
|
logs: logs
|
|
@@ -122,11 +126,10 @@ module HastCI
|
|
|
122
126
|
end
|
|
123
127
|
|
|
124
128
|
def heartbeat(
|
|
125
|
-
|
|
129
|
+
run_id:,
|
|
126
130
|
worker_id: @config.worker_id
|
|
127
131
|
)
|
|
128
|
-
post_json("/
|
|
129
|
-
run_key: run_key,
|
|
132
|
+
post_json("#{API_PATH_PREFIX}/runs/#{run_id}/heartbeats", {
|
|
130
133
|
worker_id: worker_id
|
|
131
134
|
}, pool: CONNECTION_HEARTBEAT)
|
|
132
135
|
|
|
@@ -176,12 +179,13 @@ module HastCI
|
|
|
176
179
|
|
|
177
180
|
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time if @config.debug
|
|
178
181
|
log_response(response, request_id, elapsed) if @config.debug
|
|
182
|
+
log_error_body(response, request_id) if @config.debug && response.code.to_i >= 400
|
|
179
183
|
parse_response(response)
|
|
180
184
|
end
|
|
181
185
|
end
|
|
182
186
|
|
|
183
187
|
def log_request(request, request_id)
|
|
184
|
-
HastCI.logger.debug("[#{request_id}] #{request.method} #{request.path}")
|
|
188
|
+
HastCI.logger.debug("[#{request_id}] #{request.method} #{@base_url}#{request.path}")
|
|
185
189
|
return unless request.body
|
|
186
190
|
|
|
187
191
|
body_preview = if request.body.length > 200
|
|
@@ -196,6 +200,15 @@ module HastCI
|
|
|
196
200
|
HastCI.logger.debug("[#{request_id}] Response: #{response.code} (#{(elapsed_s * 1000).round}ms)")
|
|
197
201
|
end
|
|
198
202
|
|
|
203
|
+
def log_error_body(response, request_id)
|
|
204
|
+
body = response.body.to_s
|
|
205
|
+
return if body.strip.empty?
|
|
206
|
+
|
|
207
|
+
summary = body.match(/No route matches[^<]*/)&.to_s
|
|
208
|
+
body_preview = summary || ((body.length > 200) ? "#{body[0, 200]}... (#{body.length} bytes)" : body)
|
|
209
|
+
HastCI.logger.debug("[#{request_id}] Error body: #{body_preview}")
|
|
210
|
+
end
|
|
211
|
+
|
|
199
212
|
def log_retry(request_id, attempt)
|
|
200
213
|
HastCI.logger.debug("[#{request_id}] Retry attempt #{attempt}")
|
|
201
214
|
end
|
data/lib/hastci/config.rb
CHANGED
data/lib/hastci/heartbeat.rb
CHANGED
|
@@ -7,8 +7,9 @@ module HastCI
|
|
|
7
7
|
|
|
8
8
|
private_constant :SHUTDOWN_TIMEOUT, :MAX_CONSECUTIVE_FAILURES
|
|
9
9
|
|
|
10
|
-
def initialize(api_client:, error_collector: nil, interval: 15)
|
|
10
|
+
def initialize(api_client:, run_id:, error_collector: nil, interval: 15)
|
|
11
11
|
@api_client = api_client
|
|
12
|
+
@run_id = run_id
|
|
12
13
|
@error_collector = error_collector
|
|
13
14
|
@interval = interval
|
|
14
15
|
@running = false
|
|
@@ -64,7 +65,7 @@ module HastCI
|
|
|
64
65
|
end
|
|
65
66
|
|
|
66
67
|
def send_heartbeat
|
|
67
|
-
@api_client.heartbeat
|
|
68
|
+
@api_client.heartbeat(run_id: @run_id)
|
|
68
69
|
@consecutive_failures = 0
|
|
69
70
|
rescue RetryExhaustedError, FatalApiError => e
|
|
70
71
|
@error_collector&.report(e)
|
data/lib/hastci/session.rb
CHANGED
|
@@ -203,6 +203,7 @@ module HastCI
|
|
|
203
203
|
|
|
204
204
|
@heartbeat = Heartbeat.new(
|
|
205
205
|
api_client: @api_client,
|
|
206
|
+
run_id: @run_id,
|
|
206
207
|
interval: @config.heartbeat_interval,
|
|
207
208
|
error_collector: @error_collector
|
|
208
209
|
)
|
|
@@ -233,7 +234,7 @@ module HastCI
|
|
|
233
234
|
max_size: @buffer_max_size,
|
|
234
235
|
fetcher: lambda { |limit|
|
|
235
236
|
batch_size = [limit, @config.claim_batch_size].min
|
|
236
|
-
@api_client.claim(batch: batch_size)
|
|
237
|
+
@api_client.claim(run_id: @run_id, batch: batch_size)
|
|
237
238
|
},
|
|
238
239
|
error_collector: @error_collector,
|
|
239
240
|
poll_interval: @poll_interval,
|
data/lib/hastci/version.rb
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"providerState": "a valid API key",
|
|
12
12
|
"request": {
|
|
13
13
|
"method": "post",
|
|
14
|
-
"path": "/runs
|
|
14
|
+
"path": "/api/v1/runs",
|
|
15
15
|
"headers": {
|
|
16
16
|
"Authorization": "Bearer test-api-key",
|
|
17
17
|
"Content-Type": "application/json"
|
|
@@ -39,13 +39,14 @@
|
|
|
39
39
|
"Content-Type": "application/json"
|
|
40
40
|
},
|
|
41
41
|
"body": {
|
|
42
|
-
"run_id": "
|
|
42
|
+
"run_id": "018f1234-5678-7000-8000-123456789abc",
|
|
43
43
|
"status": "seeding",
|
|
44
44
|
"role": "seeder"
|
|
45
45
|
},
|
|
46
46
|
"matchingRules": {
|
|
47
47
|
"$.body.run_id": {
|
|
48
|
-
"match": "
|
|
48
|
+
"match": "regex",
|
|
49
|
+
"regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
49
50
|
},
|
|
50
51
|
"$.body.status": {
|
|
51
52
|
"match": "regex",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"providerState": "an invalid API key",
|
|
64
65
|
"request": {
|
|
65
66
|
"method": "post",
|
|
66
|
-
"path": "/runs
|
|
67
|
+
"path": "/api/v1/runs",
|
|
67
68
|
"headers": {
|
|
68
69
|
"Authorization": "Bearer invalid-api-key",
|
|
69
70
|
"Content-Type": "application/json"
|
|
@@ -91,7 +92,10 @@
|
|
|
91
92
|
"Content-Type": "application/json"
|
|
92
93
|
},
|
|
93
94
|
"body": {
|
|
94
|
-
"error":
|
|
95
|
+
"error": {
|
|
96
|
+
"code": "unauthorized",
|
|
97
|
+
"message": "Unauthorized"
|
|
98
|
+
}
|
|
95
99
|
},
|
|
96
100
|
"matchingRules": {
|
|
97
101
|
"$.body.error": {
|
|
@@ -105,9 +109,15 @@
|
|
|
105
109
|
"providerState": "a run exists",
|
|
106
110
|
"request": {
|
|
107
111
|
"method": "get",
|
|
108
|
-
"path": "/runs/
|
|
112
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc",
|
|
109
113
|
"headers": {
|
|
110
114
|
"Authorization": "Bearer test-api-key"
|
|
115
|
+
},
|
|
116
|
+
"matchingRules": {
|
|
117
|
+
"$.path": {
|
|
118
|
+
"match": "regex",
|
|
119
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
120
|
+
}
|
|
111
121
|
}
|
|
112
122
|
},
|
|
113
123
|
"response": {
|
|
@@ -131,7 +141,7 @@
|
|
|
131
141
|
"providerState": "a run exists",
|
|
132
142
|
"request": {
|
|
133
143
|
"method": "post",
|
|
134
|
-
"path": "/runs/
|
|
144
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/seed",
|
|
135
145
|
"headers": {
|
|
136
146
|
"Authorization": "Bearer test-api-key",
|
|
137
147
|
"Content-Type": "application/json"
|
|
@@ -145,6 +155,12 @@
|
|
|
145
155
|
"name": "spec/models/post_spec.rb"
|
|
146
156
|
}
|
|
147
157
|
]
|
|
158
|
+
},
|
|
159
|
+
"matchingRules": {
|
|
160
|
+
"$.path": {
|
|
161
|
+
"match": "regex",
|
|
162
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/seed$"
|
|
163
|
+
}
|
|
148
164
|
}
|
|
149
165
|
},
|
|
150
166
|
"response": {
|
|
@@ -163,15 +179,20 @@
|
|
|
163
179
|
"providerState": "tasks are available",
|
|
164
180
|
"request": {
|
|
165
181
|
"method": "post",
|
|
166
|
-
"path": "/
|
|
182
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
|
|
167
183
|
"query": "batch=10",
|
|
168
184
|
"headers": {
|
|
169
185
|
"Authorization": "Bearer test-api-key",
|
|
170
186
|
"Content-Type": "application/json"
|
|
171
187
|
},
|
|
172
188
|
"body": {
|
|
173
|
-
"run_key": "test-run-key",
|
|
174
189
|
"worker_id": "worker-0"
|
|
190
|
+
},
|
|
191
|
+
"matchingRules": {
|
|
192
|
+
"$.path": {
|
|
193
|
+
"match": "regex",
|
|
194
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
|
|
195
|
+
}
|
|
175
196
|
}
|
|
176
197
|
},
|
|
177
198
|
"response": {
|
|
@@ -182,27 +203,45 @@
|
|
|
182
203
|
"body": {
|
|
183
204
|
"tasks": [
|
|
184
205
|
{
|
|
185
|
-
"id": "
|
|
206
|
+
"id": "018f1234-5678-7000-8000-123456789def",
|
|
186
207
|
"name": "spec/models/user_spec.rb"
|
|
187
208
|
},
|
|
188
209
|
{
|
|
189
|
-
"id": "
|
|
210
|
+
"id": "018f1234-5678-7000-8000-123456789012",
|
|
190
211
|
"name": "spec/models/post_spec.rb"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": "018f1234-5678-7000-8000-123456789013",
|
|
215
|
+
"name": "spec/models/comment_spec.rb"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"id": "018f1234-5678-7000-8000-123456789014",
|
|
219
|
+
"name": "spec/models/profile_spec.rb"
|
|
191
220
|
}
|
|
192
221
|
],
|
|
193
|
-
"queue_state": "
|
|
222
|
+
"queue_state": "draining",
|
|
194
223
|
"remaining": {
|
|
195
|
-
"queued":
|
|
196
|
-
"assigned":
|
|
197
|
-
"completed":
|
|
224
|
+
"queued": 0,
|
|
225
|
+
"assigned": 4,
|
|
226
|
+
"completed": 0
|
|
198
227
|
}
|
|
199
228
|
},
|
|
200
229
|
"matchingRules": {
|
|
201
230
|
"$.body.tasks[0].id": {
|
|
202
|
-
"match": "
|
|
231
|
+
"match": "regex",
|
|
232
|
+
"regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
203
233
|
},
|
|
204
234
|
"$.body.tasks[1].id": {
|
|
205
|
-
"match": "
|
|
235
|
+
"match": "regex",
|
|
236
|
+
"regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
237
|
+
},
|
|
238
|
+
"$.body.tasks[2].id": {
|
|
239
|
+
"match": "regex",
|
|
240
|
+
"regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
241
|
+
},
|
|
242
|
+
"$.body.tasks[3].id": {
|
|
243
|
+
"match": "regex",
|
|
244
|
+
"regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
206
245
|
},
|
|
207
246
|
"$.body.remaining.queued": {
|
|
208
247
|
"match": "type"
|
|
@@ -221,15 +260,20 @@
|
|
|
221
260
|
"providerState": "queue is empty but not drained",
|
|
222
261
|
"request": {
|
|
223
262
|
"method": "post",
|
|
224
|
-
"path": "/
|
|
263
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
|
|
225
264
|
"query": "batch=10",
|
|
226
265
|
"headers": {
|
|
227
266
|
"Authorization": "Bearer test-api-key",
|
|
228
267
|
"Content-Type": "application/json"
|
|
229
268
|
},
|
|
230
269
|
"body": {
|
|
231
|
-
"run_key": "test-run-key",
|
|
232
270
|
"worker_id": "worker-0"
|
|
271
|
+
},
|
|
272
|
+
"matchingRules": {
|
|
273
|
+
"$.path": {
|
|
274
|
+
"match": "regex",
|
|
275
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
|
|
276
|
+
}
|
|
233
277
|
}
|
|
234
278
|
},
|
|
235
279
|
"response": {
|
|
@@ -244,14 +288,20 @@
|
|
|
244
288
|
"providerState": "queue is drained",
|
|
245
289
|
"request": {
|
|
246
290
|
"method": "post",
|
|
247
|
-
"path": "/
|
|
291
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
|
|
248
292
|
"query": "batch=10",
|
|
249
293
|
"headers": {
|
|
250
|
-
"Authorization": "Bearer test-api-key"
|
|
294
|
+
"Authorization": "Bearer test-api-key",
|
|
295
|
+
"Content-Type": "application/json"
|
|
251
296
|
},
|
|
252
297
|
"body": {
|
|
253
|
-
"run_key": "test-run-key",
|
|
254
298
|
"worker_id": "worker-0"
|
|
299
|
+
},
|
|
300
|
+
"matchingRules": {
|
|
301
|
+
"$.path": {
|
|
302
|
+
"match": "regex",
|
|
303
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
|
|
304
|
+
}
|
|
255
305
|
}
|
|
256
306
|
},
|
|
257
307
|
"response": {
|
|
@@ -264,12 +314,62 @@
|
|
|
264
314
|
}
|
|
265
315
|
}
|
|
266
316
|
},
|
|
317
|
+
{
|
|
318
|
+
"description": "a request to claim from cancelled run",
|
|
319
|
+
"providerState": "run is cancelled",
|
|
320
|
+
"request": {
|
|
321
|
+
"method": "post",
|
|
322
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
|
|
323
|
+
"query": "batch=10",
|
|
324
|
+
"headers": {
|
|
325
|
+
"Authorization": "Bearer test-api-key",
|
|
326
|
+
"Content-Type": "application/json"
|
|
327
|
+
},
|
|
328
|
+
"body": {
|
|
329
|
+
"worker_id": "worker-0"
|
|
330
|
+
},
|
|
331
|
+
"matchingRules": {
|
|
332
|
+
"$.path": {
|
|
333
|
+
"match": "regex",
|
|
334
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
"response": {
|
|
339
|
+
"status": 200,
|
|
340
|
+
"headers": {
|
|
341
|
+
"Content-Type": "application/json"
|
|
342
|
+
},
|
|
343
|
+
"body": {
|
|
344
|
+
"tasks": [
|
|
345
|
+
],
|
|
346
|
+
"queue_state": "cancelled",
|
|
347
|
+
"remaining": {
|
|
348
|
+
"queued": 0,
|
|
349
|
+
"assigned": 0,
|
|
350
|
+
"completed": 5
|
|
351
|
+
},
|
|
352
|
+
"should_stop": true
|
|
353
|
+
},
|
|
354
|
+
"matchingRules": {
|
|
355
|
+
"$.body.remaining.queued": {
|
|
356
|
+
"match": "type"
|
|
357
|
+
},
|
|
358
|
+
"$.body.remaining.assigned": {
|
|
359
|
+
"match": "type"
|
|
360
|
+
},
|
|
361
|
+
"$.body.remaining.completed": {
|
|
362
|
+
"match": "type"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
},
|
|
267
367
|
{
|
|
268
368
|
"description": "a request to ack a task",
|
|
269
369
|
"providerState": "a task exists",
|
|
270
370
|
"request": {
|
|
271
371
|
"method": "post",
|
|
272
|
-
"path": "/tasks/
|
|
372
|
+
"path": "/api/v1/tasks/018f1234-5678-7000-8000-123456789def/acknowledgment",
|
|
273
373
|
"headers": {
|
|
274
374
|
"Authorization": "Bearer test-api-key",
|
|
275
375
|
"Content-Type": "application/json"
|
|
@@ -282,6 +382,12 @@
|
|
|
282
382
|
"failures": [
|
|
283
383
|
]
|
|
284
384
|
}
|
|
385
|
+
},
|
|
386
|
+
"matchingRules": {
|
|
387
|
+
"$.path": {
|
|
388
|
+
"match": "regex",
|
|
389
|
+
"regex": "^\\/api\\/v1\\/tasks\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/acknowledgment$"
|
|
390
|
+
}
|
|
285
391
|
}
|
|
286
392
|
},
|
|
287
393
|
"response": {
|
|
@@ -299,14 +405,19 @@
|
|
|
299
405
|
"providerState": "a worker exists",
|
|
300
406
|
"request": {
|
|
301
407
|
"method": "post",
|
|
302
|
-
"path": "/
|
|
408
|
+
"path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/heartbeats",
|
|
303
409
|
"headers": {
|
|
304
410
|
"Authorization": "Bearer test-api-key",
|
|
305
411
|
"Content-Type": "application/json"
|
|
306
412
|
},
|
|
307
413
|
"body": {
|
|
308
|
-
"run_key": "test-run-key",
|
|
309
414
|
"worker_id": "worker-0"
|
|
415
|
+
},
|
|
416
|
+
"matchingRules": {
|
|
417
|
+
"$.path": {
|
|
418
|
+
"match": "regex",
|
|
419
|
+
"regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/heartbeats$"
|
|
420
|
+
}
|
|
310
421
|
}
|
|
311
422
|
},
|
|
312
423
|
"response": {
|
|
@@ -321,7 +432,7 @@
|
|
|
321
432
|
"providerState": "resource not found",
|
|
322
433
|
"request": {
|
|
323
434
|
"method": "get",
|
|
324
|
-
"path": "/runs/invalid-run
|
|
435
|
+
"path": "/api/v1/runs/invalid-run",
|
|
325
436
|
"headers": {
|
|
326
437
|
"Authorization": "Bearer test-api-key"
|
|
327
438
|
}
|
|
@@ -337,7 +448,7 @@
|
|
|
337
448
|
"providerState": "server error",
|
|
338
449
|
"request": {
|
|
339
450
|
"method": "post",
|
|
340
|
-
"path": "/runs
|
|
451
|
+
"path": "/api/v1/runs",
|
|
341
452
|
"headers": {
|
|
342
453
|
"Authorization": "Bearer test-api-key",
|
|
343
454
|
"Content-Type": "application/json"
|
|
@@ -359,7 +470,7 @@
|
|
|
359
470
|
"providerState": "unexpected redirect",
|
|
360
471
|
"request": {
|
|
361
472
|
"method": "post",
|
|
362
|
-
"path": "/runs
|
|
473
|
+
"path": "/api/v1/runs",
|
|
363
474
|
"headers": {
|
|
364
475
|
"Authorization": "Bearer test-api-key",
|
|
365
476
|
"Content-Type": "application/json"
|