nestene 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +31 -0
  7. data/Rakefile +2 -0
  8. data/TODO.txt +7 -0
  9. data/api.rb +8 -0
  10. data/autons.rb +13 -0
  11. data/bin/nestene.rb +5 -0
  12. data/config.ru +21 -0
  13. data/features/api/api_create_auton.feature +6 -0
  14. data/features/api/api_credentials.feature +11 -0
  15. data/features/api/api_list_of_autons.feature +6 -0
  16. data/features/callback.feature +13 -0
  17. data/features/create_auton.feature +11 -0
  18. data/features/credentials.feature +7 -0
  19. data/features/execute_step.feature +59 -0
  20. data/features/restart.feature +7 -0
  21. data/features/schedule_steps.feature +7 -0
  22. data/features/step_definitions/api/api_create_auton_steps.rb +16 -0
  23. data/features/step_definitions/api/api_credentials_steps.rb +22 -0
  24. data/features/step_definitions/api/api_list_of_autons_steps.rb +8 -0
  25. data/features/step_definitions/callback_steps.rb +75 -0
  26. data/features/step_definitions/create_auton_steps.rb +32 -0
  27. data/features/step_definitions/credentials_steps.rb +24 -0
  28. data/features/step_definitions/execute_step_steps.rb +177 -0
  29. data/features/step_definitions/restart_steps.rb +5 -0
  30. data/features/step_definitions/schedule_steps_steps.rb +29 -0
  31. data/features/step_definitions/time_delayed_steps_steps.rb +103 -0
  32. data/features/step_definitions/ui/create_auton_steps.rb +21 -0
  33. data/features/step_definitions/ui/list_of_autons_steps.rb +18 -0
  34. data/features/step_definitions/ui/schedule_auton_step_steps.rb +64 -0
  35. data/features/step_definitions/ui/show_auton_steps.rb +49 -0
  36. data/features/support/env.rb +36 -0
  37. data/features/time_delayed_steps.feature +28 -0
  38. data/features/ui/create_auton.feature +7 -0
  39. data/features/ui/list_of_autons.feature +7 -0
  40. data/features/ui/schedule_auton_step.feature +12 -0
  41. data/features/ui/show_auton.feature +14 -0
  42. data/lib/nestene/actor/auton_queue.rb +87 -0
  43. data/lib/nestene/actor/auton_storage.rb +50 -0
  44. data/lib/nestene/actor/core.rb +150 -0
  45. data/lib/nestene/actor/delayed_scheduler.rb +76 -0
  46. data/lib/nestene/auton_context.rb +31 -0
  47. data/lib/nestene/auton_execution_queue.rb +43 -0
  48. data/lib/nestene/auton_state.rb +27 -0
  49. data/lib/nestene/callback.rb +7 -0
  50. data/lib/nestene/delayed_method.rb +17 -0
  51. data/lib/nestene/executed_method.rb +29 -0
  52. data/lib/nestene/executing_method.rb +23 -0
  53. data/lib/nestene/execution_error.rb +39 -0
  54. data/lib/nestene/scheduled_method.rb +21 -0
  55. data/lib/nestene/storage.rb +72 -0
  56. data/lib/nestene/ui/app.rb +103 -0
  57. data/lib/nestene/ui/public/app/application.js +75 -0
  58. data/lib/nestene/ui/public/vendor/angular-ui-sortable/sortable.min.js +1 -0
  59. data/lib/nestene/ui/public/vendor/angular.min.js +248 -0
  60. data/lib/nestene/ui/public/vendor/bootstrap/css/bootstrap-theme.css +347 -0
  61. data/lib/nestene/ui/public/vendor/bootstrap/css/bootstrap-theme.min.css +7 -0
  62. data/lib/nestene/ui/public/vendor/bootstrap/css/bootstrap.css +5785 -0
  63. data/lib/nestene/ui/public/vendor/bootstrap/css/bootstrap.min.css +7 -0
  64. data/lib/nestene/ui/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  65. data/lib/nestene/ui/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg +229 -0
  66. data/lib/nestene/ui/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  67. data/lib/nestene/ui/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  68. data/lib/nestene/ui/public/vendor/bootstrap/js/bootstrap.js +1951 -0
  69. data/lib/nestene/ui/public/vendor/bootstrap/js/bootstrap.min.js +6 -0
  70. data/lib/nestene/ui/public/vendor/jquery-ui.min.js +13 -0
  71. data/lib/nestene/ui/public/vendor/jquery.bootstrap-growl.min.js +1 -0
  72. data/lib/nestene/ui/public/vendor/jquery.min.js +5 -0
  73. data/lib/nestene/ui/public/vendor/json-editor/directives.js +245 -0
  74. data/lib/nestene/ui/public/vendor/json-editor/styles.css +165 -0
  75. data/lib/nestene/ui/views/auton.haml +42 -0
  76. data/lib/nestene/ui/views/auton_form.haml +8 -0
  77. data/lib/nestene/ui/views/index.haml +35 -0
  78. data/lib/nestene/ui/views/layout.haml +40 -0
  79. data/lib/nestene/ui/views/schedule_step.haml +14 -0
  80. data/lib/nestene/version.rb +3 -0
  81. data/lib/nestene.rb +50 -0
  82. data/nestene.gemspec +39 -0
  83. data/spec/nestene/auton_execution_queue_spec.rb +78 -0
  84. data/spec/nestene/nestene_spec.rb +137 -0
  85. data/spec/nestene/storage_spec.rb +125 -0
  86. data/spec/spec_helper.rb +2 -0
  87. metadata +373 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OGZlMjkwODJhMGQ4MWE0ODkyYTgzNTU4NGQyOWM5M2Q0M2ZhMTg3Nw==
5
+ data.tar.gz: !binary |-
6
+ NzhhN2NjOTM5MDM4MGZkMWZkMjU1ZGU5YTA5MDM1OTE2YzYxYTg1MQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjhmY2Q4YWFhNmIxMTE4YWQwZDE3ZTc3NzNmMzVmNGYzODMxMDYwOTQzNjlj
10
+ NDBjMTFiNWUzYmY4Y2JjNGY0MTE3MzhiMmRmODIyZjA4ZTJkOGJhODhjYWVl
11
+ ZWNmMGZkZjFiYWY4MjA5ZGE3MWU4NGJlZjg5NGJlNzE1YWZlOGY=
12
+ data.tar.gz: !binary |-
13
+ MTRlZGIxYmIwMjY2MmExMGUwM2ViNDYwOWU5ZGRjMWExN2JkOGQyZDQ0Yzc2
14
+ NDk0MDc3MTc0MjY5ZjE1MWE4MTA3YzYyMWE3MDYwYjg5ODAxODFkMDA5ZmI0
15
+ YTEzZjRjYWJjMjg0YTczN2IzNjk2NzJjMzRhMjcwODcyZWE5ODM=
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /storage
2
+ /.bundle
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Net Ice 9 Ltd
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Nestene
2
+
3
+ Execution framework for persistent Actors (Autons)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'nestene'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install nestene
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/nestene/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/TODO.txt ADDED
@@ -0,0 +1,7 @@
1
+ todo:
2
+ - Create Auton with specific ID
3
+ - Create Auton with wrong type -> error message
4
+
5
+ done:
6
+ - Render parameters field for parameters to the method, use parameters when scheduling
7
+ - Sort methods for the dropdown
data/api.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'sinatra/base'
2
+
3
+ class NesteneApi < Sinatra::Base
4
+ get '/' do
5
+ 'ok'
6
+ end
7
+ end
8
+
data/autons.rb ADDED
@@ -0,0 +1,13 @@
1
+ class DummyAuton
2
+ include StructureMapper::Hash
3
+
4
+ def start
5
+ sleep 6
6
+ end
7
+
8
+
9
+ def with_parameters p1, p2
10
+ end
11
+
12
+ attribute foo: String
13
+ end
data/bin/nestene.rb ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rack"
4
+ Rack::Server.start(config: File.expand_path('../../config.ru', __FILE__), Port: 9292)
5
+
data/config.ru ADDED
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH << '.'
2
+ $LOAD_PATH << 'lib'
3
+
4
+ require 'nestene'
5
+
6
+ Dir.mkdir('storage') unless File.exists?('storage')
7
+
8
+ Nestene::start_nestene(Nestene::DiskStorage.new('storage'))
9
+
10
+ to_check = Bundler.load.specs.map(&:full_gem_path)
11
+ to_check << '.'
12
+
13
+ to_check.each do |path|
14
+ file_name = "%s/autons.rb" % [path]
15
+ if File.exists?(file_name)
16
+ puts "loading %s" % file_name
17
+ load(file_name)
18
+ end
19
+ end
20
+
21
+ run Nestene::Ui::App
@@ -0,0 +1,6 @@
1
+ Feature: Api Create Auton
2
+
3
+ @wip
4
+ Scenario:
5
+ When request creation of an auton with an existing type
6
+ Then the API should respond with status code 201 and auton's ID
@@ -0,0 +1,11 @@
1
+ Feature: API for credentials
2
+
3
+ Scenario: getting credentials
4
+ Given there are credentials set
5
+ When I get credentials
6
+ Then I should receive credentials
7
+
8
+ Scenario: setting credentials
9
+ When I set credentials
10
+ Then the credentials should be set
11
+
@@ -0,0 +1,6 @@
1
+ Feature: list of autons
2
+
3
+ Scenario: List of autons
4
+ Given I have one started auton
5
+ When I get the API list of autons
6
+ Then result should contain the started auton
@@ -0,0 +1,13 @@
1
+ Feature: callback
2
+
3
+ Scenario: callback step execution
4
+ Given I have an Auton that holds counter state
5
+ And I have an Auton that schedules a callback step on the counter Auton
6
+ When I execute second Auton's schedule step
7
+ Then the callback step of the second Auton should be executed
8
+
9
+ Scenario: callback exception execution
10
+ Given I have an Auton that hold counter state and raises exception on execution
11
+ And I have an Auton that schedules a callback step on the counter Auton
12
+ When I execute second Auton's schedule step
13
+ Then the callback error step of the second Auton with the exception's message should be executed
@@ -0,0 +1,11 @@
1
+ Feature: create auton
2
+
3
+ Scenario: create auton
4
+ Given an empty auton
5
+ When I create the auton
6
+ Then the Auton should be in the READY state
7
+
8
+ Scenario: attempt to create auton with a wrong class name
9
+ When I try to create an auton with a non-existing type
10
+ Then an exception should be raised
11
+ And the auton should not be created
@@ -0,0 +1,7 @@
1
+ Feature: credentials
2
+
3
+ Scenario: Auton accessing credentials
4
+ Given I have an Auton that access credentials in the first step
5
+ And the credentials are set
6
+ When I execute the first step of the Auton
7
+ Then the Auton should be in the READY state
@@ -0,0 +1,59 @@
1
+ Feature: execute step
2
+
3
+ Scenario: execute simple non-failing step with parameters
4
+ Given I have a running auton with one defined step with parameters
5
+ When I add the step with parameters to the execution queue
6
+ And I wait for the step to execute
7
+ Then the Auton should be in the READY state
8
+ And the execution result should be returned
9
+
10
+ Scenario: execute simple non-failing step with parameters
11
+ Given I have a running auton with one defined step with parameters
12
+ When I add the step with parameters to the execution queue
13
+ And I wait for the step to execute
14
+ Then the Auton should be in the READY state
15
+ And the execution result should be returned
16
+
17
+ Scenario: execute simple failing step
18
+ Given I have a running auton with one defined step that fails
19
+ When I add the step to the execution queue
20
+ And I wait for the step to execute
21
+ Then the auton should be in the FAILED state
22
+ And the execution result should be an exception
23
+
24
+ Scenario: stop execution when in FAILED state
25
+ Given I have a running auton with one defined step that fails and one that does not fail
26
+ When I add first the failing and then the not failing step to the execution queue
27
+ And I wait for the first step to execute
28
+ Then the auton should be in the FAILED state
29
+ And the execution result should be an exception
30
+ And the not failing step will not be executed
31
+
32
+ Scenario: repeating failed step
33
+ Given I have a running auton with one defined step that fails on the first invocation but succeeds on the second
34
+ When I add the step to the execution queue
35
+ And I wait for the step to execute
36
+ And I repeat the failed step
37
+ And I wait for the step to execute
38
+ Then the execution result should be returned
39
+ And the Auton should be in the READY state
40
+
41
+ Scenario: resuming after failure
42
+ Given I have a running auton with one defined step that fails and one that does not fail
43
+ When I add first the failing and then the not failing step to the execution queue
44
+ And I wait for the first step to execute
45
+ Then the auton should be in the FAILED state
46
+ When I resume the failed auton
47
+ And I wait for the second step to execute
48
+ Then the execution result should be returned
49
+ And the Auton should be in the READY state
50
+
51
+ Scenario: handling exception by Auton
52
+ Given I have a running auton with one defined step that fails and one that does not fail and an exception handling method for the whole Auton
53
+ When I add first the failing and then the not failing step to the execution queue
54
+ And I wait for the first step to execute
55
+ And I wait for the second step to execute
56
+ Then the execution result should be returned
57
+ And the Auton should be in the READY state
58
+ And the "handle_exception" method should have been executed
59
+
@@ -0,0 +1,7 @@
1
+ Feature: restart
2
+
3
+ Scenario: restart with one created auton
4
+ Given an empty auton
5
+ When I create the auton
6
+ And I restart the nestene
7
+ Then the Auton should be in the READY state
@@ -0,0 +1,7 @@
1
+ Feature: schedule steps
2
+
3
+ Scenario: add step
4
+ Given I have an Auton that has two steps, first step scheduling the next step
5
+ When I schedule the first step that returns the uuid of the second scheduled step
6
+ And I wait for the second step to finish
7
+ Then the Auton should be in the READY state
@@ -0,0 +1,16 @@
1
+ When(/^request creation of an auton with an existing type$/) do
2
+ class EmptyAuton
3
+ include StructureMapper::Hash
4
+
5
+ attribute foo: String
6
+ end
7
+ @auton_type="EmptyAuton"
8
+ post '/autons', {auton_type: @auton_type}.to_json, 'Content-Type' => 'application/json'
9
+ end
10
+
11
+ Then(/^the API should respond with status code (\d+) and auton's ID$/) do |expected_status|
12
+ expect(last_response.status).to be(expected_status.to_i)
13
+ response = JSON.parse(last_response.body)
14
+ expect(response).not_to be_empty
15
+ expect(response).to have_key('auton_id')
16
+ end
@@ -0,0 +1,22 @@
1
+ Given(/^there are credentials set$/) do
2
+ Celluloid::Actor[:nestene_core].set_credentials({'a' => 'b'})
3
+ end
4
+
5
+ When(/^I get credentials$/) do
6
+ get '/credentials'
7
+ end
8
+
9
+ Then(/^I should receive credentials$/) do
10
+ expect(last_response.status).to be(200)
11
+ response = JSON.parse(last_response.body)
12
+ expect(response).to eq({'a' => 'b'})
13
+ end
14
+
15
+ When(/^I set credentials$/) do
16
+ post '/credentials', {'a' => 'b'}.to_json, 'Content-Type' => 'application/json'
17
+ end
18
+
19
+ Then(/^the credentials should be set$/) do
20
+ expect(last_response.status).to be(200)
21
+ expect(Celluloid::Actor[:nestene_core].get_credentials).to eq({'a' => 'b'})
22
+ end
@@ -0,0 +1,8 @@
1
+ When(/^I get the API list of autons$/) do
2
+ get '/autons.json'
3
+ end
4
+
5
+ Then(/^result should contain the started auton$/) do
6
+ expect(last_response).to be_ok
7
+ expect(JSON.parse(last_response.body)).not_to be_empty
8
+ end
@@ -0,0 +1,75 @@
1
+ Given(/^I have an Auton that holds counter state$/) do
2
+ class CounterAuton
3
+ include StructureMapper::Hash
4
+
5
+ def initialize
6
+ self.counter = 0
7
+ end
8
+
9
+ def next
10
+ self.counter += 1
11
+ end
12
+
13
+ attribute counter: Fixnum
14
+ end
15
+ @counter_auton_type="CounterAuton"
16
+ @counter_auton_id = Celluloid::Actor[:nestene_core].create_auton(@counter_auton_type, "counter")
17
+ end
18
+
19
+ Given(/^I have an Auton that schedules a callback step on the counter Auton$/) do
20
+ class CallbackAuton
21
+ include StructureMapper::Hash
22
+
23
+ def start
24
+ self.context.schedule_callback('counter', :next, [], :set_state)
25
+ end
26
+
27
+ def set_state new_state
28
+ self.state = new_state
29
+ end
30
+
31
+ def set_state_error error_type, message
32
+ self.error = message
33
+ end
34
+
35
+ attr_accessor :context
36
+
37
+ attribute state: Fixnum
38
+ attribute error: String
39
+ end
40
+ @callback_auton_type="CallbackAuton"
41
+ @callback_auton_id = Celluloid::Actor[:nestene_core].create_auton(@callback_auton_type, "callback")
42
+ end
43
+
44
+ When(/^I execute second Auton's schedule step$/) do
45
+ Celluloid::Actor[:nestene_core].schedule_step @callback_auton_id, :start
46
+ end
47
+
48
+ Then(/^the callback step of the second Auton should be executed$/) do
49
+ sleep 0.1
50
+ expect(Celluloid::Actor["storage:%s" % @callback_auton_id].get.serialized['state']).to eq(1)
51
+ end
52
+
53
+
54
+ Given(/^I have an Auton that hold counter state and raises exception on execution$/) do
55
+ class FailingCounterAuton
56
+ include StructureMapper::Hash
57
+
58
+ def initialize
59
+ self.counter = 0
60
+ end
61
+
62
+ def next
63
+ raise "some exception"
64
+ end
65
+
66
+ attribute counter: Fixnum
67
+ end
68
+ @counter_auton_type="FailingCounterAuton"
69
+ @counter_auton_id = Celluloid::Actor[:nestene_core].create_auton(@counter_auton_type, "counter")
70
+ end
71
+
72
+ Then(/^the callback error step of the second Auton with the exception's message should be executed$/) do
73
+ sleep 0.1
74
+ expect(Celluloid::Actor["storage:%s" % @callback_auton_id].get.serialized['error']).to eq('some exception')
75
+ end
@@ -0,0 +1,32 @@
1
+ Given(/^an empty auton$/) do
2
+ class EmptyAuton
3
+ include StructureMapper::Hash
4
+
5
+ attribute foo: String
6
+ end
7
+ @auton_type="EmptyAuton"
8
+ end
9
+
10
+ When(/^I create the auton$/) do
11
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
12
+ end
13
+
14
+ Then(/^the Auton should be in the READY state$/) do
15
+ expect(Celluloid::Actor["storage:%s" % @auton_id].get.state).to eq(:ready)
16
+ end
17
+
18
+ When(/^I try to create an auton with a non\-existing type$/) do
19
+ begin
20
+ @auton_type = Celluloid::Actor[:nestene_core].create_auton "SomeNotExistingType"
21
+ rescue Exception => exception
22
+ @exception = exception
23
+ end
24
+ end
25
+
26
+ Then(/^an exception should be raised$/) do
27
+ expect(@exception).not_to be_nil
28
+ end
29
+
30
+ Then(/^the auton should not be created$/) do
31
+ expect(@auton_type).to be_nil
32
+ end
@@ -0,0 +1,24 @@
1
+ Given(/^I have an Auton that access credentials in the first step$/) do
2
+ class CredentialsAuton
3
+ include StructureMapper::Hash
4
+
5
+ attribute credentials: String
6
+
7
+ attr_accessor :context
8
+
9
+ def use_credentials
10
+ context.credentials['mail.google.com']
11
+ end
12
+ end
13
+ @auton_type="CredentialsAuton"
14
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
15
+ end
16
+
17
+ Given(/^the credentials are set$/) do
18
+ Celluloid::Actor[:nestene_core].set_credentials({'mail.google.com' => 'creds'})
19
+ end
20
+
21
+ When(/^I execute the first step of the Auton$/) do
22
+ step_execution_id = Celluloid::Actor[:nestene_core].schedule_step @auton_id, :use_credentials
23
+ expect(Celluloid::Actor[:nestene_core].wait_for_execution_result(@auton_id, step_execution_id)).to eq('creds')
24
+ end
@@ -0,0 +1,177 @@
1
+ Given(/^I have a running auton with one defined step without any parameters$/) do
2
+ class SimpleAuton
3
+ include StructureMapper::Hash
4
+
5
+ def start
6
+ 'ok'
7
+ end
8
+
9
+ attribute foo: String
10
+ end
11
+ @auton_type="SimpleAuton"
12
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
13
+ @expected_result = "ok"
14
+ end
15
+
16
+ When(/^I add the step to the execution queue$/) do
17
+ @step_execution_id = Celluloid::Actor[:nestene_core].schedule_step @auton_id, :start
18
+ end
19
+
20
+ When(/^I wait for the step to execute$/) do
21
+ begin
22
+ @execution_result = Celluloid::Actor[:nestene_core].wait_for_execution_result(@auton_id, @step_execution_id)
23
+ rescue Exception => e
24
+ @execution_exception = e
25
+ end
26
+ end
27
+
28
+ Then(/^the execution result should be returned$/) do
29
+ expect(@execution_result).to eq(@expected_result)
30
+ end
31
+
32
+
33
+ Given(/^I have a running auton with one defined step with parameters$/) do
34
+ class SimpleParamsAuton
35
+ include StructureMapper::Hash
36
+
37
+ def start(p1)
38
+ 'param: %s' % p1
39
+ end
40
+
41
+ attribute foo: String
42
+ end
43
+ @auton_type="SimpleParamsAuton"
44
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
45
+ @expected_result = "param: p1"
46
+ end
47
+
48
+ When(/^I add the step with parameters to the execution queue$/) do
49
+ @step_execution_id = Celluloid::Actor[:nestene_core].schedule_step @auton_id, :start, "p1"
50
+ end
51
+
52
+
53
+ Given(/^I have a running auton with one defined step that fails$/) do
54
+ class SimpleFailingAuton
55
+ include StructureMapper::Hash
56
+
57
+ def start
58
+ raise "failed!"
59
+ end
60
+
61
+ attribute foo: String
62
+ end
63
+ @auton_type="SimpleFailingAuton"
64
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
65
+ end
66
+
67
+ Then(/^the auton should be in the FAILED state$/) do
68
+ expect(Celluloid::Actor["storage:%s" % @auton_id].get.state).to eq(:failed)
69
+ end
70
+
71
+ Then(/^the execution result should be an exception$/) do
72
+ expect(@execution_exception).to be_a(Exception)
73
+ end
74
+
75
+
76
+ Given(/^I have a running auton with one defined step that fails and one that does not fail$/) do
77
+ class SimpleTwoStepsFirstFailingAuton
78
+ include StructureMapper::Hash
79
+
80
+ def start
81
+ raise "failed!"
82
+ end
83
+
84
+ def cont
85
+ end
86
+
87
+ attribute foo: String
88
+ end
89
+ @auton_type="SimpleTwoStepsFirstFailingAuton"
90
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
91
+ end
92
+
93
+ When(/^I add first the failing and then the not failing step to the execution queue$/) do
94
+ @first_step_execution_id = Celluloid::Actor[:nestene_core].schedule_step @auton_id, :start
95
+ @second_step_execution_id = Celluloid::Actor[:nestene_core].schedule_step @auton_id, :cont
96
+ end
97
+
98
+ When(/^I wait for the first step to execute$/) do
99
+ begin
100
+ @execution_result = Celluloid::Actor[:nestene_core].wait_for_execution_result(@auton_id, @first_step_execution_id)
101
+ rescue Exception => e
102
+ @execution_exception = e
103
+ end
104
+ end
105
+
106
+ Then(/^the not failing step will not be executed$/) do
107
+ sleep 0.1
108
+
109
+ expect(Celluloid::Actor["storage:%s" % @auton_id].get.queue.to_execute.first.uuid).to eq(@second_step_execution_id)
110
+ end
111
+
112
+
113
+ Given(/^I have a running auton with one defined step that fails on the first invocation but succeeds on the second$/) do
114
+ class FirstExecutionFailingAuton
115
+ include StructureMapper::Hash
116
+
117
+ def initalize
118
+ self.first = true
119
+ end
120
+
121
+ def start
122
+ should_fail = self.first
123
+ self.first = false
124
+ raise "failed!" if should_fail
125
+ end
126
+
127
+ attribute first: Boolean
128
+ end
129
+ @auton_type="FirstExecutionFailingAuton"
130
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
131
+ end
132
+
133
+ When(/^I repeat the failed step$/) do
134
+
135
+ @step_execution_id = Celluloid::Actor[:nestene_core].repeat_step @auton_id, @step_execution_id
136
+
137
+ end
138
+
139
+
140
+ When(/^I resume the failed auton$/) do
141
+ @step_execution_id = Celluloid::Actor[:nestene_core].resume @auton_id
142
+ end
143
+
144
+ When(/^I wait for the second step to execute$/) do
145
+ begin
146
+ @execution_result = Celluloid::Actor[:nestene_core].wait_for_execution_result(@auton_id, @second_step_execution_id)
147
+ rescue Exception => e
148
+ @execution_exception = e
149
+ end
150
+ end
151
+
152
+
153
+ Given(/^I have a running auton with one defined step that fails and one that does not fail and an exception handling method for the whole Auton$/) do
154
+ class TwoStepsFirstFailingWithExceptionHandlerAuton
155
+ include StructureMapper::Hash
156
+
157
+ def start
158
+ raise "failed!"
159
+ end
160
+
161
+ def cont
162
+ end
163
+
164
+ def handle_exception type, message, method_name, params
165
+
166
+ end
167
+
168
+ attribute foo: String
169
+ end
170
+ @auton_type="TwoStepsFirstFailingWithExceptionHandlerAuton"
171
+ @auton_id = Celluloid::Actor[:nestene_core].create_auton @auton_type
172
+ end
173
+
174
+ Then(/^the "(.*?)" method should have been executed$/) do |method_name|
175
+ expect(Celluloid::Actor["storage:%s" % @auton_id].get.queue.executed.map(&:name)).to include(method_name.to_sym)
176
+ end
177
+
@@ -0,0 +1,5 @@
1
+ When(/^I restart the nestene$/) do
2
+ Celluloid.shutdown
3
+ Celluloid.boot
4
+ Nestene::start_nestene(@storage)
5
+ end