beanstalk_integration_tests 0.0.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.
Files changed (31) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +22 -0
  4. data/README.md +38 -0
  5. data/Rakefile +9 -0
  6. data/beanstalk_integration_tests.gemspec +26 -0
  7. data/lib/beanstalk_integration_tests.rb +2 -0
  8. data/lib/beanstalk_integration_tests/bury_test.rb +137 -0
  9. data/lib/beanstalk_integration_tests/delete_test.rb +160 -0
  10. data/lib/beanstalk_integration_tests/ignore_test.rb +127 -0
  11. data/lib/beanstalk_integration_tests/kick_job_test.rb +68 -0
  12. data/lib/beanstalk_integration_tests/kick_test.rb +207 -0
  13. data/lib/beanstalk_integration_tests/list_tube_used_test.rb +26 -0
  14. data/lib/beanstalk_integration_tests/list_tubes_test.rb +26 -0
  15. data/lib/beanstalk_integration_tests/list_tubes_watched_test.rb +26 -0
  16. data/lib/beanstalk_integration_tests/pause_tube_test.rb +166 -0
  17. data/lib/beanstalk_integration_tests/peek_test.rb +242 -0
  18. data/lib/beanstalk_integration_tests/put_test.rb +255 -0
  19. data/lib/beanstalk_integration_tests/quit_test.rb +24 -0
  20. data/lib/beanstalk_integration_tests/release_test.rb +191 -0
  21. data/lib/beanstalk_integration_tests/reserve_test.rb +385 -0
  22. data/lib/beanstalk_integration_tests/stats_job_test.rb +116 -0
  23. data/lib/beanstalk_integration_tests/stats_test.rb +130 -0
  24. data/lib/beanstalk_integration_tests/stats_tube_test.rb +141 -0
  25. data/lib/beanstalk_integration_tests/test_helper.rb +88 -0
  26. data/lib/beanstalk_integration_tests/tests.rb +4 -0
  27. data/lib/beanstalk_integration_tests/touch_test.rb +118 -0
  28. data/lib/beanstalk_integration_tests/use_test.rb +118 -0
  29. data/lib/beanstalk_integration_tests/version.rb +3 -0
  30. data/lib/beanstalk_integration_tests/watch_test.rb +128 -0
  31. metadata +157 -0
@@ -0,0 +1,116 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+
3
+ class StatsJobTest < BeanstalkIntegrationTest
4
+
5
+ context 'stats-job' do
6
+
7
+ setup do
8
+ client.transmit("use #{tube_name}")
9
+ end
10
+
11
+
12
+ should 'return stats for the specified job with all expected keys' do
13
+ message = uuid
14
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
15
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
16
+ response = client.transmit("stats-job #{job_id}")
17
+ assert_equal 'OK', response[:status]
18
+ job_stats = response[:body]
19
+ expected_keys = %w[
20
+ id tube state pri age delay ttr time-left file reserves timeouts
21
+ releases buries kicks
22
+ ]
23
+ assert_equal expected_keys, job_stats.keys
24
+ assert_nil job_stats.values.compact!, 'Expected job stats to have no nil values'
25
+ assert_equal(initial_cmd_stats_job + 1, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be incremented')
26
+ end
27
+
28
+ # Some stats are tested elsewhere:
29
+ #
30
+ # :id => See below
31
+ # :tube => PutTest
32
+ # :state => PutTest, BuryTest, ReleaseTest
33
+ # :pri => PutTest, BuryTest, ReleaseTest
34
+ # :age => See below
35
+ # :time-left => PutTest, TouchTest
36
+ # :file => NOT TESTED (except for presence)
37
+ # :reserves => ReserveTest
38
+ # :timeouts => TouchTest
39
+ # :releases => ReleaseTest
40
+ # :buries => BuryTest
41
+ # :kicks => KickTest, KickJobTest
42
+ #
43
+ # For those that aren't...
44
+
45
+ should 'return correct id' do
46
+ message = uuid
47
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
48
+ assert_equal(job_id.to_i, client.transmit("stats-job #{job_id}")[:body]['id'], 'Expected job-stats[id] to return correct job id')
49
+ end
50
+
51
+
52
+ should 'return correct age' do
53
+ message = uuid
54
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
55
+ initial_job_age = client.transmit("stats-job #{job_id}")[:body]['age']
56
+ sleep 1
57
+ assert_equal(initial_job_age + 1, client.transmit("stats-job #{job_id}")[:body]['age'], 'Expected job-stats[age] to return incremented job age')
58
+ end
59
+
60
+
61
+ should 'return NOT_FOUND if the job has never existed' do
62
+ message = uuid
63
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
64
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
65
+ assert_raises(Beaneater::NotFoundError, 'Expected job-stats for non-existent job to return NOT_FOUND') do
66
+ client.transmit("stats-job #{job_id.to_i + 1}")
67
+ end
68
+ assert_equal(initial_cmd_stats_job + 1, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be incremented')
69
+ end
70
+
71
+
72
+ should 'return NOT_FOUND if the job is deleted' do
73
+ message = uuid
74
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
75
+ client.transmit("delete #{job_id}")
76
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
77
+ assert_raises(Beaneater::NotFoundError, 'Expected job-stats for deleted job to return NOT_FOUND') do
78
+ client.transmit("stats-job #{job_id}")
79
+ end
80
+ assert_equal(initial_cmd_stats_job + 1, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be incremented')
81
+ end
82
+
83
+
84
+ should 'return BAD_FORMAT without trailing space' do
85
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
86
+ assert_raises(Beaneater::BadFormatError, 'Expected job-stats without space to return BAD_FORMAT') do
87
+ client.transmit('stats-job')
88
+ end
89
+ assert_equal(initial_cmd_stats_job, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be unchanged')
90
+ end
91
+
92
+
93
+ should 'return NOT_FOUND if job id is null, negative, or non-integer' do
94
+ ['', -5, 'foo'].each do |job_id|
95
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
96
+ assert_raises(Beaneater::NotFoundError, 'Expected job-stats for invalid job id to return NOT_FOUND') do
97
+ client.transmit("stats-job #{job_id}")
98
+ end
99
+ assert_equal(initial_cmd_stats_job + 1, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be incremented')
100
+ end
101
+ end
102
+
103
+
104
+ should 'ignore trailing space, arguments, and chars' do
105
+ message = uuid
106
+ job_id = client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
107
+ [' ', ' and ignore these arguments', '_and_ignore_these_letters'].each do |trailer|
108
+ initial_cmd_stats_job = client.transmit('stats')[:body]['cmd-stats-job']
109
+ client.transmit("stats-job #{job_id}#{trailer}")
110
+ assert_equal(initial_cmd_stats_job + 1, client.transmit('stats')[:body]['cmd-stats-job'], 'Expected cmd-stats-job to be incremented')
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -0,0 +1,130 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+ require 'socket'
3
+ require 'English'
4
+
5
+ class StatsTest < BeanstalkIntegrationTest
6
+
7
+ context 'stats' do
8
+
9
+ should 'return server stats with expected keys' do
10
+ expected_keys = %w[
11
+ current-jobs-urgent current-jobs-ready current-jobs-reserved current-jobs-delayed
12
+ current-jobs-buried cmd-put cmd-peek cmd-peek-ready cmd-peek-delayed cmd-peek-buried cmd-reserve
13
+ cmd-reserve-with-timeout cmd-delete cmd-release cmd-use cmd-watch cmd-ignore cmd-bury cmd-kick
14
+ cmd-touch cmd-stats cmd-stats-job cmd-stats-tube cmd-list-tubes cmd-list-tube-used
15
+ cmd-list-tubes-watched cmd-pause-tube job-timeouts total-jobs max-job-size current-tubes
16
+ current-connections current-producers current-workers current-waiting total-connections pid
17
+ version rusage-utime rusage-stime uptime binlog-oldest-index binlog-current-index
18
+ binlog-records-migrated binlog-records-written binlog-max-size id hostname
19
+ ]
20
+ initial_cmd_stats = client.transmit('stats')[:body]['cmd-stats']
21
+ response = client.transmit('stats')
22
+ assert_equal 'OK', response[:status]
23
+ assert_equal expected_keys, response[:body].keys
24
+ assert_nil response[:body].values.compact!, 'Expected stats to include no nil values'
25
+ assert_equal(initial_cmd_stats + 1, response[:body]['cmd-stats'], 'Expected cmd-stats to be incremented')
26
+ end
27
+
28
+ # Some stats are tested elsewhere:
29
+ #
30
+ # :current-jobs-urgent => PutTest, ReleaseTest
31
+ # :current-jobs-ready => PutTest, ReleaseTest
32
+ # :current-jobs-reserved => ReserveTest, ReleaseTest
33
+ # :current-jobs-delayed => KickTest, PutTest, ReleaseTest
34
+ # :current-jobs-buried => BuryTest, KickTest
35
+ # :total-jobs => PutTest
36
+ # :cmd-put => PutTest
37
+ # :cmd-peek => PeekTest
38
+ # :cmd-peek-ready => PeekTest
39
+ # :cmd-peek-delayed => PeekTest
40
+ # :cmd-peek-buried => PeekTest
41
+ # :cmd-reserve => ReserveTest
42
+ # :cmd-use => UseTest
43
+ # :cmd-watch => WatchTest
44
+ # :cmd-ignore => IgnoreTest
45
+ # :cmd-delete => DeleteTest
46
+ # :cmd-release => ReleaseTest
47
+ # :cmd-bury => BuryTest
48
+ # :cmd-kick => KickTest
49
+ # :cmd-stats => See above/below
50
+ # :cmd-stats-job => StatsJobTest
51
+ # :cmd-stats-tube => StatsTubeTest
52
+ # :cmd-list-tubes => ListTubesTest
53
+ # :cmd-list-tube-used => ListTubeUsedTest
54
+ # :cmd-list-tubes-watched => ListTubesWatchedTest
55
+ # :cmd-pause-tube => PauseTubeTest
56
+ # :job-timeouts => TouchTest
57
+ # :total-jobs => PutTest
58
+ # :max-job-size => PutTest (Tests retrieval directly, indiectly tests value set correctly)
59
+ # :current-tube => UseTest, Watch Test
60
+ # :current-connections => See below
61
+ # :current-producers => PutTest
62
+ # :current-workers => ReserveTest
63
+ # :current-waiting => ReserveTest
64
+ # :total-connections => See below
65
+ # :pid => See below
66
+ # :version => NOT TESTED only tested for presence
67
+ # :rusage-utime => NOT TESTED only tested for presence
68
+ # :rusage-stime => NOT TESTED only tested for presence
69
+ # :uptime => See below
70
+ # :binlog-oldest-index => NOT TESTED only tested for presence
71
+ # :binlog-current-index => NOT TESTED only tested for presence
72
+ # :binlog-max-size => NOT TESTED only tested for presence
73
+ # :binlog-records-written => NOT TESTED only tested for presence
74
+ # :binlog-records-written => NOT TESTED only tested for presence
75
+ # :id => NOT TESTED only tested for presence
76
+ # :hostname => See below
77
+ #
78
+ # For those that aren't...
79
+
80
+
81
+ should 'return correct hostname' do
82
+ # This test assume tests and beanstalk are being run on same host
83
+ assert_equal Socket.gethostname, client.transmit('stats')[:body]['hostname']
84
+ end
85
+
86
+
87
+ should 'return correct uptime' do
88
+ initial_uptime = client.transmit('stats')[:body]['uptime']
89
+ sleep 1
90
+ updated_uptime = client.transmit('stats')[:body]['uptime']
91
+ assert(updated_uptime > initial_uptime, 'Expected uptime to to be incremented')
92
+ end
93
+
94
+
95
+ should 'return correct pid' do
96
+ %x[which pgrep]
97
+ skip('pgrep is required to determine possible pids') unless $CHILD_STATUS.success?
98
+ pids = %x[pgrep -f beanstalk].split
99
+
100
+ stats = client.transmit('stats')[:body]
101
+ assert(pids.include?(stats['pid'].to_s), 'Expected pids for processes with beanstalk in title to include beanstalk pid')
102
+ end
103
+
104
+
105
+ should 'return correct count of current-connections and total-connections' do
106
+ stats = client.transmit('stats')[:body]
107
+ initial_current_connections = stats['current-connections']
108
+ initial_total_connections = stats['total-connections']
109
+ other_client = build_client
110
+ stats = client.transmit('stats')[:body]
111
+ assert_equal(initial_current_connections + 1, stats['current-connections'], 'Expected current-connections to be incremented')
112
+ assert_equal(initial_total_connections + 1, stats['total-connections'], 'Expected total-connections to be incremented')
113
+ other_client.close
114
+ assert_equal(stats['current-connections'] - 1, client.transmit('stats')[:body]['current-connections'], 'Expected current-connections to be decremented')
115
+ end
116
+
117
+
118
+ should 'return BAD_FORMAT with any trailing characters' do
119
+ initial_cmd_stats = client.transmit('stats')[:body]['cmd-stats']
120
+ [' ', ' foo'].each do |trailer|
121
+ assert_raises(Beaneater::BadFormatError, 'Expected stats with any trailing characters to return BAD_FORMAT') do
122
+ client.transmit("stats#{trailer}")
123
+ end
124
+ end
125
+ assert_equal(initial_cmd_stats + 1, client.transmit('stats')[:body]['cmd-stats'], 'Expected cmd-stats to be unchanged')
126
+ end
127
+
128
+ end
129
+
130
+ end
@@ -0,0 +1,141 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+
3
+ class StatsTubeTest < BeanstalkIntegrationTest
4
+
5
+ context 'stats-tube' do
6
+
7
+ setup do
8
+ client.transmit("use #{tube_name}")
9
+ end
10
+
11
+
12
+ should 'return stats for the specified tube with all expected keys' do
13
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
14
+ response = client.transmit("stats-tube #{tube_name}")
15
+ assert_equal 'OK', response[:status]
16
+ tube_stats = response[:body]
17
+ expected_keys = %w[
18
+ name current-jobs-urgent current-jobs-ready current-jobs-reserved current-jobs-delayed
19
+ current-jobs-buried total-jobs current-using current-watching current-waiting cmd-delete
20
+ cmd-pause-tube pause pause-time-left
21
+ ]
22
+ assert_equal expected_keys, tube_stats.keys
23
+ assert_nil tube_stats.values.compact!, 'Expected tube stats to have no nil values'
24
+ assert_equal(initial_cmd_stats_tube + 1, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be incremented')
25
+ end
26
+
27
+
28
+ # Some stats are tested elsewhere:
29
+ #
30
+ # :name => See below
31
+ # :current-jobs-urgent => PutTest, ReleaseTest
32
+ # :current-jobs-ready => PutTest, ReleaseTest
33
+ # :current-jobs-reserved => ReserveTest, ReleaseTest
34
+ # :current-jobs-delayed => KickTest, PutTest, ReleaseTest
35
+ # :current-jobs-buried => BuryTest, KickTest
36
+ # :total-jobs => PutTest
37
+ # :current-using => UseTest
38
+ # :current-waiting => ReserveTest
39
+ # :current-watching => IgnoreTest, UseTest, WatchTest
40
+ # :pause => PauseTubeTest
41
+ # :cmd-delete => DeleteTest
42
+ # :cmd-pause-tube => PauseTubeTest
43
+ # :pause-time-left => PauseTubeTest
44
+ #
45
+ # For those that aren't...
46
+
47
+
48
+ should 'return expected tube name' do
49
+ assert_equal(tube_name, client.transmit("stats-tube #{tube_name}")[:body]['name'], 'Expected stats-tube to return correct tube name')
50
+ end
51
+
52
+
53
+ should 'return NOT_FOUND if the tube has never existed' do
54
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
55
+ assert_raises(Beaneater::NotFoundError, 'Expected tube-stats for non-existent tube to return NOT_FOUND') do
56
+ client.transmit("stats-tube #{uuid}")
57
+ end
58
+ assert_equal(initial_cmd_stats_tube + 1, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be incremented')
59
+ end
60
+
61
+
62
+ should 'return NOT_FOUND if the tube is deleted' do
63
+ client.transmit('use default')
64
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
65
+ assert_raises(Beaneater::NotFoundError, 'Expected tube-stats for deleted tube to return NOT_FOUND') do
66
+ client.transmit("stats-tube #{tube_name}")
67
+ end
68
+ assert_equal(initial_cmd_stats_tube + 1, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be incremented')
69
+ end
70
+
71
+
72
+ should 'return BAD_FORMAT without trailing space' do
73
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
74
+ assert_raises(Beaneater::BadFormatError, 'Expected tube-stats without space to return BAD_FORMAT') do
75
+ client.transmit('stats-tube')
76
+ end
77
+ assert_equal(initial_cmd_stats_tube, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
78
+ end
79
+
80
+
81
+ should 'return BAD_FORMAT if tube name is null' do
82
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
83
+ assert_raises(Beaneater::BadFormatError, 'Expected tube-stats with null tube name to return BAD_FORMAT') do
84
+ client.transmit('stats-tube ')
85
+ end
86
+ assert_equal(initial_cmd_stats_tube, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
87
+ end
88
+
89
+
90
+ should 'be able to handle tube name of maximum length' do
91
+ name = 'x' * 200
92
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
93
+ client.transmit("watch #{name}")
94
+ response = client.transmit("stats-tube #{name}")
95
+ assert_equal 'OK', response[:status]
96
+ assert_equal name, response[:body]['name']
97
+ assert_equal(initial_cmd_stats_tube + 1, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be incremented')
98
+ end
99
+
100
+
101
+ should 'return BAD_FORMAT if tube name > 200 bytes' do
102
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
103
+ assert_raises Beaneater::BadFormatError do
104
+ client.transmit("stats-tube #{'x' * 201}")
105
+ end
106
+ # Get stats with other client because long tube name leaves client in weird state
107
+ assert_equal(initial_cmd_stats_tube, build_client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
108
+ end
109
+
110
+
111
+ should 'return BAD_FORMAT if line has a trailing space' do
112
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
113
+ assert_raises Beaneater::BadFormatError do
114
+ client.transmit("stats-tube #{tube_name} ")
115
+ end
116
+ assert_equal(initial_cmd_stats_tube, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
117
+ end
118
+
119
+
120
+ should 'return BAD_FORMAT if tube name includes invalid characters or starts with hyphen' do
121
+ initial_cmd_stats_tube = client.transmit('stats')[:body]['cmd-stats-tube']
122
+ valid_chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + %w[- + / ; . $ _ ( )] + [' ']
123
+ # Beanstalk hangs on char 13
124
+ bad_chars = (0..12).to_a.concat((14..255).to_a).to_a.map!(&:chr) - valid_chars
125
+
126
+ assert_raises(Beaneater::BadFormatError, 'Expected tube name starting with hyphen to be invalid') do
127
+ client.transmit('stats-tube -starts-with-hyphen')
128
+ end
129
+ assert_equal(initial_cmd_stats_tube, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
130
+
131
+ bad_chars.each do |bad_char|
132
+ assert_raises(Beaneater::BadFormatError, "Expected tube name with char #{bad_char} to be invalid") do
133
+ client.transmit("stats-tube name_with_#{bad_char}_in_it")
134
+ end
135
+ end
136
+ assert_equal(initial_cmd_stats_tube, client.transmit('stats')[:body]['cmd-stats-tube'], 'Expected cmd-stats-tube to be unchanged')
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,88 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'minitest/autorun'
4
+ require 'minitest/should'
5
+
6
+ require 'securerandom'
7
+
8
+ require 'beaneater'
9
+
10
+
11
+ class BeanstalkIntegrationTest < MiniTest::Should::TestCase
12
+
13
+ class << self
14
+
15
+ def address(custom_address = '0.0.0.0')
16
+ return @address ||= custom_address
17
+ end
18
+
19
+ end
20
+
21
+ setup do
22
+ puts "#{self.class}::#{self.__name__}" if ENV['VERBOSE']
23
+ end
24
+
25
+ teardown do
26
+ cleanup_tubes
27
+ @clients.each do |client|
28
+ client.close unless client.connection.nil?
29
+ end
30
+ end
31
+
32
+ def address
33
+ return self.class.address
34
+ end
35
+
36
+ def build_client
37
+ new_client = Beaneater::Connection.new(address)
38
+ @clients << new_client
39
+ return new_client
40
+ end
41
+
42
+ def cleanup_tubes
43
+ @pool = Beaneater::Pool.new([address])
44
+ @tubes.each do |tube_name|
45
+ @pool.tubes.find(tube_name).clear
46
+ end
47
+ @pool.close
48
+ @tubes.clear
49
+ end
50
+
51
+ def client
52
+ @client ||= build_client
53
+ end
54
+
55
+ def create_buried_jobs(buried_count = 5)
56
+ job_ids = []
57
+ buried_count.times do
58
+ message = uuid
59
+ client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")
60
+ timeout(1) do
61
+ job_ids << client.transmit('reserve')[:id]
62
+ end
63
+ client.transmit("bury #{job_ids.last} 0")
64
+ end
65
+ return job_ids
66
+ end
67
+
68
+ def initialize(*)
69
+ @tubes = []
70
+ @clients = []
71
+ super
72
+ end
73
+
74
+ def generate_tube_name
75
+ tube = uuid
76
+ @tubes << tube
77
+ return tube
78
+ end
79
+
80
+ def tube_name
81
+ return @tube_name ||= generate_tube_name
82
+ end
83
+
84
+ def uuid
85
+ SecureRandom.uuid
86
+ end
87
+
88
+ end