lhm 1.2.0 → 2.2.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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +256 -0
  4. data/.travis.yml +5 -1
  5. data/CHANGELOG.md +26 -0
  6. data/README.md +87 -8
  7. data/Rakefile +6 -4
  8. data/bin/lhm-config.sh +7 -0
  9. data/bin/lhm-kill-queue +13 -15
  10. data/bin/lhm-spec-clobber.sh +5 -4
  11. data/bin/lhm-spec-grants.sh +2 -2
  12. data/bin/lhm-spec-setup-cluster.sh +2 -3
  13. data/gemfiles/ar-2.3_mysql.gemfile +2 -1
  14. data/gemfiles/ar-3.2_mysql.gemfile +1 -1
  15. data/gemfiles/ar-3.2_mysql2.gemfile +1 -1
  16. data/gemfiles/dm_mysql.gemfile +1 -1
  17. data/lhm.gemspec +7 -8
  18. data/lib/lhm/atomic_switcher.rb +2 -1
  19. data/lib/lhm/chunker.rb +51 -39
  20. data/lib/lhm/command.rb +4 -2
  21. data/lib/lhm/connection.rb +14 -2
  22. data/lib/lhm/entangler.rb +5 -5
  23. data/lib/lhm/intersection.rb +29 -16
  24. data/lib/lhm/invoker.rb +31 -10
  25. data/lib/lhm/locked_switcher.rb +6 -6
  26. data/lib/lhm/migration.rb +7 -5
  27. data/lib/lhm/migrator.rb +57 -9
  28. data/lib/lhm/printer.rb +54 -0
  29. data/lib/lhm/sql_helper.rb +4 -4
  30. data/lib/lhm/table.rb +12 -12
  31. data/lib/lhm/throttler/time.rb +29 -0
  32. data/lib/lhm/throttler.rb +32 -0
  33. data/lib/lhm/version.rb +1 -1
  34. data/lib/lhm.rb +71 -6
  35. data/spec/.lhm.example +1 -1
  36. data/spec/README.md +20 -13
  37. data/spec/fixtures/lines.ddl +7 -0
  38. data/spec/fixtures/permissions.ddl +5 -0
  39. data/spec/fixtures/tracks.ddl +5 -0
  40. data/spec/fixtures/users.ddl +4 -2
  41. data/spec/integration/atomic_switcher_spec.rb +7 -7
  42. data/spec/integration/chunker_spec.rb +11 -5
  43. data/spec/integration/cleanup_spec.rb +72 -0
  44. data/spec/integration/entangler_spec.rb +11 -11
  45. data/spec/integration/integration_helper.rb +49 -17
  46. data/spec/integration/lhm_spec.rb +157 -37
  47. data/spec/integration/locked_switcher_spec.rb +7 -7
  48. data/spec/integration/table_spec.rb +15 -17
  49. data/spec/test_helper.rb +28 -0
  50. data/spec/unit/atomic_switcher_spec.rb +6 -6
  51. data/spec/unit/chunker_spec.rb +95 -73
  52. data/spec/unit/datamapper_connection_spec.rb +1 -0
  53. data/spec/unit/entangler_spec.rb +19 -19
  54. data/spec/unit/intersection_spec.rb +27 -15
  55. data/spec/unit/lhm_spec.rb +29 -0
  56. data/spec/unit/locked_switcher_spec.rb +14 -14
  57. data/spec/unit/migration_spec.rb +10 -5
  58. data/spec/unit/migrator_spec.rb +53 -41
  59. data/spec/unit/printer_spec.rb +79 -0
  60. data/spec/unit/sql_helper_spec.rb +10 -10
  61. data/spec/unit/table_spec.rb +11 -11
  62. data/spec/unit/throttler_spec.rb +73 -0
  63. data/spec/unit/unit_helper.rb +1 -13
  64. metadata +63 -24
  65. data/spec/bootstrap.rb +0 -13
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/unit_helper'
2
+
3
+ require 'lhm/printer'
4
+
5
+ describe Lhm::Printer do
6
+ include UnitHelper
7
+
8
+ describe 'percentage printer' do
9
+
10
+ before(:each) do
11
+ @printer = Lhm::Printer::Percentage.new
12
+ end
13
+
14
+ it 'prints the percentage' do
15
+ mock = MiniTest::Mock.new
16
+ 10.times do |i|
17
+ mock.expect(:write, :return_value) do |message|
18
+ assert_match /^\r/, message.first
19
+ assert_match /#{i}\/10/, message.first
20
+ end
21
+ end
22
+
23
+ @printer.instance_variable_set(:@output, mock)
24
+ 10.times { |i| @printer.notify(i, 10) }
25
+ mock.verify
26
+ end
27
+
28
+ it 'always print a bigger message' do
29
+ @length = 0
30
+ mock = MiniTest::Mock.new
31
+ 3.times do |i|
32
+ mock.expect(:write, :return_value) do |message|
33
+ assert message.first.length >= @length
34
+ @length = message.first.length
35
+ end
36
+ end
37
+
38
+ @printer.instance_variable_set(:@output, mock)
39
+ @printer.notify(10, 100)
40
+ @printer.notify(0, 100)
41
+ @printer.notify(1, 1000000)
42
+ @printer.notify(0, 0)
43
+ @printer.notify(0, nil)
44
+
45
+ mock.verify
46
+ end
47
+
48
+ it 'prints the end message' do
49
+ mock = MiniTest::Mock.new
50
+ mock.expect(:write, :return_value, [String])
51
+ mock.expect(:write, :return_value, ["\n"])
52
+
53
+ @printer.instance_variable_set(:@output, mock)
54
+ @printer.end
55
+
56
+ mock.verify
57
+ end
58
+ end
59
+
60
+ describe 'dot printer' do
61
+
62
+ before(:each) do
63
+ @printer = Lhm::Printer::Dot.new
64
+ end
65
+
66
+ it 'prints the dots' do
67
+ mock = MiniTest::Mock.new
68
+ 10.times do
69
+ mock.expect(:write, :return_value, ['.'])
70
+ end
71
+
72
+ @printer.instance_variable_set(:@output, mock)
73
+ 10.times { @printer.notify }
74
+
75
+ mock.verify
76
+ end
77
+
78
+ end
79
+ end
@@ -6,27 +6,27 @@ require File.expand_path(File.dirname(__FILE__)) + '/unit_helper'
6
6
  require 'lhm/sql_helper'
7
7
 
8
8
  describe Lhm::SqlHelper do
9
- it "should name index with a single column" do
9
+ it 'should name index with a single column' do
10
10
  Lhm::SqlHelper.
11
11
  idx_name(:users, :name).
12
- must_equal("index_users_on_name")
12
+ must_equal('index_users_on_name')
13
13
  end
14
14
 
15
- it "should name index with multiple columns" do
15
+ it 'should name index with multiple columns' do
16
16
  Lhm::SqlHelper.
17
17
  idx_name(:users, [:name, :firstname]).
18
- must_equal("index_users_on_name_and_firstname")
18
+ must_equal('index_users_on_name_and_firstname')
19
19
  end
20
20
 
21
- it "should name index with prefixed column" do
21
+ it 'should name index with prefixed column' do
22
22
  Lhm::SqlHelper.
23
- idx_name(:tracks, ["title(10)", "album"]).
24
- must_equal("index_tracks_on_title_and_album")
23
+ idx_name(:tracks, ['title(10)', 'album']).
24
+ must_equal('index_tracks_on_title_and_album')
25
25
  end
26
26
 
27
- it "should quote column names in index specification" do
27
+ it 'should quote column names in index specification' do
28
28
  Lhm::SqlHelper.
29
- idx_spec(["title(10)", "album"]).
30
- must_equal("`title`(10), `album`")
29
+ idx_spec(['title(10)', 'album']).
30
+ must_equal('`title`(10), `album`')
31
31
  end
32
32
  end
@@ -8,26 +8,26 @@ require 'lhm/table'
8
8
  describe Lhm::Table do
9
9
  include UnitHelper
10
10
 
11
- describe "names" do
12
- it "should name destination" do
13
- @table = Lhm::Table.new("users")
14
- @table.destination_name.must_equal "lhmn_users"
11
+ describe 'names' do
12
+ it 'should name destination' do
13
+ @table = Lhm::Table.new('users')
14
+ @table.destination_name.must_equal 'lhmn_users'
15
15
  end
16
16
  end
17
17
 
18
- describe "constraints" do
19
- it "should be satisfied with a single column primary key called id" do
20
- @table = Lhm::Table.new("table", "id")
18
+ describe 'constraints' do
19
+ it 'should be satisfied with a single column primary key called id' do
20
+ @table = Lhm::Table.new('table', 'id')
21
21
  @table.satisfies_primary_key?.must_equal true
22
22
  end
23
23
 
24
- it "should not be satisfied with a primary key unless called id" do
25
- @table = Lhm::Table.new("table", "uuid")
24
+ it 'should not be satisfied with a primary key unless called id' do
25
+ @table = Lhm::Table.new('table', 'uuid')
26
26
  @table.satisfies_primary_key?.must_equal false
27
27
  end
28
28
 
29
- it "should not be satisfied with multicolumn primary key" do
30
- @table = Lhm::Table.new("table", ["id", "secondary"])
29
+ it 'should not be satisfied with multicolumn primary key' do
30
+ @table = Lhm::Table.new('table', ['id', 'secondary'])
31
31
  @table.satisfies_primary_key?.must_equal false
32
32
  end
33
33
  end
@@ -0,0 +1,73 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/unit_helper'
2
+
3
+ require 'lhm/throttler'
4
+
5
+ describe Lhm::Throttler do
6
+ include UnitHelper
7
+
8
+ before :each do
9
+ @mock = Class.new do
10
+ extend Lhm::Throttler
11
+ end
12
+ end
13
+
14
+ describe '#setup_throttler' do
15
+ describe 'when passing a key' do
16
+ before do
17
+ @mock.setup_throttler(:time_throttler, :delay => 2)
18
+ end
19
+
20
+ it 'instantiates the time throttle' do
21
+ @mock.throttler.class.must_equal Lhm::Throttler::Time
22
+ end
23
+
24
+ it 'returns 2 seconds as time' do
25
+ @mock.throttler.timeout_seconds.must_equal 2
26
+ end
27
+ end
28
+
29
+ describe 'when passing an instance' do
30
+
31
+ before do
32
+ @instance = Class.new(Lhm::Throttler::Time) do
33
+ def timeout_seconds
34
+ 0
35
+ end
36
+ end.new
37
+
38
+ @mock.setup_throttler(@instance)
39
+ end
40
+
41
+ it 'returns the instace given' do
42
+ @mock.throttler.must_equal @instance
43
+ end
44
+
45
+ it 'returns 0 seconds as time' do
46
+ @mock.throttler.timeout_seconds.must_equal 0
47
+ end
48
+ end
49
+
50
+ describe 'when passing a class' do
51
+
52
+ before do
53
+ @klass = Class.new(Lhm::Throttler::Time)
54
+ @mock.setup_throttler(@klass)
55
+ end
56
+
57
+ it 'has the same class as given' do
58
+ @mock.throttler.class.must_equal @klass
59
+ end
60
+ end
61
+ end
62
+
63
+ describe '#throttler' do
64
+
65
+ it 'returns the default Time based' do
66
+ @mock.throttler.class.must_equal Lhm::Throttler::Time
67
+ end
68
+
69
+ it 'should default to 100 milliseconds' do
70
+ @mock.throttler.timeout_seconds.must_equal 0.1
71
+ end
72
+ end
73
+ end
@@ -1,18 +1,6 @@
1
1
  # Copyright (c) 2011 - 2013, SoundCloud Ltd., Rany Keddo, Tobias Bielohlawek, Tobias
2
2
  # Schmidt
3
-
4
- require File.expand_path(File.dirname(__FILE__)) + "/../bootstrap"
5
-
6
- begin
7
- require 'active_record'
8
- begin
9
- require 'mysql2'
10
- rescue LoadError
11
- require 'mysql'
12
- end
13
- rescue LoadError
14
- require 'dm-core'
15
- end
3
+ require 'test_helper'
16
4
 
17
5
  module UnitHelper
18
6
  def fixture(name)
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 2.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - SoundCloud
@@ -12,38 +11,34 @@ authors:
12
11
  autorequire:
13
12
  bindir: bin
14
13
  cert_chain: []
15
- date: 2013-02-22 00:00:00.000000000 Z
14
+ date: 2015-01-16 00:00:00.000000000 Z
16
15
  dependencies:
17
16
  - !ruby/object:Gem::Dependency
18
17
  name: minitest
19
18
  requirement: !ruby/object:Gem::Requirement
20
- none: false
21
19
  requirements:
22
- - - '='
20
+ - - "~>"
23
21
  - !ruby/object:Gem::Version
24
- version: 2.10.0
22
+ version: 5.0.8
25
23
  type: :development
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
- - - '='
27
+ - - "~>"
31
28
  - !ruby/object:Gem::Version
32
- version: 2.10.0
29
+ version: 5.0.8
33
30
  - !ruby/object:Gem::Dependency
34
31
  name: rake
35
32
  requirement: !ruby/object:Gem::Requirement
36
- none: false
37
33
  requirements:
38
- - - ! '>='
34
+ - - ">="
39
35
  - !ruby/object:Gem::Version
40
36
  version: '0'
41
37
  type: :development
42
38
  prerelease: false
43
39
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
40
  requirements:
46
- - - ! '>='
41
+ - - ">="
47
42
  - !ruby/object:Gem::Version
48
43
  version: '0'
49
44
  description: Migrate large tables without downtime by copying to a temporary table
@@ -55,12 +50,14 @@ executables:
55
50
  extensions: []
56
51
  extra_rdoc_files: []
57
52
  files:
58
- - .gitignore
59
- - .travis.yml
53
+ - ".gitignore"
54
+ - ".rubocop.yml"
55
+ - ".travis.yml"
60
56
  - CHANGELOG.md
61
57
  - LICENSE
62
58
  - README.md
63
59
  - Rakefile
60
+ - bin/lhm-config.sh
64
61
  - bin/lhm-kill-queue
65
62
  - bin/lhm-spec-clobber.sh
66
63
  - bin/lhm-spec-grants.sh
@@ -82,23 +79,30 @@ files:
82
79
  - lib/lhm/locked_switcher.rb
83
80
  - lib/lhm/migration.rb
84
81
  - lib/lhm/migrator.rb
82
+ - lib/lhm/printer.rb
85
83
  - lib/lhm/sql_helper.rb
86
84
  - lib/lhm/table.rb
85
+ - lib/lhm/throttler.rb
86
+ - lib/lhm/throttler/time.rb
87
87
  - lib/lhm/version.rb
88
88
  - spec/.lhm.example
89
89
  - spec/README.md
90
- - spec/bootstrap.rb
91
90
  - spec/fixtures/destination.ddl
91
+ - spec/fixtures/lines.ddl
92
92
  - spec/fixtures/origin.ddl
93
+ - spec/fixtures/permissions.ddl
93
94
  - spec/fixtures/small_table.ddl
95
+ - spec/fixtures/tracks.ddl
94
96
  - spec/fixtures/users.ddl
95
97
  - spec/integration/atomic_switcher_spec.rb
96
98
  - spec/integration/chunker_spec.rb
99
+ - spec/integration/cleanup_spec.rb
97
100
  - spec/integration/entangler_spec.rb
98
101
  - spec/integration/integration_helper.rb
99
102
  - spec/integration/lhm_spec.rb
100
103
  - spec/integration/locked_switcher_spec.rb
101
104
  - spec/integration/table_spec.rb
105
+ - spec/test_helper.rb
102
106
  - spec/unit/active_record_connection_spec.rb
103
107
  - spec/unit/atomic_switcher_spec.rb
104
108
  - spec/unit/chunker_spec.rb
@@ -106,34 +110,69 @@ files:
106
110
  - spec/unit/datamapper_connection_spec.rb
107
111
  - spec/unit/entangler_spec.rb
108
112
  - spec/unit/intersection_spec.rb
113
+ - spec/unit/lhm_spec.rb
109
114
  - spec/unit/locked_switcher_spec.rb
110
115
  - spec/unit/migration_spec.rb
111
116
  - spec/unit/migrator_spec.rb
117
+ - spec/unit/printer_spec.rb
112
118
  - spec/unit/sql_helper_spec.rb
113
119
  - spec/unit/table_spec.rb
120
+ - spec/unit/throttler_spec.rb
114
121
  - spec/unit/unit_helper.rb
115
- homepage: http://github.com/soundcloud/large-hadron-migrator
122
+ homepage: http://github.com/soundcloud/lhm
116
123
  licenses: []
124
+ metadata: {}
117
125
  post_install_message:
118
126
  rdoc_options: []
119
127
  require_paths:
120
128
  - lib
121
129
  required_ruby_version: !ruby/object:Gem::Requirement
122
- none: false
123
130
  requirements:
124
- - - ! '>='
131
+ - - ">="
125
132
  - !ruby/object:Gem::Version
126
133
  version: '0'
127
134
  required_rubygems_version: !ruby/object:Gem::Requirement
128
- none: false
129
135
  requirements:
130
- - - ! '>='
136
+ - - ">="
131
137
  - !ruby/object:Gem::Version
132
138
  version: '0'
133
139
  requirements: []
134
140
  rubyforge_project:
135
- rubygems_version: 1.8.24
141
+ rubygems_version: 2.2.2
136
142
  signing_key:
137
- specification_version: 3
143
+ specification_version: 4
138
144
  summary: online schema changer for mysql
139
- test_files: []
145
+ test_files:
146
+ - spec/README.md
147
+ - spec/fixtures/destination.ddl
148
+ - spec/fixtures/lines.ddl
149
+ - spec/fixtures/origin.ddl
150
+ - spec/fixtures/permissions.ddl
151
+ - spec/fixtures/small_table.ddl
152
+ - spec/fixtures/tracks.ddl
153
+ - spec/fixtures/users.ddl
154
+ - spec/integration/atomic_switcher_spec.rb
155
+ - spec/integration/chunker_spec.rb
156
+ - spec/integration/cleanup_spec.rb
157
+ - spec/integration/entangler_spec.rb
158
+ - spec/integration/integration_helper.rb
159
+ - spec/integration/lhm_spec.rb
160
+ - spec/integration/locked_switcher_spec.rb
161
+ - spec/integration/table_spec.rb
162
+ - spec/test_helper.rb
163
+ - spec/unit/active_record_connection_spec.rb
164
+ - spec/unit/atomic_switcher_spec.rb
165
+ - spec/unit/chunker_spec.rb
166
+ - spec/unit/connection_spec.rb
167
+ - spec/unit/datamapper_connection_spec.rb
168
+ - spec/unit/entangler_spec.rb
169
+ - spec/unit/intersection_spec.rb
170
+ - spec/unit/lhm_spec.rb
171
+ - spec/unit/locked_switcher_spec.rb
172
+ - spec/unit/migration_spec.rb
173
+ - spec/unit/migrator_spec.rb
174
+ - spec/unit/printer_spec.rb
175
+ - spec/unit/sql_helper_spec.rb
176
+ - spec/unit/table_spec.rb
177
+ - spec/unit/throttler_spec.rb
178
+ - spec/unit/unit_helper.rb
data/spec/bootstrap.rb DELETED
@@ -1,13 +0,0 @@
1
- # Copyright (c) 2011 - 2013, SoundCloud Ltd., Rany Keddo, Tobias Bielohlawek, Tobias
2
- # Schmidt
3
-
4
- require 'minitest/spec'
5
- require 'minitest/autorun'
6
- require 'minitest/mock'
7
- require "pathname"
8
-
9
- $project = Pathname.new(File.dirname(__FILE__) + '/..').cleanpath
10
- $spec = $project.join("spec")
11
- $fixtures = $spec.join("fixtures")
12
-
13
- $: << $project.join("lib").to_s