cloud_powers 0.2.7.23 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.test.env.example +6 -6
- data/.travis.yml +1 -1
- data/README +190 -0
- data/cloud_powers.gemspec +4 -4
- data/lib/cloud_powers.rb +3 -13
- data/lib/cloud_powers/aws_resources.rb +21 -4
- data/lib/cloud_powers/creatable.rb +122 -0
- data/lib/cloud_powers/helpers.rb +58 -0
- data/lib/cloud_powers/helpers/lang_help.rb +288 -0
- data/lib/cloud_powers/helpers/logic_help.rb +152 -0
- data/lib/cloud_powers/helpers/path_help.rb +90 -0
- data/lib/cloud_powers/node.rb +69 -68
- data/lib/cloud_powers/node/instance.rb +52 -0
- data/lib/cloud_powers/resource.rb +44 -0
- data/lib/cloud_powers/storage.rb +27 -14
- data/lib/{stubs → cloud_powers/stubs}/aws_stubs.rb +37 -14
- data/lib/cloud_powers/synapse/broadcast.rb +117 -0
- data/lib/cloud_powers/synapse/broadcast/channel.rb +44 -0
- data/lib/cloud_powers/synapse/pipe.rb +211 -0
- data/lib/cloud_powers/synapse/pipe/stream.rb +41 -0
- data/lib/cloud_powers/synapse/queue.rb +357 -0
- data/lib/cloud_powers/synapse/queue/board.rb +61 -95
- data/lib/cloud_powers/synapse/queue/poller.rb +29 -0
- data/lib/cloud_powers/synapse/synapse.rb +10 -12
- data/lib/cloud_powers/synapse/web_soc.rb +13 -0
- data/lib/cloud_powers/synapse/web_soc/soc_client.rb +52 -0
- data/lib/cloud_powers/synapse/web_soc/soc_server.rb +48 -0
- data/lib/cloud_powers/version.rb +1 -1
- data/lib/cloud_powers/zenv.rb +13 -12
- metadata +24 -13
- data/lib/cloud_powers/context.rb +0 -275
- data/lib/cloud_powers/delegator.rb +0 -113
- data/lib/cloud_powers/helper.rb +0 -453
- data/lib/cloud_powers/synapse/websocket/websocclient.rb +0 -53
- data/lib/cloud_powers/synapse/websocket/websocserver.rb +0 -46
- data/lib/cloud_powers/workflow_factory.rb +0 -160
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Smash
|
6
|
+
module CloudPowers
|
7
|
+
module PathHelp
|
8
|
+
|
9
|
+
# Gives a common home for jobs to live so they can be easily grouped and
|
10
|
+
# found. This method will create nested directories, based on the
|
11
|
+
# <tt>#project_root()</tt> method and an additional 'lib/jobs' directory.
|
12
|
+
# If no project root has been set by the time this method is called, a new
|
13
|
+
# directory will be created relative to the gem's project root.
|
14
|
+
#
|
15
|
+
# Returns
|
16
|
+
# +String+
|
17
|
+
#
|
18
|
+
# Notes
|
19
|
+
# * # If no project root has been set by the time this method is called, a new
|
20
|
+
# directory will be created relative to the gem's project root. This might
|
21
|
+
# have deeper implications than you want to deal with so it's always a good
|
22
|
+
# idea to set your project root as soon as you can.
|
23
|
+
# * TODO: find a way to have this method figure out the actual project's
|
24
|
+
# root, as opposed to just making common <i>"good"</i> assumptions.
|
25
|
+
def job_home
|
26
|
+
string_th = FileUtils.mkdir_p("#{project_root}/lib/jobs/").first
|
27
|
+
@job_home ||= Pathname.new(string_th).realpath.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
# Gives the path from the project root to lib/jobs[/#{file}.rb]
|
31
|
+
#
|
32
|
+
# Parameters
|
33
|
+
# * file +String+ (optional) (default is '') - name of a file
|
34
|
+
#
|
35
|
+
# Returns
|
36
|
+
# * path/file +String+ if +file+ parameter is given. return has
|
37
|
+
# '.rb' extension included
|
38
|
+
# * file +String+ if +file+ parameter is not given it will return the
|
39
|
+
# <tt>#job_require_path()</tt>
|
40
|
+
#
|
41
|
+
# Notes
|
42
|
+
# * See <tt>#job_home</tt>
|
43
|
+
def job_path(file = '')
|
44
|
+
return job_home if file.empty?
|
45
|
+
Pathname.new("#{job_home}/#{file}").to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# Check if the job file exists in the job directory
|
50
|
+
#
|
51
|
+
# Parameters
|
52
|
+
# * file +String+
|
53
|
+
#
|
54
|
+
# Returns
|
55
|
+
# +Boolean+
|
56
|
+
#
|
57
|
+
# Notes
|
58
|
+
# * See +#job_home()+
|
59
|
+
def job_exist?(file)
|
60
|
+
begin
|
61
|
+
File.new("#{job_home}/#{file}")
|
62
|
+
true
|
63
|
+
rescue Errno::ENOENT
|
64
|
+
false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Gives the path from the project root to lib/jobs[/file]
|
69
|
+
#
|
70
|
+
# Parameters String (optional)
|
71
|
+
# * file_name name of a file
|
72
|
+
#
|
73
|
+
# Returns
|
74
|
+
# * path/file +String+ if +file_name+ was given
|
75
|
+
# * path to job_directory if +file_name+ was <i>not</i> given
|
76
|
+
#
|
77
|
+
# Notes
|
78
|
+
# * Neither path nor file will have a file extension
|
79
|
+
# * See <tt>#job_home</tt>
|
80
|
+
def job_require_path(file_name = '')
|
81
|
+
begin
|
82
|
+
file_sans_extension = File.basename(file_name, '.*')
|
83
|
+
(Pathname.new(job_home) + file_sans_extension).to_s
|
84
|
+
rescue Errno::ENOENT
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/cloud_powers/node.rb
CHANGED
@@ -1,36 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require 'cloud_powers/auth'
|
2
|
+
require 'cloud_powers/helpers'
|
3
|
+
require 'cloud_powers/zenv'
|
4
|
+
require 'cloud_powers/node/instance'
|
5
5
|
|
6
6
|
module Smash
|
7
7
|
module CloudPowers
|
8
8
|
module Node
|
9
9
|
include Smash::CloudPowers::Auth
|
10
|
-
include Smash::CloudPowers::
|
11
|
-
include Smash::CloudPowers::SelfAwareness
|
10
|
+
include Smash::CloudPowers::Helpers
|
12
11
|
include Smash::CloudPowers::Zenv
|
13
12
|
|
14
|
-
#
|
13
|
+
# This method adds certain tags to an array of resource ids.
|
15
14
|
#
|
16
15
|
# Parameters
|
17
|
-
# *
|
18
|
-
#
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
16
|
+
# * ids +Array+|+String+ - an Array or a single instance id, as an Array
|
17
|
+
# of Strings or a single String
|
18
|
+
# * tags +Array+ - an Array of key, value hash
|
19
|
+
#
|
20
|
+
# Returns
|
21
|
+
# * Returns an empty response.
|
22
|
+
#
|
23
|
+
# Examples
|
24
|
+
# create_tag('ami-2342354', tags: { key: "stack", value: "production"})
|
25
|
+
# or
|
26
|
+
# create_tag(['ami-2432342'], tags: [{ key: 'stack', value: 'production' }])
|
27
|
+
# or any permutation of those
|
28
|
+
def batch_tag(ids, tags, client: ec2)
|
29
|
+
tags_opts = { resources: ids, tags: tags }
|
30
|
+
ec2.create_tags(tags_opts)
|
31
|
+
logger.info "tags for #{ids} created"
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_node(name:, client: ec2, **config)
|
35
|
+
resp = Smash::CloudPowers::Node::Instance.build(name: name, client: ec2, **config)
|
36
|
+
i_var_name = "#{name}_node"
|
37
|
+
instance_attr_accessor i_var_name
|
38
|
+
instance_variable_set(to_i_var(i_var_name), resp)
|
34
39
|
end
|
35
40
|
|
36
41
|
# Uses +Aws::EC2#run_instances()+ to create nodes (Neurons or Cerebrums), at
|
@@ -43,58 +48,54 @@ module Smash
|
|
43
48
|
# * opts +Hash+ (optional)
|
44
49
|
# an optional instance configuration hash can be passed, which will override
|
45
50
|
# the values in the default configuration returned by #instance_config()
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
response = ec2.run_instances(node_config(opts))
|
52
|
-
ids = response.instances.map(&:instance_id)
|
53
|
-
|
54
|
-
if should_wait
|
55
|
-
count = 0
|
56
|
-
begin
|
57
|
-
ec2.wait_until(:instance_running, instance_ids: ids) do
|
58
|
-
logger.info "waiting for #{ids.count} Neurons to start..."
|
59
|
-
end
|
60
|
-
rescue Aws::Waiters::Errors::WaiterFailed => e
|
61
|
-
# TODO: deal with failed instances
|
62
|
-
# redo unless (count += 1 <=3 )
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
batch_tag(ids, tags) unless tags.empty?
|
67
|
-
ids
|
68
|
-
|
69
|
-
rescue Aws::EC2::Errors::DryRunOperation
|
70
|
-
ids = (1..(opts[:max_count] || 0)).to_a.map { |n| n.to_s }
|
71
|
-
logger.info "waiting for #{ids.count} Neurons to start..."
|
72
|
-
end
|
73
|
-
|
74
|
-
ids
|
51
|
+
def create_node(name:, client: ec2, **config)
|
52
|
+
resp = Smash::CloudPowers::Node::Instance.create!(name: name, client: ec2, **config)
|
53
|
+
i_var_name = "#{name}_node"
|
54
|
+
instance_attr_accessor i_var_name
|
55
|
+
instance_variable_set(to_i_var(i_var_name), resp)
|
75
56
|
end
|
76
57
|
|
77
|
-
#
|
58
|
+
# Uses +Aws::EC2#run_instances()+ to create nodes (Neurons or Cerebrums),
|
59
|
+
# at a rate of 0..(n <= 100) at a time, until the required number of
|
60
|
+
# instances has been started. The #instance_config() method is used to
|
61
|
+
# create instance configuration for the #run_instances method by using
|
62
|
+
# the opts hash that was provided as a parameter.
|
78
63
|
#
|
79
64
|
# Parameters
|
80
|
-
# *
|
81
|
-
#
|
65
|
+
# * opts +Hash+ (optional) - an optional instance configuration hash can
|
66
|
+
# be passed, which will override the values in the default configuration
|
67
|
+
# returned by <tt>#instance_config()</tt>
|
82
68
|
#
|
83
69
|
# Returns
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# or any permutation of those
|
91
|
-
|
92
|
-
def batch_tag(ids, tags)
|
93
|
-
tags_opts = { resources: ids, tags: tags }
|
94
|
-
ec2.create_tags(tags_opts)
|
95
|
-
logger.info "tags for #{ids} created"
|
70
|
+
# +Array+ of responses from
|
71
|
+
def create_nodes(name:, client: ec2, **config)
|
72
|
+
resp = ec2.run_instances(node_config(config)).instances
|
73
|
+
i_var_name = "#{name}_nodes"
|
74
|
+
instance_attr_accessor i_var_name
|
75
|
+
instance_variable_set(to_i_var(i_var_name), resp)
|
96
76
|
end
|
97
77
|
|
78
|
+
# These are sensible defaults that can be overriden by providing a Hash as a param.
|
79
|
+
#
|
80
|
+
# Parameters
|
81
|
+
# * opts +Hash+ (optional)
|
82
|
+
# the opts Hash should have values that should be used instead of the default
|
83
|
+
# configuration.
|
84
|
+
def node_config(**config)
|
85
|
+
{
|
86
|
+
dry_run: zfind(:testing) || false,
|
87
|
+
image_id: image(zfind(:node_image)).image_id, # image(:neuron).image_id
|
88
|
+
instance_type: 't2.nano',
|
89
|
+
min_count: config[:max_count] || 0,
|
90
|
+
max_count: 0,
|
91
|
+
key_name: 'crawlBot',
|
92
|
+
security_groups: ['webCrawler'],
|
93
|
+
security_group_ids: ['sg-940edcf2'],
|
94
|
+
placement: { availability_zone: 'us-west-2c' },
|
95
|
+
disable_api_termination: 'false',
|
96
|
+
instance_initiated_shutdown_behavior: 'terminate'
|
97
|
+
}.merge(config)
|
98
|
+
end
|
98
99
|
end
|
99
100
|
end
|
100
101
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'cloud_powers/node'
|
2
|
+
require 'cloud_powers/resource'
|
3
|
+
|
4
|
+
module Smash
|
5
|
+
module CloudPowers
|
6
|
+
module Node
|
7
|
+
class Instance < Smash::CloudPowers::Resource
|
8
|
+
include Smash::CloudPowers::Node
|
9
|
+
|
10
|
+
# The name of the Aws::EC2 instance
|
11
|
+
attr_accessor :name
|
12
|
+
# An Aws::EC2::Client. See <tt>Smash::CloudPowers::AwsResources#ec2()</tt>
|
13
|
+
attr_accessor :ec2
|
14
|
+
|
15
|
+
def initialize(name:, client: ec2, **config)
|
16
|
+
super(name: name)
|
17
|
+
@ec2 = client
|
18
|
+
end
|
19
|
+
|
20
|
+
# Uses +Aws::EC2#run_instances()+ to create nodes (Neurons or Cerebrums), at
|
21
|
+
# a rate of 0..(n <= 100) at a time, until the required number of instances
|
22
|
+
# has been started. The #instance_config() method is used to create instance
|
23
|
+
# configuration for the #run_instances method by using the opts hash that was
|
24
|
+
# provided as a parameter.
|
25
|
+
#
|
26
|
+
# Parameters
|
27
|
+
# * opts +Hash+ (optional)
|
28
|
+
# an optional instance configuration hash can be passed, which will override
|
29
|
+
# the values in the default configuration returned by #instance_config()
|
30
|
+
def create_resource
|
31
|
+
# response = ec2.run_instances(
|
32
|
+
# node_config(max_count: 1, self.to_h)
|
33
|
+
# ).instances.first
|
34
|
+
|
35
|
+
instance_attr_accessor response
|
36
|
+
# id = @response[:instance_id]
|
37
|
+
begin
|
38
|
+
ec2.wait_until(:instance_running, instance_ids: [id]) do
|
39
|
+
logger.info "waiting for #{ids.count} Neurons to start..."
|
40
|
+
end
|
41
|
+
rescue Aws::Waiters::Errors::WaiterFailed => e
|
42
|
+
# TODO: retry stuff
|
43
|
+
# redo unless (count += 1 <=3 )
|
44
|
+
end
|
45
|
+
|
46
|
+
yield self if block_given?
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'cloud_powers/aws_resources'
|
2
|
+
require 'cloud_powers/creatable'
|
3
|
+
require 'cloud_powers/helpers'
|
4
|
+
require 'cloud_powers/zenv'
|
5
|
+
|
6
|
+
module Smash
|
7
|
+
module CloudPowers
|
8
|
+
class Resource
|
9
|
+
include Smash::CloudPowers::Creatable
|
10
|
+
include Smash::CloudPowers::AwsResources
|
11
|
+
include Smash::CloudPowers::Helpers
|
12
|
+
include Smash::CloudPowers::Zenv
|
13
|
+
|
14
|
+
# client used to make HTTP requests to the cloud
|
15
|
+
attr_accessor :client
|
16
|
+
# the name this resource can be set and retrieved by
|
17
|
+
attr_accessor :call_name
|
18
|
+
# the given name for this resource
|
19
|
+
attr_accessor :name
|
20
|
+
# whether or not a call has been made to the cloud to back this resource
|
21
|
+
attr_accessor :linked
|
22
|
+
# the ID in the cloud; e.g. ARN for AWS, etc
|
23
|
+
attr_accessor :remote_id
|
24
|
+
# tracking on the remote resource that maps to this resource
|
25
|
+
attr_accessor :tags
|
26
|
+
# the type of resource this was instantiated as
|
27
|
+
attr_accessor :type
|
28
|
+
|
29
|
+
# Usually this method is called by calling +super+ in another class that
|
30
|
+
# inherits from this class. The initialize method follows the method
|
31
|
+
# signature for the active record-like pattern being followed throughout
|
32
|
+
# the code
|
33
|
+
def initialize(name:, client: nil, **config)
|
34
|
+
@linked = false
|
35
|
+
@saved = false
|
36
|
+
@client = client
|
37
|
+
@type = to_snake(self.class.name.split('::').last)
|
38
|
+
@call_name = to_snake("#{name}_#{@type}")
|
39
|
+
@name = name
|
40
|
+
@tags = Array.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/cloud_powers/storage.rb
CHANGED
@@ -6,7 +6,11 @@ module Smash
|
|
6
6
|
module Storage
|
7
7
|
include Smash::CloudPowers::AwsResources
|
8
8
|
|
9
|
-
|
9
|
+
def local_job_file_exists?(file)
|
10
|
+
File.exists?(job_path(to_ruby_file_name(file)))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Searches a local job storage location for the given +file+ name
|
10
14
|
# if it exists - exit the method
|
11
15
|
# if it does <i>not</i> exist - get the file from s3 and place it in
|
12
16
|
# the directory that was just searched bucket using +#zfind()+
|
@@ -22,31 +26,32 @@ module Smash
|
|
22
26
|
# project_root- |
|
23
27
|
# |_sub_directory
|
24
28
|
# | |_current_file.rb
|
25
|
-
# |
|
29
|
+
# |_job_storage
|
26
30
|
# | |_demorific.rb
|
27
31
|
# | |_foobar.rb
|
28
32
|
# * code:
|
29
|
-
#
|
33
|
+
# source_job('demorific')
|
30
34
|
# # file tree doesn't change because this file exists
|
31
|
-
#
|
35
|
+
# source_job('custom_greetings')
|
32
36
|
# # file tree now looks like this
|
33
37
|
# * new file tree
|
34
38
|
# project_root- |
|
35
39
|
# |_sub_directory
|
36
40
|
# | |_current_file.rb
|
37
|
-
# |
|
41
|
+
# |_job_storage
|
38
42
|
# | |_demorific.rb
|
39
43
|
# | |_foobar.rb
|
40
44
|
# | |_custom_greetings.js # could be an after effects JS script
|
41
|
-
def
|
45
|
+
def source_job(file)
|
42
46
|
# TODO: better path management
|
43
|
-
bucket = zfind('
|
44
|
-
if
|
47
|
+
bucket = zfind('job storage')
|
48
|
+
if job_path(to_ruby_file_name(file)).nil?
|
45
49
|
objects = s3.list_objects(bucket: bucket).contents.select do |f|
|
46
50
|
/#{Regexp.escape file}/i =~ f.key
|
47
51
|
end
|
52
|
+
|
48
53
|
objects.each do |obj|
|
49
|
-
s3.get_object(bucket: bucket, key: obj.key, response_target:
|
54
|
+
s3.get_object(bucket: bucket, key: obj.key, response_target: job_path(file))
|
50
55
|
end
|
51
56
|
end
|
52
57
|
end
|
@@ -55,17 +60,25 @@ module Smash
|
|
55
60
|
#
|
56
61
|
# Parameters
|
57
62
|
# * bucket +String+ - the bucket to search through in AWS
|
58
|
-
# * pattern +
|
59
|
-
# search
|
63
|
+
# * pattern +Regexp+|+nil+ - the Regex pattern you want to use for the
|
64
|
+
# search. nil doesn't cause an exception but probably returns <tt>[]</tt>
|
60
65
|
#
|
61
66
|
# Example
|
62
|
-
# matches = search('
|
67
|
+
# matches = search('neuronJobs', /[Dd]emo\w*/)
|
63
68
|
# # => ['Aws::S3::Type::ListObjectOutPut','Aws::S3::Type::ListObjectOutPut',...] # anything that matched that regex
|
64
69
|
# matches.first.contents.size
|
65
70
|
# # => 238934 # integer representation of the file size
|
66
71
|
def search(bucket, pattern)
|
67
|
-
|
68
|
-
|
72
|
+
return [] if bucket.nil?
|
73
|
+
|
74
|
+
begin
|
75
|
+
pattern = /#{pattern}/ unless pattern.kind_of? Regexp
|
76
|
+
s3.list_objects(bucket: bucket).contents.select do |o|
|
77
|
+
o.key =~ pattern || /#{o.key}/ =~ pattern.to_s
|
78
|
+
end
|
79
|
+
rescue Aws::S3::Errors::NoSuchBucket => e
|
80
|
+
logger.info format_error_message e
|
81
|
+
return # log that the bucket doesn't exist but don't explode
|
69
82
|
end
|
70
83
|
end
|
71
84
|
|
@@ -74,7 +74,7 @@ module Smash
|
|
74
74
|
# for your own custom configuration
|
75
75
|
def self.node_stub(opts = {})
|
76
76
|
time = opts[:launch_time] || Time.new((Time.now.utc.to_i / 86400 * 86400)) # midnight
|
77
|
-
tags = [{key: '
|
77
|
+
tags = [{key: 'job', value: 'test'}]
|
78
78
|
{
|
79
79
|
stub_responses: {
|
80
80
|
create_tags: {},
|
@@ -143,18 +143,22 @@ module Smash
|
|
143
143
|
stub.merge(opts.select { |k,v| stub.key? k })
|
144
144
|
end
|
145
145
|
|
146
|
-
# Get or create an Kinesis client and cache that client so that a Context
|
146
|
+
# Get or create an Kinesis client and cache that client so that a Context
|
147
|
+
# is more well tied together
|
147
148
|
# Parameters
|
148
149
|
# * opts <tt>Hash</tt>
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
150
|
+
# * stub_responses: defaulted to false but it can be overriden with the
|
151
|
+
# desired responses for local testing
|
152
|
+
# * region: defaulted to use the `#region()` method
|
153
|
+
# * AWS::Credentials object, which will also scour the context and
|
154
|
+
# environment for your keys
|
152
155
|
#
|
153
156
|
# Returns
|
154
157
|
# AWS::Kinesis client
|
155
158
|
#
|
156
159
|
# Example
|
157
|
-
# # sets and gets an Kinesis client. No need to set a variable because
|
160
|
+
# # sets and gets an Kinesis client. No need to set a variable because
|
161
|
+
# one was
|
158
162
|
# # just created as +@kinesis+ and is set to the client
|
159
163
|
# kinesis(Smash::CloudPowers::AwsStubs.pipe_stub)
|
160
164
|
#
|
@@ -175,6 +179,7 @@ module Smash
|
|
175
179
|
},
|
176
180
|
describe_stream: {
|
177
181
|
stream_description: {
|
182
|
+
stream_creation_timestamp: Time.now - 10,
|
178
183
|
stream_name: opts[:name] || 'testPipe',
|
179
184
|
stream_arn: 'arnarnarnarnar',
|
180
185
|
stream_status: 'ACTIVE',
|
@@ -223,7 +228,25 @@ module Smash
|
|
223
228
|
def self.storage_stub(opts = {})
|
224
229
|
{
|
225
230
|
stub_responses: {
|
226
|
-
head_bucket: {
|
231
|
+
head_bucket: {
|
232
|
+
|
233
|
+
},
|
234
|
+
list_objects: {
|
235
|
+
is_truncated: false,
|
236
|
+
contents: [
|
237
|
+
key: 'testinz',
|
238
|
+
last_modified: Time.now,
|
239
|
+
etag: 'asdf1234',
|
240
|
+
size: 123,
|
241
|
+
storage_class: 'STANDARD',
|
242
|
+
owner: {display_name: 'snargle', id: 'id-bargle132'}
|
243
|
+
],
|
244
|
+
name: 'testFile',
|
245
|
+
prefix: 'test',
|
246
|
+
delimiter: ' ',
|
247
|
+
max_keys: 1234,
|
248
|
+
common_prefixes: [{ prefix: 'test' }]
|
249
|
+
}
|
227
250
|
}
|
228
251
|
}
|
229
252
|
end
|
@@ -250,14 +273,14 @@ module Smash
|
|
250
273
|
# for your own custom configuration
|
251
274
|
def self.queue_stub(opts = {})
|
252
275
|
msg_body = if opts[:body]
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
rescue JSON::ParserError
|
259
|
-
{foo: 'bar'}.to_json
|
276
|
+
begin
|
277
|
+
if opts[:body].kind_of? Hash
|
278
|
+
opts[:body] = opts[:body].to_json
|
279
|
+
elsif JSON.parse(opts[:body])
|
280
|
+
opts[:body]
|
260
281
|
end
|
282
|
+
rescue JSON::ParserError
|
283
|
+
{foo: 'bar'}.to_json
|
261
284
|
end
|
262
285
|
end
|
263
286
|
{
|