zeebe_bpmn_rspec 0.1.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 +7 -0
- data/.codeclimate.yml +53 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +21 -0
- data/README.md +245 -0
- data/docker-compose.yml +46 -0
- data/lib/zeebe_bpmn_rspec.rb +35 -0
- data/lib/zeebe_bpmn_rspec/activated_job.rb +91 -0
- data/lib/zeebe_bpmn_rspec/helpers.rb +134 -0
- data/lib/zeebe_bpmn_rspec/version.rb +5 -0
- data/zeebe_bpmn_rspec.gemspec +54 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 21f042c1e3d81e8f0bc9096924685cdd8c436de1a5a68e1cef9857e3f4e87a58
|
4
|
+
data.tar.gz: fe32bf072bc3677667e1ed6ac49c92e2cd48647ad5adfabd546a7a94ea253eef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 34a5334740649b53d9199e74009fb6e233ac34667b33c8e012f9c30fa168f470626c5d199a83f83032deae764a3408a33b6df3ce620ee427895d0d9bcc60f7c7
|
7
|
+
data.tar.gz: 1688746402718b8d1d38868f8271782af51be446bc3ba4d62b953ca9c049afa1933d4614ce9203294aa46286efaa74a54fd88b377c8df32f09e9c932acea8179
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
version: "2"
|
2
|
+
checks:
|
3
|
+
file-lines:
|
4
|
+
enabled: false
|
5
|
+
method-lines:
|
6
|
+
enabled: false
|
7
|
+
plugins:
|
8
|
+
csslint:
|
9
|
+
enabled: true
|
10
|
+
duplication:
|
11
|
+
enabled: true
|
12
|
+
config:
|
13
|
+
languages:
|
14
|
+
- ruby
|
15
|
+
- javascript
|
16
|
+
fixme:
|
17
|
+
enabled: true
|
18
|
+
exclude_patterns:
|
19
|
+
- config/
|
20
|
+
- db/
|
21
|
+
- script/
|
22
|
+
- spec/
|
23
|
+
- vendor/
|
24
|
+
- "**.jpg"
|
25
|
+
- "**.png"
|
26
|
+
- "**.gif"
|
27
|
+
- "**.svg"
|
28
|
+
- "**.scss"
|
29
|
+
- "**.md"
|
30
|
+
- ".rubocop.yml"
|
31
|
+
- "Dockerfile"
|
32
|
+
- "Capfile"
|
33
|
+
- "README.md"
|
34
|
+
- "**.erb"
|
35
|
+
- "**.jbuilder"
|
36
|
+
- "**.rabl"
|
37
|
+
- "**.zip"
|
38
|
+
- "**.crt"
|
39
|
+
- "**.txt"
|
40
|
+
- "**.ico"
|
41
|
+
- "**.eot"
|
42
|
+
- "**.pdf"
|
43
|
+
- "**.html"
|
44
|
+
- "**.key"
|
45
|
+
- "**.docx"
|
46
|
+
- "**.fcgi"
|
47
|
+
- "**.xml"
|
48
|
+
- "**.pem"
|
49
|
+
- "**.csr"
|
50
|
+
- "**.org"
|
51
|
+
- "**.cgi"
|
52
|
+
- "**.ru"
|
53
|
+
- "**.pptx"
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
# override the :github shortcut to be secure by using HTTPS
|
6
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
7
|
+
|
8
|
+
# Specify your gem's dependencies in zeebe_bpmn_rspec.gemspec
|
9
|
+
gemspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 ezCater, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
# zeebe_bpmn_rspec
|
2
|
+
|
3
|
+
This gem provides support for testing BPMN files using RSpec with the Zeebe workflow engine.
|
4
|
+
|
5
|
+
The gem adds RSpec helpers that are used to interact with Zeebe and a running workflow instance.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to the test group in your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
group :test do
|
13
|
+
gem "zeebe_bpmn_rspec"
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle install
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install zeebe_bpmn_rspec
|
24
|
+
|
25
|
+
## Configuration
|
26
|
+
|
27
|
+
Either the address for the Zeebe workflow engine or a Zeebe client must be configured.
|
28
|
+
`ZEEBE_ADDRESS` if used from the environment if this is not configured.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
ZeebeBpmnRspec.configure do |config|
|
32
|
+
config.zeebe_address = "localhost:26500"
|
33
|
+
# -OR-
|
34
|
+
config.client = #<Zeebe::Client::GatewayProtocol::Gateway::Stub instance>
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
The gem adds the following helper methods to RSpec.
|
41
|
+
|
42
|
+
### Deploy Workflow
|
43
|
+
|
44
|
+
The `deploy_workflow` method requires a path to a BPMN file and deploys it to Zeebe. There is no support for
|
45
|
+
removing a BPMN file once deployed, so this can be done once before the examples that use it.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
before(:all) { deploy_workflow(filepath) }
|
49
|
+
```
|
50
|
+
|
51
|
+
A custom name can also be specified for the workflow:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
before(:all) { deploy_workflow(filepath, "custom_name") }
|
55
|
+
```
|
56
|
+
|
57
|
+
### With Workflow Instance
|
58
|
+
|
59
|
+
The `with_workflow_instance` method is used to create an instance for the specified workflow
|
60
|
+
and then yields a block that can interact with the instance.
|
61
|
+
|
62
|
+
This method ensures that an active instance is cancelled at the end of the block.
|
63
|
+
|
64
|
+
For testing BPMN files it is expected that most of the test definition will be wrapped in a
|
65
|
+
call to this method.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
with_workflow_instance("file_basename") do
|
69
|
+
...
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
### Processing Jobs
|
74
|
+
|
75
|
+
A single job can be processed for a workflow by calling `activate_job` (previously `process_job`).
|
76
|
+
`activate_job` is called with a job type:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
activate_job("my_job")
|
80
|
+
```
|
81
|
+
|
82
|
+
The call to `activate_job` returns a `ActivatedJob` object that provides a fluent interface to chain
|
83
|
+
additional expectations and responses onto the job.
|
84
|
+
|
85
|
+
#### Expect Input
|
86
|
+
|
87
|
+
To check the input variables that are passed to the job add `.expect_input`:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
activate_job("my_job").
|
91
|
+
expect_input(user_id: 123)
|
92
|
+
```
|
93
|
+
|
94
|
+
Expect input uses RSpec expectations so it supports other RSpec helpers. For example, to perform
|
95
|
+
a partial match on the input:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
activate_job("my_job").
|
99
|
+
expect_input(hash_including("user_id" => 123))
|
100
|
+
```
|
101
|
+
|
102
|
+
Note: that when using methods like `hash_including` string keys must be used to match the parsed JSON
|
103
|
+
coming from Zeebe.
|
104
|
+
|
105
|
+
#### Expect Headers
|
106
|
+
|
107
|
+
Similar to `expect_input`, expectations can be set on headers for the job using `.expect_headers`:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
activate_job("my_job").
|
111
|
+
expect_headers(content_type: "CREATE")
|
112
|
+
|
113
|
+
# Combined with expect_input
|
114
|
+
activate_job("my_job").
|
115
|
+
expect_input(user_id: 123).
|
116
|
+
expect_headers(content_type: "CREATE")
|
117
|
+
```
|
118
|
+
|
119
|
+
#### Complete Job
|
120
|
+
|
121
|
+
Jobs can be completed by calling `and_complete`. Variables can optionally be returned with the
|
122
|
+
completed job.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
# Completing a job can be changed with expectations
|
126
|
+
activate_job("my_job").
|
127
|
+
expect_input(user_id: 123).
|
128
|
+
and_complete
|
129
|
+
|
130
|
+
# Jobs can be completed with data that is merged with variables in the workflow
|
131
|
+
project_job("my_job").
|
132
|
+
and_complete(status: "ACTIVATED")
|
133
|
+
```
|
134
|
+
|
135
|
+
#### Fail Job
|
136
|
+
|
137
|
+
Jobs can be failed by calling `and_fail`. An optional message can be specified when failing a job.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
# Failing a job can be chanined with expectations
|
141
|
+
activate_job("my_job").
|
142
|
+
expect_headers(id_type: "user").
|
143
|
+
and_fail
|
144
|
+
|
145
|
+
# Jobs can be failed with a message
|
146
|
+
activate_job("my_job").
|
147
|
+
and_fail("something didn't go right")
|
148
|
+
```
|
149
|
+
|
150
|
+
#### Throw Error
|
151
|
+
|
152
|
+
The `and_throw_error` method can be used to throw an error for a job. The error code is required and an
|
153
|
+
optional message may be specified:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
activate_job("my_job").
|
157
|
+
expect_input(foo: "bar").
|
158
|
+
and_throw_error("NOT_FOUND")
|
159
|
+
|
160
|
+
# with message
|
161
|
+
activate_job("my_job").
|
162
|
+
expect_input(foo: "bar").
|
163
|
+
and_throw_error("NOT_FOUND", "couldn't find a bar")
|
164
|
+
```
|
165
|
+
|
166
|
+
#### Activating Multiple Jobs
|
167
|
+
|
168
|
+
TODO
|
169
|
+
|
170
|
+
### Workflow Complete
|
171
|
+
|
172
|
+
The `workflow_complete!` method can be used to assert that the current workflow is complete at the end of a
|
173
|
+
test. This is implemented by cancelling the workflow and checking for an error that it is already
|
174
|
+
complete.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
with_workflow_instance("file_basename") do
|
178
|
+
...
|
179
|
+
|
180
|
+
workflow_complete!
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
### Publish Message
|
185
|
+
|
186
|
+
The `publish_message` method is used to send a message to Zeebe.
|
187
|
+
|
188
|
+
The message name and correlation key are required:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
publish_message("message_name", correlation_key: expected_value)
|
192
|
+
```
|
193
|
+
|
194
|
+
Variables can also be sent with a message:
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
publish_message("message_name", correlation_key: expected_value,
|
198
|
+
variables: { foo: "bar" })
|
199
|
+
```
|
200
|
+
|
201
|
+
## Limitations
|
202
|
+
|
203
|
+
The current gem and approach have some limitations:
|
204
|
+
|
205
|
+
1. You can interact with only one workflow at a time.
|
206
|
+
|
207
|
+
## Development
|
208
|
+
|
209
|
+
This repo contains a docker-compose file that starts Zeebe and can be used for
|
210
|
+
local development. Docker and Docker Compose most be installed as prerequisites.
|
211
|
+
|
212
|
+
Run the following to start a bash session. Gems will automatically be bundled and
|
213
|
+
the environment will have access to a running Zeebe broker:
|
214
|
+
|
215
|
+
```bash
|
216
|
+
docker-compose run --rm console bash
|
217
|
+
```
|
218
|
+
|
219
|
+
To run specs using docker-compose run the following command:
|
220
|
+
|
221
|
+
```bash
|
222
|
+
docker-compose run --rm console rspec
|
223
|
+
```
|
224
|
+
|
225
|
+
### Install Locally
|
226
|
+
|
227
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
228
|
+
|
229
|
+
### Create a Release
|
230
|
+
|
231
|
+
To release a new version, update the version number in `version.rb`, and then
|
232
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
233
|
+
push git commits and tags, and push the `.gem` file to
|
234
|
+
[rubygems.org](https://rubygems.org).
|
235
|
+
|
236
|
+
## Contributing
|
237
|
+
|
238
|
+
Bug reports and pull requests are welcome on GitHub at
|
239
|
+
https://github.com/ezcater/zeebe_bpmn_rspec.
|
240
|
+
|
241
|
+
## License
|
242
|
+
|
243
|
+
The gem is available as open source under the terms of the
|
244
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
245
|
+
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
version: "3.4"
|
2
|
+
volumes:
|
3
|
+
bundle-volume:
|
4
|
+
shared-volume:
|
5
|
+
x-environment: &default-environment
|
6
|
+
PRYRC: /usr/src/app/.docker-pryrc
|
7
|
+
BUNDLE_IGNORE_CONFIG: 1
|
8
|
+
BUNDLE_DISABLE_SHARED_GEMS: "true"
|
9
|
+
ZEEBE_ADDRESS: zeebe-bpmn-gateway:26500
|
10
|
+
x-service: &default-service
|
11
|
+
image: ruby:2.6.6
|
12
|
+
volumes:
|
13
|
+
- .:/usr/src/gem
|
14
|
+
- ./compose/entrypoint.sh:/tmp/entrypoint.sh
|
15
|
+
- bundle-volume:/usr/local/bundle:delegated
|
16
|
+
- shared-volume:/usr/src/shared:delegated
|
17
|
+
tty: true
|
18
|
+
stdin_open: true
|
19
|
+
services:
|
20
|
+
zeebe:
|
21
|
+
image: camunda/zeebe:0.23.2
|
22
|
+
environment:
|
23
|
+
ZEEBE_LOG_LEVEL: debug
|
24
|
+
volumes:
|
25
|
+
- ./compose/zeebe-hazelcast-exporter.jar:/usr/local/zeebe/exporters/zeebe-hazelcast-exporter.jar
|
26
|
+
- ./compose/application.yml:/usr/local/zeebe/config/application.yaml
|
27
|
+
|
28
|
+
monitor:
|
29
|
+
image: camunda/zeebe-simple-monitor:0.19.0
|
30
|
+
environment:
|
31
|
+
- zeebe.client.broker.contactPoint=zeebe-bpmn-gateway:26500
|
32
|
+
- zeebe.client.worker.hazelcast.connection=zeebe-bpmn-gateway:5701
|
33
|
+
ports:
|
34
|
+
- "8082:8082"
|
35
|
+
depends_on:
|
36
|
+
- zeebe
|
37
|
+
|
38
|
+
console:
|
39
|
+
<<: *default-service
|
40
|
+
environment:
|
41
|
+
<<: *default-environment
|
42
|
+
entrypoint: /tmp/entrypoint.sh
|
43
|
+
command: bash
|
44
|
+
working_dir: /usr/src/gem
|
45
|
+
depends_on:
|
46
|
+
- zeebe
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rspec"
|
4
|
+
require "zeebe/client"
|
5
|
+
require "zeebe_bpmn_rspec/helpers"
|
6
|
+
require "zeebe_bpmn_rspec/version"
|
7
|
+
|
8
|
+
# Top-level gem module
|
9
|
+
module ZeebeBpmnRspec
|
10
|
+
class << self
|
11
|
+
attr_writer :client, :zeebe_address
|
12
|
+
|
13
|
+
def configure
|
14
|
+
yield(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
18
|
+
def client
|
19
|
+
@client ||= Zeebe::Client::GatewayProtocol::Gateway::Stub.new(zeebe_address, :this_channel_is_insecure)
|
20
|
+
end
|
21
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
22
|
+
|
23
|
+
def zeebe_address
|
24
|
+
@zeebe_address || ENV["ZEEBE_ADDRESS"] || (raise "zeebe_address must be set")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.include ZeebeBpmnRspec::Helpers
|
31
|
+
|
32
|
+
config.after(:each) do
|
33
|
+
reset_zeebe!
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support"
|
4
|
+
require "active_support/core_ext/hash/keys"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module ZeebeBpmnRspec
|
8
|
+
class ActivatedJob
|
9
|
+
include ::Zeebe::Client::GatewayProtocol # for direct reference of request classes
|
10
|
+
|
11
|
+
attr_reader :job, :type, :workflow_instance_key
|
12
|
+
|
13
|
+
def initialize(job, type:, workflow_instance_key:, client:, context:)
|
14
|
+
@job = job
|
15
|
+
@type = type
|
16
|
+
@workflow_instance_key = workflow_instance_key
|
17
|
+
@client = client
|
18
|
+
@context = context
|
19
|
+
|
20
|
+
context.instance_eval do
|
21
|
+
aggregate_failures do
|
22
|
+
expect(job.workflowInstanceKey).to eq(workflow_instance_key)
|
23
|
+
expect(job.type).to eq(type)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def key
|
29
|
+
job.key
|
30
|
+
end
|
31
|
+
|
32
|
+
def variables
|
33
|
+
@_variables ||= JSON.parse(job.variables)
|
34
|
+
end
|
35
|
+
|
36
|
+
def headers
|
37
|
+
@_headers ||= JSON.parse(job.customHeaders)
|
38
|
+
end
|
39
|
+
|
40
|
+
def expect_input(data)
|
41
|
+
job_variables = variables
|
42
|
+
data = data.stringify_keys if data.is_a?(Hash)
|
43
|
+
context.instance_eval do
|
44
|
+
expect(job_variables).to match(data)
|
45
|
+
end
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def expect_headers(headers)
|
51
|
+
job_headers = self.headers
|
52
|
+
headers = headers.stringify_keys if headers.is_a?(Hash)
|
53
|
+
context.instance_eval do
|
54
|
+
expect(job_headers).to match(headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def and_throw_error(error_code, message = nil)
|
61
|
+
client.throw_error(ThrowErrorRequest.new(
|
62
|
+
{
|
63
|
+
jobKey: job.key,
|
64
|
+
errorCode: error_code,
|
65
|
+
errorMessage: message,
|
66
|
+
}.compact
|
67
|
+
))
|
68
|
+
end
|
69
|
+
|
70
|
+
def and_fail(message = nil)
|
71
|
+
client.fail_job(FailJobRequest.new(
|
72
|
+
{
|
73
|
+
jobKey: job.key,
|
74
|
+
retries: 0,
|
75
|
+
errorMessage: message,
|
76
|
+
}.compact
|
77
|
+
))
|
78
|
+
end
|
79
|
+
|
80
|
+
def and_complete(variables = {})
|
81
|
+
client.complete_job(CompleteJobRequest.new(
|
82
|
+
jobKey: job.key,
|
83
|
+
variables: variables.to_json
|
84
|
+
))
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
attr_reader :client, :context
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zeebe_bpmn_rspec/activated_job"
|
4
|
+
|
5
|
+
module ZeebeBpmnRspec
|
6
|
+
module Helpers # rubocop:disable Metrics/ModuleLength
|
7
|
+
include ::Zeebe::Client::GatewayProtocol # for direct reference of request classes
|
8
|
+
|
9
|
+
def deploy_workflow(path, name = nil)
|
10
|
+
_zeebe_client.deploy_workflow(DeployWorkflowRequest.new(
|
11
|
+
workflows: [WorkflowRequestObject.new(
|
12
|
+
name: (name && "#{name}.bpmn") || File.basename(path),
|
13
|
+
type: WorkflowRequestObject::ResourceType::FILE,
|
14
|
+
definition: File.read(path)
|
15
|
+
)]
|
16
|
+
))
|
17
|
+
rescue StandardError => e
|
18
|
+
raise "Failed to deploy workflow: #{e}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_workflow_instance(name, variables = {})
|
22
|
+
system_error = nil
|
23
|
+
workflow = _zeebe_client.create_workflow_instance(CreateWorkflowInstanceRequest.new(
|
24
|
+
bpmnProcessId: name,
|
25
|
+
version: -1, # always latest
|
26
|
+
variables: variables.to_json
|
27
|
+
))
|
28
|
+
@__workflow_instance_key = workflow.workflowInstanceKey
|
29
|
+
yield(workflow.workflowInstanceKey)
|
30
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
31
|
+
# exceptions are rescued to ensure that instances are cancelled
|
32
|
+
# any error is re-raised below
|
33
|
+
system_error = e
|
34
|
+
ensure
|
35
|
+
if workflow&.workflowInstanceKey
|
36
|
+
begin
|
37
|
+
_zeebe_client.cancel_workflow_instance(CancelWorkflowInstanceRequest.new(
|
38
|
+
workflowInstanceKey: workflow.workflowInstanceKey
|
39
|
+
))
|
40
|
+
rescue GRPC::NotFound => _e
|
41
|
+
# expected
|
42
|
+
rescue StandardError => _e
|
43
|
+
puts "Cancelled instance #{ex.inspect}" # TODO
|
44
|
+
end
|
45
|
+
end
|
46
|
+
raise system_error if system_error
|
47
|
+
end
|
48
|
+
|
49
|
+
def workflow_complete!
|
50
|
+
error = nil
|
51
|
+
sleep 0.25 # TODO: configurable?
|
52
|
+
begin
|
53
|
+
_zeebe_client.cancel_workflow_instance(CancelWorkflowInstanceRequest.new(
|
54
|
+
workflowInstanceKey: workflow_instance_key
|
55
|
+
))
|
56
|
+
rescue GRPC::NotFound => e
|
57
|
+
error = e
|
58
|
+
end
|
59
|
+
|
60
|
+
raise "Expected workflow instance #{workflow_instance_key} to be complete" if error.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
def workflow_instance_key
|
64
|
+
@__workflow_instance_key
|
65
|
+
end
|
66
|
+
|
67
|
+
def activate_job(type)
|
68
|
+
stream = _zeebe_client.activate_jobs(ActivateJobsRequest.new(
|
69
|
+
type: type,
|
70
|
+
worker: "#{type}-#{SecureRandom.hex}",
|
71
|
+
maxJobsToActivate: 1,
|
72
|
+
timeout: 5000, # TODO: configure
|
73
|
+
requestTimeout: 5000
|
74
|
+
))
|
75
|
+
|
76
|
+
job = nil
|
77
|
+
stream.find { |response| job = response.jobs.first }
|
78
|
+
raise "No job with type #{type.inspect} found" if job.nil?
|
79
|
+
|
80
|
+
# puts job.inspect # support debug logging?
|
81
|
+
|
82
|
+
ActivatedJob.new(job,
|
83
|
+
type: type,
|
84
|
+
workflow_instance_key: workflow_instance_key,
|
85
|
+
client: _zeebe_client,
|
86
|
+
context: self)
|
87
|
+
end
|
88
|
+
alias process_job activate_job
|
89
|
+
# TODO: deprecate process_job
|
90
|
+
|
91
|
+
def activate_jobs(type, max_jobs: nil)
|
92
|
+
stream = _zeebe_client.activate_jobs(ActivateJobsRequest.new({
|
93
|
+
type: type,
|
94
|
+
worker: "#{type}-#{SecureRandom.hex}",
|
95
|
+
maxJobsToActivate: max_jobs,
|
96
|
+
timeout: 5000, # TODO: configure
|
97
|
+
requestTimeout: 5000,
|
98
|
+
}.compact))
|
99
|
+
|
100
|
+
Enumerator.new do |yielder|
|
101
|
+
stream.each do |response|
|
102
|
+
response.jobs.each do |job|
|
103
|
+
yielder << ActivatedJob.new(job,
|
104
|
+
type: type,
|
105
|
+
workflow_instance_key: workflow_instance_key,
|
106
|
+
client: _zeebe_client,
|
107
|
+
context: self)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def publish_message(name, correlation_key:, variables: nil)
|
114
|
+
_zeebe_client.publish_message(PublishMessageRequest.new(
|
115
|
+
{
|
116
|
+
name: name,
|
117
|
+
correlationKey: correlation_key,
|
118
|
+
timeToLive: 5000,
|
119
|
+
variables: variables&.to_json,
|
120
|
+
}.compact
|
121
|
+
))
|
122
|
+
end
|
123
|
+
|
124
|
+
def reset_zeebe!
|
125
|
+
@__workflow_instance_key = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def _zeebe_client
|
131
|
+
ZeebeBpmnRspec.client
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "zeebe_bpmn_rspec/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "zeebe_bpmn_rspec"
|
9
|
+
spec.version = ZeebeBpmnRspec::VERSION
|
10
|
+
spec.authors = ["ezCater, Inc"]
|
11
|
+
spec.email = ["engineering@ezcater.com"]
|
12
|
+
spec.summary = "Zeebe BPMN testing using RSpec"
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = "https://github.com/ezcater/zeebe_bpmn_rspec"
|
15
|
+
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
# Set "allowed_push_post" to control where this gem can be published.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
excluded_files = %w(.circleci/config.yml
|
26
|
+
.github/PULL_REQUEST_TEMPLATE.md
|
27
|
+
.gitignore
|
28
|
+
.rspec
|
29
|
+
.rubocop.yml
|
30
|
+
.ruby-gemset
|
31
|
+
.ruby-version
|
32
|
+
.travis.yml
|
33
|
+
bin/console
|
34
|
+
bin/setup
|
35
|
+
Rakefile)
|
36
|
+
|
37
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
38
|
+
f.match(/^(test|spec|features|compose)\//)
|
39
|
+
end - excluded_files
|
40
|
+
spec.bindir = "bin"
|
41
|
+
spec.executables = []
|
42
|
+
spec.require_paths = ["lib"]
|
43
|
+
|
44
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
45
|
+
spec.add_development_dependency "ezcater_rubocop", "2.0.0"
|
46
|
+
spec.add_development_dependency "overcommit"
|
47
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
48
|
+
spec.add_development_dependency "rspec_junit_formatter", "0.2.2"
|
49
|
+
spec.add_development_dependency "simplecov", "< 0.18"
|
50
|
+
|
51
|
+
spec.add_runtime_dependency "activesupport"
|
52
|
+
spec.add_runtime_dependency "rspec", "~> 3.4"
|
53
|
+
spec.add_runtime_dependency "zeebe-client"
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zeebe_bpmn_rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ezCater, Inc
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ezcater_rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: overcommit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec_junit_formatter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.2.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.2.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "<"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.18'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "<"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.18'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.4'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: zeebe-client
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Zeebe BPMN testing using RSpec
|
140
|
+
email:
|
141
|
+
- engineering@ezcater.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".codeclimate.yml"
|
147
|
+
- CHANGELOG.md
|
148
|
+
- Gemfile
|
149
|
+
- LICENSE.txt
|
150
|
+
- README.md
|
151
|
+
- docker-compose.yml
|
152
|
+
- lib/zeebe_bpmn_rspec.rb
|
153
|
+
- lib/zeebe_bpmn_rspec/activated_job.rb
|
154
|
+
- lib/zeebe_bpmn_rspec/helpers.rb
|
155
|
+
- lib/zeebe_bpmn_rspec/version.rb
|
156
|
+
- zeebe_bpmn_rspec.gemspec
|
157
|
+
homepage: https://github.com/ezcater/zeebe_bpmn_rspec
|
158
|
+
licenses:
|
159
|
+
- MIT
|
160
|
+
metadata:
|
161
|
+
allowed_push_host: https://rubygems.org
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
requirements: []
|
177
|
+
rubygems_version: 3.1.4
|
178
|
+
signing_key:
|
179
|
+
specification_version: 4
|
180
|
+
summary: Zeebe BPMN testing using RSpec
|
181
|
+
test_files: []
|