kafkat 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTY0MTdhYjQ3YjAzNWExNWJjMzMyYThmOTY5ZWQ5NmQyOTcyMGM4Yw==
4
+ NjhlMGY5MzIyYWFhZjdlZmE3YjlmM2M3MTc3MGU0MjQyYzQ2YjA5Zg==
5
5
  data.tar.gz: !binary |-
6
- MTkzM2UzODgxNTIzMmJiYTAwNDQ2NmI5ZmVjYWZkYTdiYjNkZDk4Ng==
6
+ NDNlMjdjNDAxMjc4NTcyZDE2YzliNjI5OTBkNmJkMDA2OGM3Yjc0Zg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- N2U0ZTMyMjQ4MmI3M2QzMDkyNTM4ZWFjOWJmMTNhNmIxNjlkM2NjMzBkYTli
10
- YmY3N2Y1ZTk5OWIwZjZlZjZhMzNjOGE2MmE4NDg2ZTc4NzFjYTYzZmZlZWNi
11
- YzFmNzFjZGU5N2Y5Y2UyMGY5NDhiNmEyZWU5NjdiNzViMjVlNjU=
9
+ MDdkOWI2ZjBhNjU2ZWM3NmI5YTMwNTFjYTA3MjQ5NjJiNDVjOTFiMGRkMDMw
10
+ ZmNkNThiNGJhYzYyNjIwYzczOTY0MjNhY2ZlYzA1MTQ2Y2Y4YTQxZDcwNTVm
11
+ NWU4YjA0NGYzMDQ1Mjc3ZjBiMGUxMTllM2U0N2QwMDdkODYzOGQ=
12
12
  data.tar.gz: !binary |-
13
- YjRiMzllYmZjNDBiMmYxNjRiNzExMzlkZGM2ZWQwOTA0NmFiMGRkZTQzZjMz
14
- ZmRlMGM5OTczMTcwYzI4MmJiYmE1ZGYwMDZlNzhhMTI3ZmQ2YThkN2E4OTdj
15
- ZmUzN2QyZDMxNDk5ODE1ZWIwNTdjZmMyNWFkMTYzYWRjOWJmZWY=
13
+ MzU2ODcyZWFmY2VjMmFiM2NkMDMxNDRjNmQ4NGU5Y2JhOTE5MDczMzYzZGFj
14
+ MjhmOGE5MjVjNzViZWM3ZDJjMTkzZmZhZGYxMjI1Y2Q1NWEzMDU3ODc5MWUy
15
+ NzAyMTBlNmExN2E5M2U2MGM5YWZkY2FkNTkxZTAyMjY3NDE2ZTI=
data/.gitignore CHANGED
@@ -4,3 +4,4 @@
4
4
  *.iml
5
5
  *.ipr
6
6
 
7
+ reports
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.simplecov ADDED
@@ -0,0 +1,5 @@
1
+ if ENV['COVERAGE']
2
+ SimpleCov.start do
3
+ coverage_dir("reports/coverage")
4
+ end
5
+ end
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ script:
5
+ - bundle exec rake
6
+ rvm:
7
+ - 1.9.3
8
+ - 2.0.0
9
+ - 2.1.6
10
+ - 2.2.2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kafkat (0.0.10)
4
+ kafkat (0.0.11)
5
5
  colored (~> 1.2)
6
6
  highline (~> 1.6, >= 1.6.21)
7
7
  retryable (~> 1.3, >= 1.3.5)
@@ -11,22 +11,59 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
+ activesupport (4.2.1)
15
+ i18n (~> 0.7)
16
+ json (~> 1.7, >= 1.7.7)
17
+ minitest (~> 5.1)
18
+ thread_safe (~> 0.3, >= 0.3.4)
19
+ tzinfo (~> 1.1)
14
20
  colored (1.2)
15
- highline (1.6.21)
16
- little-plugger (1.1.3)
17
- logging (1.8.2)
18
- little-plugger (>= 1.1.3)
19
- multi_json (>= 1.8.4)
20
- multi_json (1.10.1)
21
- retryable (1.3.5)
22
- trollop (2.0)
23
- zk (1.9.4)
24
- logging (~> 1.8.2)
21
+ diff-lcs (1.2.5)
22
+ docile (1.1.5)
23
+ factory_girl (4.5.0)
24
+ activesupport (>= 3.0.0)
25
+ highline (1.7.2)
26
+ i18n (0.7.0)
27
+ json (1.8.3)
28
+ minitest (5.7.0)
29
+ multi_json (1.11.1)
30
+ rake (10.4.2)
31
+ retryable (1.3.6)
32
+ rspec (3.2.0)
33
+ rspec-core (~> 3.2.0)
34
+ rspec-expectations (~> 3.2.0)
35
+ rspec-mocks (~> 3.2.0)
36
+ rspec-collection_matchers (1.1.2)
37
+ rspec-expectations (>= 2.99.0.beta1)
38
+ rspec-core (3.2.3)
39
+ rspec-support (~> 3.2.0)
40
+ rspec-expectations (3.2.1)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.2.0)
43
+ rspec-mocks (3.2.1)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.2.0)
46
+ rspec-support (3.2.2)
47
+ simplecov (0.9.0)
48
+ docile (~> 1.1.0)
49
+ multi_json
50
+ simplecov-html (~> 0.8.0)
51
+ simplecov-html (0.8.0)
52
+ thread_safe (0.3.5)
53
+ trollop (2.1.2)
54
+ tzinfo (1.2.2)
55
+ thread_safe (~> 0.1)
56
+ zk (1.9.6)
25
57
  zookeeper (~> 1.4.0)
26
- zookeeper (1.4.9)
58
+ zookeeper (1.4.11)
27
59
 
28
60
  PLATFORMS
29
61
  ruby
30
62
 
31
63
  DEPENDENCIES
64
+ factory_girl (~> 4.5.0)
32
65
  kafkat!
66
+ rake
67
+ rspec (~> 3.2.0)
68
+ rspec-collection_matchers (~> 1.1.0)
69
+ simplecov
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/airbnb/kafkat.png?branch=master)](https://travis-ci.org/airbnb/kafkat)
2
+
1
3
  kafkat
2
4
  ======
3
5
 
@@ -52,6 +54,7 @@ Here's a list of supported commands:
52
54
  set-replication-factor [topic] [--newrf <n>] [--brokers id[,id]] Set the replication factor of
53
55
  shutdown <broker id> Gracefully remove leaderships from a broker (requires JMX).
54
56
  topics Print all topics.
57
+ drain <broker id> [--topic <t>] [--brokers <ids>] Reassign partitions from a specific broker to other brokers.
55
58
 
56
59
  ```
57
60
 
data/Rakefile CHANGED
@@ -1,8 +1,25 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
- task :default => :spec
3
+ require 'rake/clean'
4
4
 
5
- RSpec::Core::RakeTask.new(:spec) do |spec|
6
- spec.pattern = 'spec/**/*_spec.rb'
7
- spec.rspec_opts = ['-cfs --backtrace']
5
+
6
+ CLEAN << 'reports'
7
+ CLOBBER << FileList['kafkat*.gem']
8
+
9
+ desc 'Run all specs'
10
+ RSpec::Core::RakeTask.new :spec do |t|
11
+ t.pattern = ['spec/**/*_spec.rb']
12
+ t.rspec_opts = %w{--order random --format documentation --color --format html --out reports/specs.html}
13
+ t.rspec_opts << "--backtrace" if ENV['backtrace']
14
+ t.verbose = true
15
+ end
16
+
17
+
18
+ desc 'Run all specs and generate spec and coverage reports'
19
+ task :coverage do
20
+ ENV['COVERAGE'] = 'true'
21
+ Rake::Task['spec'].invoke
8
22
  end
23
+
24
+ task :test => :spec
25
+ task :default => :coverage
data/_kafkat ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Run kafkat from source, specifically for testing stuff without doing a rake install.
4
+
5
+ require 'rubygems'
6
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') << File.join(File.dirname(__FILE__), 'addon')
7
+
8
+ require 'kafkat/version'
9
+ spec = Gem::Specification.load(File.join(File.dirname(__FILE__), 'kafkat.gemspec'))
10
+
11
+ # To avoid a warning about the version_requirements deprecation, we use this method inline.
12
+ def version_required(gem_def)
13
+ return Gem::Dependency.instance_methods.map(&:to_sym).include?(:requirement) ? gem_def.requirement : gem_def.version_requirements
14
+ end
15
+ spec.dependencies.each do |dep|
16
+ gem dep.name, version_required(dep) if dep.type == :runtime
17
+ end
18
+ Gem.loaded_specs['kafkat'] = spec # Prevents RubyGem from loading files from installed kafkat gems
19
+
20
+ require 'kafkat'
21
+ Kafkat::CLI.run!
data/kafkat.gemspec CHANGED
@@ -23,4 +23,10 @@ Gem::Specification.new do |s|
23
23
  s.add_runtime_dependency 'highline', '~> 1.6', '>= 1.6.21'
24
24
  s.add_runtime_dependency 'retryable', '~> 1.3', '>= 1.3.5'
25
25
  s.add_runtime_dependency 'colored', '~> 1.2'
26
+
27
+ s.add_development_dependency 'rake'
28
+ s.add_development_dependency 'simplecov'
29
+ s.add_development_dependency 'rspec', '~> 3.2.0'
30
+ s.add_development_dependency 'rspec-collection_matchers', '~> 1.1.0'
31
+ s.add_development_dependency 'factory_girl', '~> 4.5.0'
26
32
  end
@@ -14,6 +14,7 @@ module Kafkat
14
14
 
15
15
  class Base
16
16
  include Formatting
17
+ include CommandIO
17
18
 
18
19
  attr_reader :config
19
20
 
@@ -0,0 +1,94 @@
1
+ module Kafkat
2
+ module Command
3
+ class Drain < Base
4
+ register_as 'drain'
5
+
6
+ usage 'drain <broker id> [--topic <t>] [--brokers <ids>]',
7
+ 'Reassign partitions from a specific broker to destination brokers.'
8
+
9
+ # For each partition (of speicified topic) on the source broker, the command is to
10
+ # assign the partition to one of the destination brokers that does not already have
11
+ # this partition, along with existing brokers to achieve minimal movement of data.
12
+ # To help distribute data evenly, if there are more than one destination brokers
13
+ # meet the requirement, the command will always choose the brokers with the lowest
14
+ # number of partitions of the involving topic.
15
+ #
16
+ # In order to find out the broker with lowest number of partitions, the command maintain
17
+ # a hash table with broker id as key and number of partitions as value. The hash table
18
+ # will be updated along with assignment.
19
+ def run
20
+ source_broker = ARGV[0] && ARGV.shift.to_i
21
+ if source_broker.nil?
22
+ puts "You must specify a broker ID."
23
+ exit 1
24
+ end
25
+
26
+ opts = Trollop.options do
27
+ opt :brokers, "destination broker IDs", type: :string
28
+ opt :topic, "topic name to reassign", type: :string
29
+ end
30
+
31
+ topic_name = opts[:topic]
32
+ topics = topic_name && zookeeper.get_topics([topic_name])
33
+ topics ||= zookeeper.get_topics
34
+
35
+ destination_brokers = opts[:brokers] && opts[:brokers].split(',').map(&:to_i)
36
+ destination_brokers ||= zookeeper.get_brokers.values.map(&:id)
37
+ destination_brokers.delete(source_broker)
38
+
39
+ active_brokers = zookeeper.get_brokers.values.map(&:id)
40
+
41
+ unless (inactive_brokers = destination_brokers - active_brokers).empty?
42
+ print "ERROR: Broker #{inactive_brokers} are not currently active.\n"
43
+ exit 1
44
+ end
45
+
46
+ assignments =
47
+ generate_assignments(source_broker, topics, destination_brokers)
48
+ prompt_and_execute_assignments(assignments)
49
+ end
50
+
51
+ def generate_assignments(source_broker, topics, destination_brokers)
52
+
53
+ assignments = []
54
+ topics.each do |_, t|
55
+ partitions_by_broker = build_partitions_by_broker(t, destination_brokers)
56
+
57
+ t.partitions.each do |p|
58
+ if p.replicas.include? source_broker
59
+ replicas = p.replicas - [source_broker]
60
+ potential_broker_ids = destination_brokers - replicas
61
+ if potential_broker_ids.empty?
62
+ print "ERROR: Not enough destination brokers to reassign topic \"#{t.name}\".\n"
63
+ exit 1
64
+ end
65
+
66
+ num_partitions_on_potential_broker =
67
+ partitions_by_broker.select { |id, _| potential_broker_ids.include? id }
68
+ assigned_broker_id = num_partitions_on_potential_broker.min_by{ |id, num| num }[0]
69
+ replicas << assigned_broker_id
70
+ partitions_by_broker[assigned_broker_id] += 1
71
+
72
+ assignments << Assignment.new(t.name, p.id, replicas)
73
+ end
74
+ end
75
+ end
76
+
77
+ assignments
78
+ end
79
+
80
+ # Build a hash map from broker id to number of partitions on it to facilitate
81
+ # finding the broker with lowest number of partitions to help balance brokers.
82
+ def build_partitions_by_broker(topic, destination_brokers)
83
+ partitions_by_broker = Hash.new(0)
84
+ destination_brokers.each { |id| partitions_by_broker[id] = 0 }
85
+ topic.partitions.each do |p|
86
+ p.replicas.each do |r|
87
+ partitions_by_broker[r] += 1
88
+ end
89
+ end
90
+ partitions_by_broker
91
+ end
92
+ end
93
+ end
94
+ end
@@ -68,21 +68,7 @@ module Kafkat
68
68
 
69
69
  # ****************
70
70
 
71
- print "This operation executes the following assignments:\n\n"
72
- print_assignment_header
73
- assignments.each { |a| print_assignment(a) }
74
- print "\n"
75
-
76
- return unless agree("Proceed (y/n)?")
77
-
78
- result = nil
79
- begin
80
- print "\nBeginning.\n"
81
- result = admin.reassign!(assignments)
82
- print "Started.\n"
83
- rescue Interface::Admin::ExecutionFailedError
84
- print result
85
- end
71
+ prompt_and_execute_assignments(assignments)
86
72
  end
87
73
  end
88
74
  end
@@ -1 +1,2 @@
1
1
  require 'kafkat/utility/formatting'
2
+ require 'kafkat/utility/command_io'
@@ -0,0 +1,21 @@
1
+ module Kafkat
2
+ module CommandIO
3
+ def prompt_and_execute_assignments(assignments)
4
+ print "This operation executes the following assignments:\n\n"
5
+ print_assignment_header
6
+ assignments.each { |a| print_assignment(a) }
7
+ print "\n"
8
+
9
+ return unless agree("Proceed (y/n)?")
10
+
11
+ result = nil
12
+ begin
13
+ print "\nBeginning.\n"
14
+ result = admin.reassign!(assignments)
15
+ print "Started.\n"
16
+ rescue Interface::Admin::ExecutionFailedError
17
+ print result
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Kafkat
2
- VERSION = '0.0.10'
2
+ VERSION = '0.0.11'
3
3
  end
@@ -0,0 +1,39 @@
1
+ module Kafkat
2
+ FactoryGirl.define do
3
+ factory :topic, class:Topic do
4
+ name "topic_name"
5
+
6
+ factory :topic_with_one_empty_broker do
7
+ partitions {[Partition.new(name, 0, [0], 0, 0),
8
+ Partition.new(name, 1, [1], 1, 1),
9
+ Partition.new(name, 2, [0], 0, 0),
10
+ Partition.new(name, 3, [0], 0, 0),
11
+ Partition.new(name, 4, [1], 1, 1)]}
12
+ end
13
+
14
+ factory :topic_rep_factor_one do
15
+ partitions {[Partition.new(name, 0, [0], 0, 0),
16
+ Partition.new(name, 1, [1], 1, 1),
17
+ Partition.new(name, 2, [2], 2, 2),
18
+ Partition.new(name, 3, [0], 0, 0),
19
+ Partition.new(name, 4, [1], 1, 1)]}
20
+ end
21
+
22
+ factory :topic_rep_factor_two do
23
+ partitions {[Partition.new(name, 0, [0, 1], 0, 0),
24
+ Partition.new(name, 1, [0, 2], 2, 2),
25
+ Partition.new(name, 2, [1, 2], 1, 1),
26
+ Partition.new(name, 3, [0, 1], 0, 0),
27
+ Partition.new(name, 4, [0, 2], 2, 2)]}
28
+ end
29
+
30
+ factory :topic_rep_factor_three do
31
+ partitions {[Partition.new(name, 0, [0, 1, 2], 0, 0),
32
+ Partition.new(name, 1, [0, 1, 2], 1, 1),
33
+ Partition.new(name, 2, [0, 1, 2], 2, 2),
34
+ Partition.new(name, 3, [0, 1, 2], 0, 0),
35
+ Partition.new(name, 4, [0, 1, 2], 1, 1)]}
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ module Kafkat
4
+ RSpec.describe Command::Drain do
5
+ let(:drain) { Command::Drain.new({}) }
6
+ let(:broker_id) { 0 }
7
+ let(:destination_broker_ids) { [1, 2] }
8
+
9
+ context 'three nodes with replication factor 1' do
10
+ let(:topic_rep_factor_one) { FactoryGirl.build(:topic_rep_factor_one) }
11
+
12
+ it 'should put replicas to broker with lowest number of replicas' do
13
+ assignments = drain.generate_assignments(broker_id,
14
+ {"topic_name" => topic_rep_factor_one},
15
+ destination_broker_ids)
16
+ expect(assignments).to have_exactly(2).Partition
17
+ expect(assignments[0].replicas).to eq([2])
18
+ expect(assignments[1].replicas).to eq([1])
19
+ end
20
+ end
21
+
22
+ context 'three nodes with replication factor 2' do
23
+ let(:topic_rep_factor_two) { FactoryGirl.build(:topic_rep_factor_two) }
24
+ it 'should put replicas to broker with lowest number of replicas' do
25
+ assignments = drain.generate_assignments(broker_id,
26
+ {"topic_name" => topic_rep_factor_two},
27
+ destination_broker_ids)
28
+ expect(assignments).to have_exactly(4).Partition
29
+ expect(assignments[0].replicas).to eq([1, 2])
30
+ expect(assignments[1].replicas).to eq([2, 1])
31
+ expect(assignments[2].replicas).to eq([1, 2])
32
+ expect(assignments[3].replicas).to eq([2, 1])
33
+ end
34
+ end
35
+
36
+ context 'not enough brokers to keep all replicas' do
37
+ let(:topic_rep_factor_three) { FactoryGirl.build(:topic_rep_factor_three) }
38
+
39
+ it 'should raise SystemExit' do
40
+ expect do
41
+ drain.generate_assignments(broker_id,
42
+ {"topic_name" => topic_rep_factor_three},
43
+ destination_broker_ids)
44
+ end.to raise_error(SystemExit)
45
+ end
46
+ end
47
+
48
+ context 'one destination broker is empty' do
49
+ let(:topic_with_one_empty_broker) { FactoryGirl.build(:topic_with_one_empty_broker) }
50
+ it 'should not raise exception' do
51
+ expect do
52
+ drain.generate_assignments(broker_id,
53
+ {"topic_name" => topic_with_one_empty_broker},
54
+ destination_broker_ids)
55
+ end.not_to raise_error
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,102 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ if ENV['COVERAGE']
20
+ require 'simplecov'
21
+ end
22
+ require 'kafkat'
23
+ require 'factory_girl'
24
+ require 'rspec/collection_matchers'
25
+
26
+ require_relative '../spec/factories/topic'
27
+
28
+ RSpec.configure do |config|
29
+ # rspec-expectations config goes here. You can use an alternate
30
+ # assertion/expectation library such as wrong or the stdlib/minitest
31
+ # assertions if you prefer.
32
+ config.expect_with :rspec do |expectations|
33
+ # This option will default to `true` in RSpec 4. It makes the `description`
34
+ # and `failure_message` of custom matchers include text for helper methods
35
+ # defined using `chain`, e.g.:
36
+ # be_bigger_than(2).and_smaller_than(4).description
37
+ # # => "be bigger than 2 and smaller than 4"
38
+ # ...rather than:
39
+ # # => "be bigger than 2"
40
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
41
+ end
42
+
43
+ # rspec-mocks config goes here. You can use an alternate test double
44
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
45
+ config.mock_with :rspec do |mocks|
46
+ # Prevents you from mocking or stubbing a method that does not exist on
47
+ # a real object. This is generally recommended, and will default to
48
+ # `true` in RSpec 4.
49
+ mocks.verify_partial_doubles = true
50
+ end
51
+
52
+ config.include FactoryGirl::Syntax::Methods
53
+
54
+ # The settings below are suggested to provide a good initial experience
55
+ # with RSpec, but feel free to customize to your heart's content.
56
+ =begin
57
+ # These two settings work together to allow you to limit a spec run
58
+ # to individual examples or groups you care about by tagging them with
59
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
60
+ # get run.
61
+ config.filter_run :focus
62
+ config.run_all_when_everything_filtered = true
63
+
64
+ # Limits the available syntax to the non-monkey patched syntax that is
65
+ # recommended. For more details, see:
66
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
67
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
68
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
69
+ config.disable_monkey_patching!
70
+
71
+ # This setting enables warnings. It's recommended, but in some cases may
72
+ # be too noisy due to issues in dependencies.
73
+ config.warnings = true
74
+
75
+ # Many RSpec users commonly either run the entire suite or an individual
76
+ # file, and it's useful to allow more verbose output when running an
77
+ # individual spec file.
78
+ if config.files_to_run.one?
79
+ # Use the documentation formatter for detailed output,
80
+ # unless a formatter has already been configured
81
+ # (e.g. via a command-line flag).
82
+ config.default_formatter = 'doc'
83
+ end
84
+
85
+ # Print the 10 slowest examples and example groups at the
86
+ # end of the spec run, to help surface which specs are running
87
+ # particularly slow.
88
+ config.profile_examples = 10
89
+
90
+ # Run specs in random order to surface order dependencies. If you find an
91
+ # order dependency and want to debug it, you can fix the order by providing
92
+ # the seed, which is printed after each run.
93
+ # --seed 1234
94
+ config.order = :random
95
+
96
+ # Seed global randomization in this process using the `--seed` CLI option.
97
+ # Setting this allows you to use `--seed` to deterministically reproduce
98
+ # test failures related to randomization by passing the same `--seed` value
99
+ # as the one that triggered the failure.
100
+ Kernel.srand config.seed
101
+ =end
102
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kafkat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nelson Gauthier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-01 00:00:00.000000000 Z
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zk
@@ -98,6 +98,76 @@ dependencies:
98
98
  - - ~>
99
99
  - !ruby/object:Gem::Version
100
100
  version: '1.2'
101
+ - !ruby/object:Gem::Dependency
102
+ name: rake
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ - !ruby/object:Gem::Dependency
116
+ name: simplecov
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ - !ruby/object:Gem::Dependency
130
+ name: rspec
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ~>
134
+ - !ruby/object:Gem::Version
135
+ version: 3.2.0
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 3.2.0
143
+ - !ruby/object:Gem::Dependency
144
+ name: rspec-collection_matchers
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 1.1.0
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ~>
155
+ - !ruby/object:Gem::Version
156
+ version: 1.1.0
157
+ - !ruby/object:Gem::Dependency
158
+ name: factory_girl
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ~>
162
+ - !ruby/object:Gem::Version
163
+ version: 4.5.0
164
+ type: :development
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ~>
169
+ - !ruby/object:Gem::Version
170
+ version: 4.5.0
101
171
  description: Simplified command-line administration for Kafka brokers
102
172
  email:
103
173
  - nelson@airbnb.com
@@ -107,11 +177,15 @@ extensions: []
107
177
  extra_rdoc_files: []
108
178
  files:
109
179
  - .gitignore
180
+ - .rspec
181
+ - .simplecov
182
+ - .travis.yml
110
183
  - Gemfile
111
184
  - Gemfile.lock
112
185
  - LICENSE.txt
113
186
  - README.md
114
187
  - Rakefile
188
+ - _kafkat
115
189
  - bin/kafkat
116
190
  - kafkat.gemspec
117
191
  - lib/kafkat.rb
@@ -125,6 +199,7 @@ files:
125
199
  - lib/kafkat/command/brokers.rb
126
200
  - lib/kafkat/command/clean-indexes.rb
127
201
  - lib/kafkat/command/controller.rb
202
+ - lib/kafkat/command/drain.rb
128
203
  - lib/kafkat/command/elect-leaders.rb
129
204
  - lib/kafkat/command/partitions.rb
130
205
  - lib/kafkat/command/reassign.rb
@@ -138,8 +213,12 @@ files:
138
213
  - lib/kafkat/interface/kafka_logs.rb
139
214
  - lib/kafkat/interface/zookeeper.rb
140
215
  - lib/kafkat/utility.rb
216
+ - lib/kafkat/utility/command_io.rb
141
217
  - lib/kafkat/utility/formatting.rb
142
218
  - lib/kafkat/version.rb
219
+ - spec/factories/topic.rb
220
+ - spec/lib/kafkat/command/drain_spec.rb
221
+ - spec/spec_helper.rb
143
222
  homepage: https://github.com/airbnb/kafkat
144
223
  licenses:
145
224
  - Apache-v2
@@ -164,4 +243,7 @@ rubygems_version: 2.4.1
164
243
  signing_key:
165
244
  specification_version: 4
166
245
  summary: Simplified command-line administration for Kafka brokers
167
- test_files: []
246
+ test_files:
247
+ - spec/factories/topic.rb
248
+ - spec/lib/kafkat/command/drain_spec.rb
249
+ - spec/spec_helper.rb