taps2 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+ require 'mocha'
4
+ require 'mocha/api'
5
+ require 'rack/test'
6
+ require 'tempfile'
7
+
8
+ $:.unshift File.dirname(__FILE__) + "/../lib"
9
+
10
+ class Bacon::Context
11
+ include Mocha::API
12
+ include Rack::Test::Methods
13
+
14
+ alias_method :old_it, :it
15
+ def it(description)
16
+ old_it(description) do
17
+ mocha_setup
18
+ yield
19
+ mocha_verify
20
+ mocha_teardown
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'taps/config'
26
+ Taps::Config.taps_database_url = "sqlite://#{Tempfile.new('test.db').path}"
27
+ Sequel.connect(Taps::Config.taps_database_url)
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require 'taps/utils'
3
+
4
+ describe Taps::Chunksize do
5
+ it "scales chunksize down slowly when the time delta of the block is just over a second" do
6
+ Time.stubs(:now).returns(10.0).returns(11.5)
7
+ Taps::Utils.calculate_chunksize(1000) { |c| }.should == 900
8
+ end
9
+
10
+ it "scales chunksize down fast when the time delta of the block is over 3 seconds" do
11
+ Time.stubs(:now).returns(10.0).returns(15.0)
12
+ Taps::Utils.calculate_chunksize(3000) { |c| }.should == 1000
13
+ end
14
+
15
+ it "scales up chunksize fast when the time delta of the block is under 0.8 seconds" do
16
+ Time.stubs(:now).returns(10.0).returns(10.7)
17
+ Taps::Utils.calculate_chunksize(1000) { |c| }.should == 2000
18
+ end
19
+
20
+ it "scales up chunksize slow when the time delta of the block is between 0.8 and 1.1 seconds" do
21
+ Time.stubs(:now).returns(10.0).returns(10.8)
22
+ Taps::Utils.calculate_chunksize(1000) { |c| }.should == 1100
23
+
24
+ Time.stubs(:now).returns(10.0).returns(11.1)
25
+ Taps::Utils.calculate_chunksize(1000) { |c| }.should == 1100
26
+ end
27
+
28
+ it "will reset the chunksize to a small value if we got a broken pipe exception" do
29
+ Taps::Utils.calculate_chunksize(1000) do |c|
30
+ raise Errno::EPIPE if c.chunksize == 1000
31
+ c.chunksize.should == 10
32
+ end.should == 10
33
+ end
34
+
35
+ it "will reset the chunksize to a small value if we got a broken pipe exception a second time" do
36
+ Taps::Utils.calculate_chunksize(1000) do |c|
37
+ raise Errno::EPIPE if c.chunksize == 1000 || c.chunksize == 10
38
+ c.chunksize.should == 1
39
+ end.should == 1
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require 'taps/cli'
3
+
4
+ describe Taps::Cli do
5
+ it "translates a list of tables into a regex that can be used in table_filter" do
6
+ @cli = Taps::Cli.new(["-t", "mytable1,logs", "sqlite://tmp.db", "http://x:y@localhost:5000"])
7
+ opts = @cli.clientoptparse(:pull)
8
+ opts[:table_filter].should == "(^mytable1$|^logs$)"
9
+ end
10
+
11
+ it "translates a list of tables to exclude into a regex that can be used in table_filter" do
12
+ @cli = Taps::Cli.new(["-e", "mytable1,logs", "sqlite://tmp.db", "http://x:y@localhost:5000"])
13
+ opts = @cli.clientoptparse(:pull)
14
+ opts[:exclude_tables].should == ['mytable1','logs']
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require 'taps/data_stream'
3
+
4
+ describe Taps::DataStream do
5
+ before do
6
+ @db = mock('db')
7
+ end
8
+
9
+ it "increments the offset" do
10
+ stream = Taps::DataStream.new(@db, :table_name => 'test_table', :chunksize => 100)
11
+ stream.state[:offset].should == 0
12
+ stream.increment(100)
13
+ stream.state[:offset].should == 100
14
+ end
15
+
16
+ it "marks the stream complete if no rows are fetched" do
17
+ stream = Taps::DataStream.new(@db, :table_name => 'test_table', :chunksize => 100)
18
+ stream.stubs(:fetch_rows).returns({})
19
+ stream.complete?.should.be.false
20
+ stream.fetch
21
+ stream.complete?.should.be.true
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require 'taps/operation'
3
+
4
+ describe Taps::Operation do
5
+ before do
6
+ @op = Taps::Operation.new('dummy://localhost', 'http://x:y@localhost:5000')
7
+ end
8
+
9
+ it "returns an array of tables that match the regex table_filter" do
10
+ @op = Taps::Operation.new('dummy://localhost', 'http://x:y@localhost:5000', :table_filter => 'abc')
11
+ @op.apply_table_filter(['abc', 'def']).should == ['abc']
12
+ end
13
+
14
+ it "returns a hash of tables that match the regex table_filter" do
15
+ @op = Taps::Operation.new('dummy://localhost', 'http://x:y@localhost:5000', :table_filter => 'abc')
16
+ @op.apply_table_filter({ 'abc' => 1, 'def' => 2 }).should == { 'abc' => 1 }
17
+ end
18
+
19
+ it "returns an array of tables without the exclude_tables tables" do
20
+ @op = Taps::Operation.new('dummy://localhost', 'http://x:y@localhost:5000', :exclude_tables => ['abc', 'ghi', 'jkl'])
21
+ @op.apply_table_filter(['abc', 'def', 'ghi', 'jkl', 'mno']).should == ['def', 'mno']
22
+ end
23
+
24
+ it "returns a hash of tables without the exclude_tables tables" do
25
+ @op = Taps::Operation.new('dummy://localhost', 'http://x:y@localhost:5000', :exclude_tables => ['abc', 'ghi', 'jkl'])
26
+ @op.apply_table_filter({ 'abc' => 1, 'def' => 2, 'ghi' => 3, 'jkl' => 4, 'mno' => 5 }).should == { 'def' => 2, 'mno' => 5 }
27
+ end
28
+
29
+ it "masks a url's password" do
30
+ @op.safe_url("mysql://root:password@localhost/mydb").should == "mysql://root:[hidden]@localhost/mydb"
31
+ end
32
+
33
+ it "returns http headers with compression enabled" do
34
+ @op.http_headers.should == { :taps_version => Taps.version, :accept_encoding => "gzip, deflate" }
35
+ end
36
+
37
+ it "returns http headers with compression disabled" do
38
+ @op.stubs(:compression_disabled?).returns(true)
39
+ @op.http_headers.should == { :taps_version => Taps.version, :accept_encoding => "" }
40
+ end
41
+
42
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+
3
+ require 'taps/server'
4
+ require 'pp'
5
+
6
+ describe Taps::Server do
7
+ def app
8
+ Taps::Server.new
9
+ end
10
+
11
+ before do
12
+ Taps::Config.login = 'taps'
13
+ Taps::Config.password = 'tpass'
14
+
15
+ @app = Taps::Server
16
+ @auth_header = "Basic " + ["taps:tpass"].pack("m*")
17
+ end
18
+
19
+ it "asks for http basic authentication" do
20
+ get '/'
21
+ last_response.status.should == 401
22
+ end
23
+
24
+ it "verifies the client taps version" do
25
+ get('/', { }, { 'HTTP_AUTHORIZATION' => @auth_header, 'HTTP_TAPS_VERSION' => Taps.version })
26
+ last_response.status.should == 200
27
+ end
28
+
29
+ it "yells loudly if the client taps version doesn't match" do
30
+ get('/', { }, { 'HTTP_AUTHORIZATION' => @auth_header, 'HTTP_TAPS_VERSION' => '0.0.1' })
31
+ last_response.status.should == 417
32
+ end
33
+
34
+ it "allows healthcheck to be accessed w/o HTTP_TAPS_VERSION" do
35
+ get('/health', { }, { 'HTTP_AUTHORIZATION' => @auth_header })
36
+ last_response.status.should == 200
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require 'taps/utils'
3
+
4
+ describe Taps::Utils do
5
+ it "generates a checksum using crc32" do
6
+ Taps::Utils.checksum("hello world").should == Zlib.crc32("hello world")
7
+ end
8
+
9
+ it "formats a data hash into one hash that contains an array of headers and an array of array of data" do
10
+ first_row = { :x => 1, :y => 1 }
11
+ first_row.stubs(:keys).returns([:x, :y])
12
+ Taps::Utils.format_data([ first_row, { :x => 2, :y => 2 } ]).should == { :header => [ :x, :y ], :data => [ [1, 1], [2, 2] ] }
13
+ end
14
+
15
+ it "enforces length limitations on columns" do
16
+ data = [ { :a => "aaabbbccc" } ]
17
+ schema = [ [ :a, { :db_type => "varchar(3)" }]]
18
+ lambda { Taps::Utils.format_data(data, :schema => schema) }.should.raise(Taps::InvalidData)
19
+ end
20
+
21
+ it "returns a list of columns that are text fields if the database is mysql" do
22
+ @db = mock("db", :url => "mysql://localhost/mydb")
23
+ @db.stubs(:schema).with(:mytable).returns([
24
+ [:id, { :db_type => "int" }],
25
+ [:mytext, { :db_type => "text" }]
26
+ ])
27
+ Taps::Utils.incorrect_blobs(@db, :mytable).should == [:mytext]
28
+ end
29
+
30
+ it "rejects a multiple-column primary key as a single integer primary key" do
31
+ @db = mock("db")
32
+ @db.stubs(:schema).with(:pktable.identifier).returns([
33
+ [:id1, { :primary_key => true, :type => :integer }],
34
+ [:id2, { :primary_key => true, :type => :string }]
35
+ ])
36
+ Taps::Utils.single_integer_primary_key(@db, :pktable).should.be.false
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,230 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taps2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ platform: ruby
6
+ authors:
7
+ - Ricardo Chimal, Jr.
8
+ - Joel Van Horn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-04-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.0.1
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 1.0.1
28
+ - !ruby/object:Gem::Dependency
29
+ name: rest-client
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.4.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 1.4.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: sequel
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 4.0.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 4.0.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: sinatra
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.4.4
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.4.4
70
+ - !ruby/object:Gem::Dependency
71
+ name: sqlite3
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.3.8
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.3.8
84
+ - !ruby/object:Gem::Dependency
85
+ name: extlib
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: bacon
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: mocha
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 1.2.1
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 1.2.1
126
+ - !ruby/object:Gem::Dependency
127
+ name: rack-test
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: rake
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: simplecov
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ description: A simple database agnostic import/export app to transfer data to/from
169
+ a remote database.
170
+ email:
171
+ - ricardo@heroku.com
172
+ - joel@joelvanhorn.com
173
+ executables:
174
+ - taps
175
+ - schema
176
+ extensions: []
177
+ extra_rdoc_files: []
178
+ files:
179
+ - README.rdoc
180
+ - VERSION.yml
181
+ - bin/schema
182
+ - bin/schema.cmd
183
+ - bin/taps
184
+ - lib/taps/chunksize.rb
185
+ - lib/taps/cli.rb
186
+ - lib/taps/config.rb
187
+ - lib/taps/data_stream.rb
188
+ - lib/taps/db_session.rb
189
+ - lib/taps/errors.rb
190
+ - lib/taps/log.rb
191
+ - lib/taps/monkey.rb
192
+ - lib/taps/multipart.rb
193
+ - lib/taps/operation.rb
194
+ - lib/taps/progress_bar.rb
195
+ - lib/taps/schema.rb
196
+ - lib/taps/server.rb
197
+ - lib/taps/utils.rb
198
+ - lib/taps/version.rb
199
+ - lib/vendor/okjson.rb
200
+ - spec/base.rb
201
+ - spec/chunksize_spec.rb
202
+ - spec/cli_spec.rb
203
+ - spec/data_stream_spec.rb
204
+ - spec/operation_spec.rb
205
+ - spec/server_spec.rb
206
+ - spec/utils_spec.rb
207
+ homepage: http://github.com/joelvh/taps2
208
+ licenses: []
209
+ metadata: {}
210
+ post_install_message:
211
+ rdoc_options: []
212
+ require_paths:
213
+ - lib
214
+ required_ruby_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ requirements: []
225
+ rubyforge_project:
226
+ rubygems_version: 2.6.11
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: Simple database import/export app
230
+ test_files: []