flare-up 0.6 → 0.7

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
- OWIzMWE3OTM0ZWNkMDFkZGQyMzY4ODdmMTQ3MzVlMDI5MzA1YTgzZg==
4
+ YTIzMzhkOTUyZjYwNzUyMzYyYTUxYTEwZGJlZmY1ODdmNWJkYjUzMw==
5
5
  data.tar.gz: !binary |-
6
- N2M1NTg4OGZlMDUyNTVhYWJkOTZlZDA2ZWQzYmY3MDA5YTNlOGQwMw==
6
+ NDJiMGI4OWQ2ZjMyNWQ2MDQ4NmRjZWY4MjVkNTllY2I1NWJkYmVkOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NzkyMmYwZjdhMjYzNWVhN2IwNDg1N2Y0OTg5MmI5M2IyMTQyNjkzZTc5ODI4
10
- M2MzY2FiN2Y4M2U2OGNkYzdkM2FiNzZjZmI1OTA2ZjE4ODNmNjQ0NzY4Y2Zh
11
- NWI2NDBlMDQ4NjNhYmRmNzg5NzUxNjNhNjYzYzUzZDcyYTYwYWI=
9
+ YTdiYjFkMmFmODI0MTNkYzgyZjAyY2UyNGNkMzM0ZDljMDgxNjNjMjJiNjQx
10
+ ZmM5ZTZiOGI0NDMyZjZhM2VmZGUwMGJkYTg5M2EwM2EzOTFiMTY5ZDBkYjU2
11
+ ZjAxODg1YTFiZTIxNDk4NWVjZmQ3YzJhZjAwNjk5YWM4ZjUxZmY=
12
12
  data.tar.gz: !binary |-
13
- OGQzYjRiN2JlNTM3Y2NmMjMxNWU0NGE3ZTg1ZjY1MjAwMDU4MzU4NzFiNjNh
14
- MjJjMjZlMmFkZmE5ZWIyNGNjNWFmYjk0YTUwOTU2ZDM3ZmJlYTMzYjcwZWNh
15
- NDVkNjQ4MDdmNjZkZmZkMTI2YWJkZDI3MjVmYTE4OTc5NGYzMmI=
13
+ MTFkMTlkOTliMGM0YTMxZDExZjRhNmJlMTA5NGMwODFmM2I3MzM0ZTQ5YTYw
14
+ ZTc4N2VlYjQxZTRkZmEwMTdlYjdjM2E5MjZjNTA0YTczNzVkY2Y1MDVlNDEx
15
+ M2VhNDcyZjI1MzU4NmVlNTIzMjZlMTE0OWU0MzViMzdmMWQzNTI=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flare-up (0.6)
4
+ flare-up (0.7)
5
5
  pg (~> 0.17)
6
6
  thor (~> 0.19)
7
7
 
data/README.md CHANGED
@@ -50,5 +50,5 @@ Note that this example assumes you have credentials set as environment variables
50
50
  dev \
51
51
  hearthstone_cards \
52
52
  --column-list name cost attack health description \
53
- --copy_options "REGION 'us-east-1' CSV"
53
+ --copy-options "REGION 'us-east-1' CSV"
54
54
  ```
data/lib/flare_up/boot.rb CHANGED
@@ -2,14 +2,28 @@ module FlareUp
2
2
 
3
3
  class Boot
4
4
 
5
- # TODO: This control flow is untested
5
+ # TODO: This control flow is untested and too procedural
6
6
  def self.boot(options)
7
7
  conn = create_connection(options)
8
8
  copy = create_copy_command(options)
9
9
 
10
10
  begin
11
+ trap('SIGINT') do
12
+ Emitter.warn('CTRL-C received; cancelling COPY command...')
13
+ error_message = conn.cancel_current_command
14
+ if error_message
15
+ Emitter.error("Error cancelling COPY: #{error_message}")
16
+ else
17
+ Emitter.success('COPY command cancelled.')
18
+ end
19
+ CLI.bailout(1)
20
+ end
21
+
11
22
  Emitter.info("Executing command: #{copy.get_command}")
12
23
  handle_load_errors(copy.execute(conn))
24
+ rescue ConnectionError => e
25
+ Emitter.error(e.message)
26
+ CLI.bailout(1)
13
27
  rescue CopyCommandError => e
14
28
  Emitter.error(e.message)
15
29
  CLI.bailout(1)
@@ -1,14 +1,16 @@
1
1
  module FlareUp
2
2
 
3
- class HostUnknownOrInaccessibleError < StandardError
3
+ class ConnectionError < StandardError
4
4
  end
5
- class TimeoutError < StandardError
5
+ class HostUnknownOrInaccessibleError < ConnectionError
6
6
  end
7
- class NoDatabaseError < StandardError
7
+ class TimeoutError < ConnectionError
8
8
  end
9
- class AuthenticationError < StandardError
9
+ class NoDatabaseError < ConnectionError
10
10
  end
11
- class UnknownError < StandardError
11
+ class AuthenticationError < ConnectionError
12
+ end
13
+ class UnknownError < ConnectionError
12
14
  end
13
15
 
14
16
  class Connection
@@ -30,15 +32,20 @@ module FlareUp
30
32
  @connect_timeout = 5
31
33
  end
32
34
 
33
- # TODO - Not quite sure how to test this; perhaps fold connect/execute into
34
- # TODO one method so we can close connections in case of failure, etc.
35
35
  def execute(statement)
36
- @pg_conn ||= connect
37
- @pg_conn.exec(statement)
36
+ connection.async_exec(statement)
37
+ end
38
+
39
+ def cancel_current_command
40
+ connection.cancel
38
41
  end
39
42
 
40
43
  private
41
44
 
45
+ def connection
46
+ @pg_conn ||= connect
47
+ end
48
+
42
49
  def connect
43
50
  begin
44
51
  PG.connect(connection_parameters)
@@ -53,11 +60,12 @@ module FlareUp
53
60
  when /password authentication failed for user/
54
61
  raise AuthenticationError, "Either username '#{@user}' or password invalid"
55
62
  else
56
- raise UnknownError
63
+ raise UnknownError, e.message
57
64
  end
58
65
  end
59
66
  end
60
67
 
68
+ # http://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
61
69
  def connection_parameters
62
70
  {
63
71
  :host => @host,
@@ -65,7 +73,17 @@ module FlareUp
65
73
  :dbname => @dbname,
66
74
  :user => @user,
67
75
  :password => @password,
68
- :connect_timeout => @connect_timeout
76
+ :connect_timeout => @connect_timeout,
77
+ # Enable keep-alives
78
+ :keepalives => 1,
79
+ # Idle time in between keep-alives when there is a response from the peer
80
+ :keepalives_idle => 30,
81
+ # Interval between keep-alives when there is no response from the peer
82
+ # This is done to probe the peer until there is a response
83
+ :keepalives_interval => 10,
84
+ # Number of keep-alives that can be lost before the client's connection
85
+ # to the server is considered dead
86
+ :keepalives_count => 3
69
87
  }
70
88
  end
71
89
 
@@ -14,6 +14,16 @@ module FlareUp
14
14
  $stderr.puts sanitize("\x1b[31m#{message}") unless ENV['TESTING']
15
15
  end
16
16
 
17
+ # TODO: How do we test this?
18
+ def self.success(message)
19
+ $stdout.puts sanitize("\x1b[32m#{message}") unless ENV['TESTING']
20
+ end
21
+
22
+ # TODO: How do we test this?
23
+ def self.warn(message)
24
+ $stdout.puts sanitize("\x1b[33m#{message}") unless ENV['TESTING']
25
+ end
26
+
17
27
  # TODO: How do we test this?
18
28
  def self.info(message)
19
29
  $stdout.puts sanitize(message) unless ENV['TESTING']
@@ -1,3 +1,3 @@
1
1
  module FlareUp
2
- VERSION = '0.6'
2
+ VERSION = '0.7'
3
3
  end
@@ -1,13 +1,15 @@
1
1
  describe FlareUp::Boot do
2
2
 
3
3
  describe '.boot' do
4
+ let(:connection) { instance_double('FlareUp::Connection') }
4
5
  let(:copy_command) { instance_double('FlareUp::CopyCommand') }
5
6
 
6
7
  before do
7
8
  allow(copy_command).to receive(:get_command)
8
9
  end
9
10
 
10
- context 'when there is an error' do
11
+ context 'when there is an error connecting' do
12
+
11
13
  before do
12
14
  expect(FlareUp::Boot).to receive(:create_copy_command).and_return(copy_command)
13
15
  expect(copy_command).to receive(:execute).and_raise(copy_command_error)
@@ -39,6 +41,55 @@ describe FlareUp::Boot do
39
41
 
40
42
  end
41
43
 
44
+ context 'when there is an error copying' do
45
+
46
+ before do
47
+ expect(FlareUp::Boot).to receive(:create_connection).and_return(connection)
48
+ expect(connection).to receive(:execute).and_raise(connection_error)
49
+ end
50
+
51
+ context 'when there is a HostUnknownOrInaccessibleError' do
52
+ let(:connection_error) { FlareUp::HostUnknownOrInaccessibleError }
53
+ it 'should handle the error' do
54
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
55
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
56
+ end
57
+ end
58
+
59
+ context 'when there is a TimeoutError' do
60
+ let(:connection_error) { FlareUp::TimeoutError }
61
+ it 'should handle the error' do
62
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
63
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
64
+ end
65
+ end
66
+
67
+ context 'when there is a NoDatabaseError' do
68
+ let(:connection_error) { FlareUp::NoDatabaseError }
69
+ it 'should handle the error' do
70
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
71
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
72
+ end
73
+ end
74
+
75
+ context 'when there is a AuthenticationError' do
76
+ let(:connection_error) { FlareUp::AuthenticationError }
77
+ it 'should handle the error' do
78
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
79
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
80
+ end
81
+ end
82
+
83
+ context 'when there is a UnknownError' do
84
+ let(:connection_error) { FlareUp::UnknownError }
85
+ it 'should handle the error' do
86
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
87
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
88
+ end
89
+ end
90
+
91
+ end
92
+
42
93
  end
43
94
 
44
95
  describe '.create_connection' do
@@ -4,6 +4,8 @@ describe FlareUp::Connection do
4
4
  FlareUp::Connection.new('TEST_HOST', 'TEST_DB_NAME', 'TEST_USER', 'TEST_PASSWORD')
5
5
  end
6
6
 
7
+ let(:mock_pg_connection) { instance_double('PGConn') }
8
+
7
9
  its(:host) { should == 'TEST_HOST' }
8
10
  its(:port) { should == 5439 }
9
11
  its(:dbname) { should == 'TEST_DB_NAME' }
@@ -97,7 +99,6 @@ describe FlareUp::Connection do
97
99
  end
98
100
 
99
101
  describe '#connection_parameters' do
100
-
101
102
  it 'should return the required parameters' do
102
103
  expect(subject.send(:connection_parameters)).to eq({
103
104
  :host => 'TEST_HOST',
@@ -106,9 +107,32 @@ describe FlareUp::Connection do
106
107
  :user => 'TEST_USER',
107
108
  :password => 'TEST_PASSWORD',
108
109
  :connect_timeout => 5,
110
+ :keepalives => 1,
111
+ :keepalives_idle => 30,
112
+ :keepalives_interval => 10,
113
+ :keepalives_count => 3
109
114
  })
110
115
  end
116
+ end
111
117
 
118
+ describe '#execute' do
119
+ before do
120
+ allow(subject).to receive(:connect).and_return(mock_pg_connection)
121
+ end
122
+ it 'should execute the specified command' do
123
+ expect(mock_pg_connection).to receive(:async_exec).with('TEST_STATEMENT')
124
+ subject.execute('TEST_STATEMENT')
125
+ end
126
+ end
127
+
128
+ describe '#cancel_current_command' do
129
+ before do
130
+ allow(subject).to receive(:connect).and_return(mock_pg_connection)
131
+ end
132
+ it 'should execute the specified command' do
133
+ expect(mock_pg_connection).to receive(:cancel)
134
+ subject.cancel_current_command
135
+ end
112
136
  end
113
137
 
114
138
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flare-up
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: '0.7'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Slifka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-12 00:00:00.000000000 Z
11
+ date: 2014-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg