flydata 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/serverinfo +53 -0
- data/flydata.gemspec +5 -4
- data/lib/flydata/cli.rb +1 -0
- data/lib/flydata/command/sender.rb +2 -1
- data/lib/flydata/command/sync.rb +20 -18
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +8 -2
- data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +5 -1
- data/lib/flydata/fluent-plugins/mysql/context.rb +2 -2
- data/lib/flydata/fluent-plugins/preference.rb +1 -0
- data/spec/flydata/cli_spec.rb +3 -3
- data/spec/flydata/command/sender_spec.rb +6 -0
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +69 -0
- data/spec/spec_helper.rb +38 -0
- data/tmpl/redshift_mysql_data_entry.conf.tmpl +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a3fbdc5a0e42708b1dd6f173c366810e4f58892
|
4
|
+
data.tar.gz: 85a647490961e9b85baea5524b9c0f4f395a9d64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 200c29e2a64610cd4561ae127365f934b9cef0ef9dad264fed54d191bc3ec779eb22fe507d4d55c6373928a560c807dafa0cc0883243b0865723a62649349d40
|
7
|
+
data.tar.gz: 2a5b4a1e246b448e6fffe76c6fff8416298d22c4e46719109d6d9c2fca99c3f2ddb1cc3e70cb5b5bf9afbac388c3048b1b840c05952bcc0ab9e14a53c89b901f
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
data/bin/serverinfo
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
detect_system() {
|
3
|
+
# refer to https://github.com/wayneeseguin/rvm/blob/master/scripts/functions/utility_system
|
4
|
+
unset _system_info _system_lib_type
|
5
|
+
export _system_info _system_lib_type
|
6
|
+
_system_info="$(command uname -a)"
|
7
|
+
_system_lib_type="unknown"
|
8
|
+
case "$(command uname)" in
|
9
|
+
(Linux|GNU*)
|
10
|
+
if [[ -f /etc/lsb-release ]]; then
|
11
|
+
_system_lib_type="debian"
|
12
|
+
elif [[ -f /etc/debian_version ]]; then
|
13
|
+
_system_lib_type="debian"
|
14
|
+
elif [[ -f /etc/os-release ]]; then
|
15
|
+
_system_lib_type="debian"
|
16
|
+
elif [[ -f /etc/system-release ]]; then
|
17
|
+
_system_lib_type="centos"
|
18
|
+
elif [[ -f /etc/centos-release ]]; then
|
19
|
+
_system_lib_type="centos"
|
20
|
+
elif [[ -f /etc/redhat-release ]]; then
|
21
|
+
_system_lib_type="centos"
|
22
|
+
fi
|
23
|
+
;;
|
24
|
+
#(Darwin)
|
25
|
+
# _system_lib_type="osx"
|
26
|
+
# ;;
|
27
|
+
(*)
|
28
|
+
;;
|
29
|
+
esac
|
30
|
+
}
|
31
|
+
|
32
|
+
log_server_details()
|
33
|
+
{
|
34
|
+
echo "Logging ip address"
|
35
|
+
ip addr show
|
36
|
+
|
37
|
+
echo "Logging ulimit and uname"
|
38
|
+
ulimit -a
|
39
|
+
uname -a
|
40
|
+
|
41
|
+
echo "Logging repo details"
|
42
|
+
detect_system
|
43
|
+
if [ "${_system_lib_type}" = "debian" ]; then
|
44
|
+
grep -RoPish --include="*.list" "(?<=^deb\s).*?(?=#|$)" /etc/apt
|
45
|
+
else
|
46
|
+
yum repolist all
|
47
|
+
fi
|
48
|
+
|
49
|
+
echo "Logging release details"
|
50
|
+
cat /etc/*-release
|
51
|
+
}
|
52
|
+
|
53
|
+
log_server_details
|
data/flydata.gemspec
CHANGED
@@ -2,19 +2,19 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: flydata 0.2.
|
5
|
+
# stub: flydata 0.2.2 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "flydata"
|
9
|
-
s.version = "0.2.
|
9
|
+
s.version = "0.2.2"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Koichi Fujikawa"]
|
14
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-09-12"
|
15
15
|
s.description = "FlyData Command Line Interface"
|
16
16
|
s.email = "sysadmin@flydata.co"
|
17
|
-
s.executables = ["fdmysqldump", "flydata"]
|
17
|
+
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
18
18
|
s.files = [
|
19
19
|
".gitignore",
|
20
20
|
".rspec",
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
"VERSION",
|
25
25
|
"bin/fdmysqldump",
|
26
26
|
"bin/flydata",
|
27
|
+
"bin/serverinfo",
|
27
28
|
"flydata.gemspec",
|
28
29
|
"lib/fly_data_model.rb",
|
29
30
|
"lib/flydata.rb",
|
data/lib/flydata/cli.rb
CHANGED
@@ -6,7 +6,7 @@ module Flydata
|
|
6
6
|
on 'n', 'no-daemon', 'Start FlyData agent as a regular program'
|
7
7
|
end
|
8
8
|
end
|
9
|
-
def start(options_or_show_final_message = {show_final_message: true}) # For backward compatibility. Use only as options going forward
|
9
|
+
def start(options_or_show_final_message = {show_final_message: true}) # For backward compatibility. Use only as options going forward
|
10
10
|
if options_or_show_final_message.kind_of? Hash
|
11
11
|
options = options_or_show_final_message
|
12
12
|
else
|
@@ -23,6 +23,7 @@ module Flydata
|
|
23
23
|
# Start sender(fluentd) process
|
24
24
|
say('Starting sender process.') unless options[:quiet]
|
25
25
|
Dir.chdir(FLYDATA_HOME){
|
26
|
+
Kernel.system("bash #{File.dirname(__FILE__)}/../../../bin/serverinfo", :out => ["#{FLYDATA_HOME}/flydata.log",'a'], :err => ["#{FLYDATA_HOME}/flydata.log",'a'])
|
26
27
|
daemon_option = opts.no_daemon? ? "" : "-d #{FLYDATA_HOME}/flydata.pid"
|
27
28
|
Kernel.system("fluentd #{daemon_option} -l #{FLYDATA_HOME}/flydata.log -c #{FLYDATA_HOME}/flydata.conf -p #{File.dirname(__FILE__)}/../fluent-plugins")
|
28
29
|
}
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -35,16 +35,10 @@ module Flydata
|
|
35
35
|
end
|
36
36
|
exit 1
|
37
37
|
end
|
38
|
-
de =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
de = load_sync_info(override_tables(de, tables))
|
43
|
-
flush_buffer_and_stop unless de['mysql_data_entry_preference']['initial_sync']
|
44
|
-
sync_mysql_to_redshift(de)
|
45
|
-
else
|
46
|
-
raise "No supported data entry. Only mysql-redshift sync is supported."
|
47
|
-
end
|
38
|
+
de = retrieve_data_entry
|
39
|
+
de = load_sync_info(override_tables(de, tables))
|
40
|
+
flush_buffer_and_stop unless de['mysql_data_entry_preference']['initial_sync']
|
41
|
+
sync_mysql_to_redshift(de)
|
48
42
|
end
|
49
43
|
|
50
44
|
def flush
|
@@ -65,7 +59,7 @@ module Flydata
|
|
65
59
|
sender.flush_client_buffer # TODO We should rather delete buffer files
|
66
60
|
sender.stop
|
67
61
|
|
68
|
-
de =
|
62
|
+
de = retrieve_data_entry
|
69
63
|
wait_for_server_buffer
|
70
64
|
cleanup_sync_server(de, tables) unless opts.client?
|
71
65
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
|
@@ -114,7 +108,7 @@ module Flydata
|
|
114
108
|
end
|
115
109
|
|
116
110
|
def check
|
117
|
-
de =
|
111
|
+
de = retrieve_data_entry
|
118
112
|
retry_on(RestClient::Exception) do
|
119
113
|
status = do_check(de)
|
120
114
|
if status['complete']
|
@@ -127,7 +121,7 @@ module Flydata
|
|
127
121
|
|
128
122
|
# skip initial sync
|
129
123
|
def skip
|
130
|
-
de =
|
124
|
+
de = retrieve_data_entry
|
131
125
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
|
132
126
|
binlog_path = sync_fm.binlog_path
|
133
127
|
`touch #{binlog_path}`
|
@@ -137,20 +131,28 @@ module Flydata
|
|
137
131
|
end
|
138
132
|
|
139
133
|
def generate_table_ddl(*tables)
|
140
|
-
de =
|
134
|
+
de = retrieve_data_entry
|
141
135
|
Flydata::Mysql::CompatibilityCheck.new(de['mysql_data_entry_preference']).check
|
136
|
+
do_generate_table_ddl(override_tables(de, tables))
|
137
|
+
end
|
142
138
|
|
139
|
+
private
|
140
|
+
|
141
|
+
def retrieve_data_entry
|
142
|
+
de = retrieve_data_entries.first
|
143
143
|
raise "There are no data entry." unless de
|
144
144
|
case de['type']
|
145
145
|
when 'RedshiftMysqlDataEntry'
|
146
|
-
|
146
|
+
mp = de['mysql_data_entry_preference']
|
147
|
+
if mp['tables_append_only']
|
148
|
+
mp['tables'] = (mp['tables'].split(",") + mp['tables_append_only'].split(",")).uniq.join(",")
|
149
|
+
end
|
147
150
|
else
|
148
151
|
raise "No supported data entry. Only mysql-redshift sync is supported."
|
149
152
|
end
|
153
|
+
de
|
150
154
|
end
|
151
155
|
|
152
|
-
private
|
153
|
-
|
154
156
|
def cleanup_sync_server(de, tables = [])
|
155
157
|
puts "Cleaning the server"
|
156
158
|
flydata.data_entry.cleanup_sync(de['id'], tables)
|
@@ -412,7 +414,7 @@ What's next?
|
|
412
414
|
Thank you for using FlyData!
|
413
415
|
EOM
|
414
416
|
def complete
|
415
|
-
de = load_sync_info(
|
417
|
+
de = load_sync_info(retrieve_data_entry)
|
416
418
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
|
417
419
|
info = sync_fm.load_dump_pos
|
418
420
|
if info[:status] == STATUS_COMPLETE
|
@@ -47,6 +47,7 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
47
47
|
|
48
48
|
config_param :database, :string
|
49
49
|
config_param :tables, :string
|
50
|
+
config_param :tables_append_only, :string
|
50
51
|
|
51
52
|
def configure(conf)
|
52
53
|
super
|
@@ -55,13 +56,18 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
55
56
|
raise "No position file(#{@position_file}). Initial synchronization is required before starting."
|
56
57
|
end
|
57
58
|
load_custom_conf
|
58
|
-
$log.info "mysql host:\"#{@host}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\""
|
59
|
+
$log.info "mysql host:\"#{@host}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\" tables_append_only:\"#{tables_append_only}\""
|
59
60
|
@tables = @tables.split(/,\s*/)
|
61
|
+
@omit_events = Hash.new
|
62
|
+
@tables_append_only.split(/,\s*/).each do |table|
|
63
|
+
@tables << table unless @tables.include?(table)
|
64
|
+
@omit_events[table] = [:delete]
|
65
|
+
end
|
60
66
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(nil) # Passing nil for data_entry as this class does not use methods which require data_entry
|
61
67
|
|
62
68
|
@context = Mysql::Context.new(
|
63
69
|
database: @database, tables: @tables,
|
64
|
-
tag: @tag, sync_fm: sync_fm
|
70
|
+
tag: @tag, sync_fm: sync_fm, omit_events: @omit_events
|
65
71
|
)
|
66
72
|
@record_dispatcher = Mysql::FlydataBinlogRecordDispatcher.new(@context)
|
67
73
|
end
|
@@ -50,6 +50,10 @@ module Mysql
|
|
50
50
|
acceptable
|
51
51
|
end
|
52
52
|
|
53
|
+
def acceptable_event?(type, table)
|
54
|
+
@context.omit_events[table].nil? || !@context.omit_events[table].include?(type)
|
55
|
+
end
|
56
|
+
|
53
57
|
def emit_record(type, record, opt = {})
|
54
58
|
return unless acceptable_db?(record)
|
55
59
|
return unless record["table_name"].nil? or acceptable_table?(record, record["table_name"])
|
@@ -62,7 +66,7 @@ module Mysql
|
|
62
66
|
|
63
67
|
table = records.first[TABLE_NAME] || record['table_name']
|
64
68
|
raise "Missing table name. #{record}" if table.to_s.empty?
|
65
|
-
return unless acceptable_table?(record, table)
|
69
|
+
return unless acceptable_table?(record, table) && acceptable_event?(type, table)
|
66
70
|
|
67
71
|
table_rev = @context.sync_fm.table_rev(table)
|
68
72
|
position = record['next_position'] - record['event_length']
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Mysql
|
2
2
|
class Context
|
3
3
|
MANDATORY_OPTS = [
|
4
|
-
:database, :tables, :tag, :sync_fm,
|
4
|
+
:database, :tables, :tag, :sync_fm, :omit_events
|
5
5
|
]
|
6
6
|
OPTIONAL_OPTS = [
|
7
|
-
:current_binlog_file
|
7
|
+
:current_binlog_file
|
8
8
|
]
|
9
9
|
|
10
10
|
(MANDATORY_OPTS + OPTIONAL_OPTS).each do |opt|
|
data/spec/flydata/cli_spec.rb
CHANGED
@@ -20,7 +20,7 @@ module Flydata
|
|
20
20
|
expect(a.to_hash).to be_empty
|
21
21
|
}.and_return(command_obj)
|
22
22
|
expect(command_obj).to receive(:run)
|
23
|
-
|
23
|
+
|
24
24
|
subject.run
|
25
25
|
end
|
26
26
|
end
|
@@ -30,7 +30,7 @@ module Flydata
|
|
30
30
|
expect(subject).to receive(:puts).with('! Unknown options -a, --host-name').once
|
31
31
|
allow(subject).to receive(:puts)
|
32
32
|
|
33
|
-
subject.run
|
33
|
+
expect{ subject.run }.to terminate.with_code(1)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
context 'with arguments' do
|
@@ -65,7 +65,7 @@ module Flydata
|
|
65
65
|
expect(subject).to receive(:puts).with('! Unknown options -a, --host-name').once
|
66
66
|
allow(subject).to receive(:puts)
|
67
67
|
|
68
|
-
subject.run
|
68
|
+
expect{ subject.run }.to terminate.with_code(1)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -21,6 +21,8 @@ module Flydata
|
|
21
21
|
let(:args) { [] }
|
22
22
|
it "starts fluend with daemon option" do
|
23
23
|
expect(Kernel).to receive(:system).with( Regexp.new(
|
24
|
+
"bash .+/../../../bin/serverinfo"), :out => [Regexp.new(".+/flydata.log"),'a'], :err => [Regexp.new(".+/flydata.log"),'a'])
|
25
|
+
expect(Kernel).to receive(:system).with( Regexp.new(
|
24
26
|
"fluentd -d .+/flydata.pid -l .+/flydata.log -c .+/flydata.conf -p .+/\.\./fluent-plugins"))
|
25
27
|
subject.start(false)
|
26
28
|
end
|
@@ -28,6 +30,8 @@ module Flydata
|
|
28
30
|
context "as regular process" do
|
29
31
|
let(:args) { ["-n"] }
|
30
32
|
it "starts fluentd with no daemon option" do
|
33
|
+
expect(Kernel).to receive(:system).with( Regexp.new(
|
34
|
+
"bash .+/../../../bin/serverinfo"), :out => [Regexp.new(".+/flydata.log"),'a'], :err => [Regexp.new(".+/flydata.log"),'a'])
|
31
35
|
expect(Kernel).to receive(:system).with(Regexp.new(
|
32
36
|
"fluentd -l .+/flydata.log -c .+/flydata.conf -p .+/\.\./fluent-plugins"))
|
33
37
|
subject.start(false)
|
@@ -36,6 +40,8 @@ module Flydata
|
|
36
40
|
context "as regular process with long option" do
|
37
41
|
let(:args) { ["--no-daemon"] }
|
38
42
|
it "starts fluentd with no daemon option" do
|
43
|
+
expect(Kernel).to receive(:system).with( Regexp.new(
|
44
|
+
"bash .+/../../../bin/serverinfo"), :out => [Regexp.new(".+/flydata.log"),'a'], :err => [Regexp.new(".+/flydata.log"),'a'])
|
39
45
|
expect(Kernel).to receive(:system).with(Regexp.new(
|
40
46
|
"fluentd -l .+/flydata.log -c .+/flydata.conf -p .+/\.\./fluent-plugins"))
|
41
47
|
subject.start(false)
|
@@ -18,10 +18,27 @@ module Fluent
|
|
18
18
|
TEST_POSITION_FILE = "test_position.log"
|
19
19
|
TEST_REVISION_FILE = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE}.rev")
|
20
20
|
TEST_TIMESTAMP = 1389214083
|
21
|
+
TEST_TABLE_APPEND_ONLY = "test_table_4"
|
22
|
+
TEST_SEQUENCE_FILE_1 = File.join(FLYDATA_HOME, "positions/#{TEST_TABLE_APPEND_ONLY}.pos")
|
21
23
|
TEST_CONFIG = <<EOT
|
22
24
|
tag #{TEST_TAG}
|
23
25
|
database #{TEST_DB}
|
24
26
|
tables #{TEST_TABLES}
|
27
|
+
tables_append_only
|
28
|
+
position_file #{TEST_POSITION_FILE}
|
29
|
+
EOT
|
30
|
+
TEST_TABLES_APPEND_ONLY_CONFIG = <<EOT
|
31
|
+
tag #{TEST_TAG}
|
32
|
+
database #{TEST_DB}
|
33
|
+
tables #{TEST_TABLES}
|
34
|
+
tables_append_only #{TEST_TABLE_APPEND_ONLY}
|
35
|
+
position_file #{TEST_POSITION_FILE}
|
36
|
+
EOT
|
37
|
+
TEST_TABLES_DUPLICATE_CONFIG = <<EOT
|
38
|
+
tag #{TEST_TAG}
|
39
|
+
database #{TEST_DB}
|
40
|
+
tables #{TEST_TABLES},#{TEST_TABLE_APPEND_ONLY}
|
41
|
+
tables_append_only #{TEST_TABLE_APPEND_ONLY}
|
25
42
|
position_file #{TEST_POSITION_FILE}
|
26
43
|
EOT
|
27
44
|
|
@@ -189,11 +206,13 @@ EOT
|
|
189
206
|
def setup_initial_flydata_files
|
190
207
|
%w(positions dump conf).each{|f| FileUtils.mkdir_p(File.join(FLYDATA_HOME, f))}
|
191
208
|
create_file(TEST_SEQUENCE_FILE, TEST_SEQUENCE_NUM.to_s)
|
209
|
+
create_file(TEST_SEQUENCE_FILE_1, TEST_SEQUENCE_NUM.to_s)
|
192
210
|
end
|
193
211
|
|
194
212
|
def cleanup_flydata_files
|
195
213
|
%w(positions dump conf).each{|f| FileUtils.rm_rf(File.join(FLYDATA_HOME, f))}
|
196
214
|
delete_file(TEST_SEQUENCE_FILE)
|
215
|
+
delete_file(TEST_SEQUENCE_FILE_1)
|
197
216
|
end
|
198
217
|
|
199
218
|
before do
|
@@ -409,6 +428,56 @@ EOT
|
|
409
428
|
expect_no_emitted_record(event)
|
410
429
|
end
|
411
430
|
end
|
431
|
+
|
432
|
+
context 'for append only' do
|
433
|
+
shared_examples 'emits records correctly' do
|
434
|
+
it 'emits records when it receives an insert event for append only table' do
|
435
|
+
event = insert_event
|
436
|
+
event['table_name'] = TEST_TABLE_APPEND_ONLY
|
437
|
+
expect_emitted_records_with_rows(event, :insert, TEST_TABLE_APPEND_ONLY, 628, "mysql-bin.000048",
|
438
|
+
[{"1"=>"0SL00000001", "2"=>"foo"}, {"1"=>"0SL00000002", "2"=>"var"}, {"1"=>"0SL00000003", "2"=>"hoge"}])
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'does not emit a record when it receives a delete event for append only table' do
|
442
|
+
event = delete_event
|
443
|
+
event['table_name'] = TEST_TABLE_APPEND_ONLY
|
444
|
+
expect_no_emitted_record(event)
|
445
|
+
end
|
446
|
+
|
447
|
+
it 'emits records when it receives an update event for append only table' do
|
448
|
+
event = update_event
|
449
|
+
event['table_name'] = TEST_TABLE_APPEND_ONLY
|
450
|
+
expect_emitted_records_with_rows(event, :update, TEST_TABLE_APPEND_ONLY, 2528, "mysql-bin.000048",
|
451
|
+
[{"1"=>"0SL00000001", "2"=>"wow"}, {"1"=>"0SL00000003", "2"=>"fuga"}])
|
452
|
+
end
|
453
|
+
|
454
|
+
it 'emits a record when it receives a delete event for non-append only table' do
|
455
|
+
expect_emitted_records_with_rows(delete_event, :delete, TEST_TABLE, 5324, "mysql-bin.000048",
|
456
|
+
[{"1"=>"0SL00000002", "2"=>"var"}, {"1"=>"0SL00000003", "2"=>"hoge"}])
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'emits records when it receives an insert event for non-append only table' do
|
460
|
+
expect_emitted_records_with_rows(insert_event, :insert, TEST_TABLE, 628, "mysql-bin.000048",
|
461
|
+
[{"1"=>"0SL00000001", "2"=>"foo"}, {"1"=>"0SL00000002", "2"=>"var"}, {"1"=>"0SL00000003", "2"=>"hoge"}])
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
context 'no duplicate entries in tables and tables_append_only' do
|
466
|
+
before do
|
467
|
+
Test.configure_plugin(plugin, TEST_TABLES_APPEND_ONLY_CONFIG)
|
468
|
+
plugin.event_listener(rotate_event)
|
469
|
+
end
|
470
|
+
include_examples 'emits records correctly'
|
471
|
+
end
|
472
|
+
|
473
|
+
context 'duplicate entries in tables and tables_append_only' do
|
474
|
+
before do
|
475
|
+
Test.configure_plugin(plugin, TEST_TABLES_DUPLICATE_CONFIG)
|
476
|
+
plugin.event_listener(rotate_event)
|
477
|
+
end
|
478
|
+
include_examples 'emits records correctly'
|
479
|
+
end
|
480
|
+
end
|
412
481
|
end
|
413
482
|
end
|
414
483
|
|
data/spec/spec_helper.rb
CHANGED
@@ -33,5 +33,43 @@ RSpec.configure do |config|
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# https://gist.github.com/stevenharman/2355172
|
39
|
+
RSpec::Matchers.define :terminate do |code|
|
40
|
+
actual = nil
|
41
|
+
|
42
|
+
def supports_block_expectations?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
match do |block|
|
47
|
+
begin
|
48
|
+
block.call
|
49
|
+
rescue SystemExit => e
|
50
|
+
actual = e.status
|
51
|
+
end
|
52
|
+
actual and actual == status_code
|
53
|
+
end
|
54
|
+
|
55
|
+
chain :with_code do |status_code|
|
56
|
+
@status_code = status_code
|
57
|
+
end
|
58
|
+
|
59
|
+
failure_message_for_should do |block|
|
60
|
+
"expected block to call exit(#{status_code}) but exit" +
|
61
|
+
(actual.nil? ? " not called" : "(#{actual}) was called")
|
62
|
+
end
|
63
|
+
|
64
|
+
failure_message_for_should_not do |block|
|
65
|
+
"expected block not to call exit(#{status_code})"
|
66
|
+
end
|
67
|
+
|
68
|
+
description do
|
69
|
+
"expect block to call exit(#{status_code})"
|
70
|
+
end
|
36
71
|
|
72
|
+
def status_code
|
73
|
+
@status_code ||= 0
|
74
|
+
end
|
37
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flydata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Fujikawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -377,6 +377,7 @@ email: sysadmin@flydata.co
|
|
377
377
|
executables:
|
378
378
|
- fdmysqldump
|
379
379
|
- flydata
|
380
|
+
- serverinfo
|
380
381
|
extensions: []
|
381
382
|
extra_rdoc_files: []
|
382
383
|
files:
|
@@ -388,6 +389,7 @@ files:
|
|
388
389
|
- VERSION
|
389
390
|
- bin/fdmysqldump
|
390
391
|
- bin/flydata
|
392
|
+
- bin/serverinfo
|
391
393
|
- flydata.gemspec
|
392
394
|
- lib/fly_data_model.rb
|
393
395
|
- lib/flydata.rb
|