td-client 1.0.0-java
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 +7 -0
- data/data/ca-bundle.crt +3448 -0
- data/lib/td-client.rb +1 -0
- data/lib/td/client.rb +606 -0
- data/lib/td/client/api.rb +707 -0
- data/lib/td/client/api/access_control.rb +74 -0
- data/lib/td/client/api/account.rb +45 -0
- data/lib/td/client/api/bulk_import.rb +184 -0
- data/lib/td/client/api/bulk_load.rb +172 -0
- data/lib/td/client/api/database.rb +50 -0
- data/lib/td/client/api/export.rb +38 -0
- data/lib/td/client/api/import.rb +38 -0
- data/lib/td/client/api/job.rb +390 -0
- data/lib/td/client/api/partial_delete.rb +27 -0
- data/lib/td/client/api/result.rb +46 -0
- data/lib/td/client/api/schedule.rb +120 -0
- data/lib/td/client/api/server_status.rb +21 -0
- data/lib/td/client/api/table.rb +132 -0
- data/lib/td/client/api/user.rb +134 -0
- data/lib/td/client/api_error.rb +37 -0
- data/lib/td/client/compat_gzip_reader.rb +22 -0
- data/lib/td/client/model.rb +816 -0
- data/lib/td/client/version.rb +5 -0
- data/lib/td/core_ext/openssl/ssl/sslcontext/set_params.rb +18 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/td/client/access_control_api_spec.rb +37 -0
- data/spec/td/client/account_api_spec.rb +34 -0
- data/spec/td/client/api_error_spec.rb +77 -0
- data/spec/td/client/api_spec.rb +269 -0
- data/spec/td/client/api_ssl_connection_spec.rb +109 -0
- data/spec/td/client/bulk_import_spec.rb +199 -0
- data/spec/td/client/bulk_load_spec.rb +401 -0
- data/spec/td/client/db_api_spec.rb +123 -0
- data/spec/td/client/export_api_spec.rb +51 -0
- data/spec/td/client/import_api_spec.rb +148 -0
- data/spec/td/client/job_api_spec.rb +833 -0
- data/spec/td/client/model_job_spec.rb +136 -0
- data/spec/td/client/model_schedule_spec.rb +26 -0
- data/spec/td/client/model_schema_spec.rb +134 -0
- data/spec/td/client/partial_delete_api_spec.rb +58 -0
- data/spec/td/client/result_api_spec.rb +77 -0
- data/spec/td/client/sched_api_spec.rb +109 -0
- data/spec/td/client/server_status_api_spec.rb +25 -0
- data/spec/td/client/spec_resources.rb +99 -0
- data/spec/td/client/table_api_spec.rb +226 -0
- data/spec/td/client/user_api_spec.rb +118 -0
- data/spec/td/client_sched_spec.rb +79 -0
- data/spec/td/client_spec.rb +46 -0
- metadata +271 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Job Model' do
|
5
|
+
include_context 'spec symbols'
|
6
|
+
include_context 'common helper'
|
7
|
+
include_context 'job resources'
|
8
|
+
|
9
|
+
before do
|
10
|
+
stub_api_request(:post, "/v3/user/authenticate").
|
11
|
+
to_return(:body => {'apikey' => 'apikey'}.to_json)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#client' do
|
15
|
+
subject do
|
16
|
+
Job.new(client, *arguments).client
|
17
|
+
end
|
18
|
+
|
19
|
+
let :client do
|
20
|
+
Client.authenticate('user', 'password')
|
21
|
+
end
|
22
|
+
|
23
|
+
let :arguments do
|
24
|
+
job_attributes = raw_jobs.first
|
25
|
+
[
|
26
|
+
'job_id', 'type', 'query', 'status', 'url', 'debug',
|
27
|
+
'start_at', 'end_at', 'cpu_time', 'result_size', 'result', 'result_url',
|
28
|
+
'hive_result_schema', 'priority', 'retry_limit', 'org_name', 'db_name',
|
29
|
+
'duration', 'num_records'
|
30
|
+
].map {|name| job_attributes[name]}
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns Job object having client' do
|
34
|
+
expect(subject).to eq client
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#result_raw' do
|
39
|
+
let(:client) { Client.authenticate('user', 'password') }
|
40
|
+
let(:job_id) { 12345678 }
|
41
|
+
let(:job) { Job.new(client, job_id, nil, nil) }
|
42
|
+
let(:format) { 'json' }
|
43
|
+
let(:io) { StringIO.new }
|
44
|
+
|
45
|
+
context 'not finished?' do
|
46
|
+
before { allow(job).to receive(:finished?) { false } }
|
47
|
+
|
48
|
+
it 'do not call #job_result_raw' do
|
49
|
+
expect(client).not_to receive(:job_result_raw)
|
50
|
+
|
51
|
+
expect(job.result_raw(format, io)).to_not be
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'finished?' do
|
56
|
+
before { allow(job).to receive(:finished?) { true } }
|
57
|
+
|
58
|
+
it 'call #job_result_raw' do
|
59
|
+
expect(client).to receive(:job_result_raw).with(job_id, format, io)
|
60
|
+
|
61
|
+
job.result_raw(format, io)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#wait' do
|
67
|
+
let(:client) { Client.authenticate('user', 'password') }
|
68
|
+
let(:job_id) { 12345678 }
|
69
|
+
let(:job) { Job.new(client, job_id, nil, nil) }
|
70
|
+
|
71
|
+
def change_job_status(status)
|
72
|
+
allow(client).to receive(:job_status).with(job_id).and_return(status)
|
73
|
+
end
|
74
|
+
|
75
|
+
before do
|
76
|
+
change_job_status(Job::STATUS_QUEUED)
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'without timeout' do
|
80
|
+
it 'waits the job to be finished' do
|
81
|
+
begin
|
82
|
+
thread = Thread.start { job.wait }
|
83
|
+
expect(thread).to be_alive
|
84
|
+
change_job_status(Job::STATUS_SUCCESS)
|
85
|
+
thread.join(1)
|
86
|
+
expect(thread).to be_stop
|
87
|
+
ensure
|
88
|
+
thread.kill # just in case
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'calls a given block in every wait_interval second' do
|
93
|
+
now = 1_400_000_000
|
94
|
+
allow(self).to receive(:sleep){|arg| now += arg }
|
95
|
+
allow(Process).to receive(:clock_gettime){ now }
|
96
|
+
expect { |b|
|
97
|
+
begin
|
98
|
+
thread = Thread.start {
|
99
|
+
job.wait(nil, 2, &b)
|
100
|
+
}
|
101
|
+
sleep 6
|
102
|
+
change_job_status(Job::STATUS_SUCCESS)
|
103
|
+
thread.join(1)
|
104
|
+
expect(thread).to be_stop
|
105
|
+
ensure
|
106
|
+
thread.kill # just in case
|
107
|
+
end
|
108
|
+
}.to yield_control.at_least(2).at_most(3).times
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'with timeout' do
|
113
|
+
context 'the job running time is too long' do
|
114
|
+
it 'raise Timeout::Error' do
|
115
|
+
expect {
|
116
|
+
job.wait(0.1)
|
117
|
+
}.to raise_error(Timeout::Error)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'calls a given block in every wait_interval second, and timeout' do
|
122
|
+
expect { |b|
|
123
|
+
begin
|
124
|
+
thread = Thread.start {
|
125
|
+
job.wait(0.3, 0.1, &b)
|
126
|
+
}
|
127
|
+
expect{ thread.value }.to raise_error(Timeout::Error)
|
128
|
+
expect(thread).to be_stop
|
129
|
+
ensure
|
130
|
+
thread.kill # just in case
|
131
|
+
end
|
132
|
+
}.to yield_control.at_least(2).times
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Schedule Model' do
|
5
|
+
describe '#run' do
|
6
|
+
let(:api_key) { '1234567890abcd' }
|
7
|
+
let(:api) { double(:api) }
|
8
|
+
let(:client) { Client.new(api_key) }
|
9
|
+
let(:name) { 'schedule' }
|
10
|
+
let(:schedule) {
|
11
|
+
Schedule.new(client, name, '0 0 * * * *', 'select 1')
|
12
|
+
}
|
13
|
+
let(:time) { "2013-01-01 00:00:00" }
|
14
|
+
let(:num) { 1 }
|
15
|
+
|
16
|
+
before do
|
17
|
+
allow(API).to receive(:new).with(api_key, {}).and_return(api)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'success call api' do
|
21
|
+
expect(api).to receive(:run_schedule).with(name, time, num).and_return([])
|
22
|
+
|
23
|
+
schedule.run(time, num)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'TreasureData::Schema::Field' do
|
5
|
+
describe '.new' do
|
6
|
+
context 'name="v"' do
|
7
|
+
it 'raises ParameterValidationError' do
|
8
|
+
expect{ Schema::Field.new('v', 'int') }.to raise_error(ParameterValidationError)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
context 'name="time"' do
|
12
|
+
it 'raises ParameterValidationError' do
|
13
|
+
expect{ Schema::Field.new('time', 'int') }.to raise_error(ParameterValidationError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'name with UTF-8' do
|
17
|
+
it 'works' do
|
18
|
+
name = "\u3042\u3044\u3046"
|
19
|
+
f = Schema::Field.new(name, 'int')
|
20
|
+
expect(f.name).to eq name
|
21
|
+
expect(f.type).to eq 'int'
|
22
|
+
expect(f.sql_alias).to be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context 'with sql_alias' do
|
26
|
+
it 'raises' do
|
27
|
+
f = Schema::Field.new('t:t', 'int', 'alice')
|
28
|
+
expect(f.name).to eq 't:t'
|
29
|
+
expect(f.type).to eq 'int'
|
30
|
+
expect(f.sql_alias).to eq 'alice'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
context 'with invalid sql_alias' do
|
34
|
+
it 'raises' do
|
35
|
+
expect{ Schema::Field.new('t:t', 'int', 't:t') }.to raise_error(ParameterValidationError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'TreasureData::Schema' do
|
42
|
+
describe '.parse' do
|
43
|
+
let(:columns){ ["foo:int", "BAR\u3070\u30FC:string@bar", "baz:baz!:array<double>@baz"] }
|
44
|
+
it do
|
45
|
+
sc = Schema.parse(columns)
|
46
|
+
expect(sc.fields.size).to eq 3
|
47
|
+
expect(sc.fields[0].name).to eq 'foo'
|
48
|
+
expect(sc.fields[0].type).to eq 'int'
|
49
|
+
expect(sc.fields[0].sql_alias).to be_nil
|
50
|
+
expect(sc.fields[1].name).to eq "BAR\u3070\u30FC"
|
51
|
+
expect(sc.fields[1].type).to eq 'string'
|
52
|
+
expect(sc.fields[1].sql_alias).to eq 'bar'
|
53
|
+
expect(sc.fields[2].name).to eq 'baz:baz!'
|
54
|
+
expect(sc.fields[2].type).to eq 'array<double>'
|
55
|
+
expect(sc.fields[2].sql_alias).to eq 'baz'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.new' do
|
60
|
+
it do
|
61
|
+
f = Schema::Field.new('a', 'int')
|
62
|
+
sc = Schema.new([f])
|
63
|
+
expect(sc.fields[0]).to eq f
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#fields' do
|
68
|
+
it do
|
69
|
+
f = Schema::Field.new('a', 'int')
|
70
|
+
sc = Schema.new([f])
|
71
|
+
expect(sc.fields[0]).to eq f
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#add_field' do
|
76
|
+
it do
|
77
|
+
f = Schema::Field.new('a', 'int')
|
78
|
+
sc = Schema.new([f])
|
79
|
+
sc.add_field('b', 'double', 'bb')
|
80
|
+
expect(sc.fields[1].name).to eq 'b'
|
81
|
+
end
|
82
|
+
it 'raises ParameterValidationError if name is duplicated' do
|
83
|
+
f = Schema::Field.new('a', 'int')
|
84
|
+
sc = Schema.new([f])
|
85
|
+
expect{ sc.add_field('a', 'double') }.to raise_error(ParameterValidationError)
|
86
|
+
end
|
87
|
+
it 'raises ParameterValidationError if sql_alias is duplicated' do
|
88
|
+
f = Schema::Field.new('a', 'int')
|
89
|
+
sc = Schema.new([f])
|
90
|
+
expect{ sc.add_field('abc', 'double', 'a') }.to raise_error(ParameterValidationError)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#merge' do
|
95
|
+
it do
|
96
|
+
sc1 = Schema.parse(['foo:int', 'bar:float'])
|
97
|
+
sc2 = Schema.parse(['bar:double', 'baz:string'])
|
98
|
+
sc3 = sc1.merge(sc2)
|
99
|
+
expect(sc3.fields.size).to eq 3
|
100
|
+
expect(sc3.fields[0].name).to eq 'foo'
|
101
|
+
expect(sc3.fields[0].type).to eq 'int'
|
102
|
+
expect(sc3.fields[1].name).to eq 'bar'
|
103
|
+
expect(sc3.fields[1].type).to eq 'double'
|
104
|
+
expect(sc3.fields[2].name).to eq 'baz'
|
105
|
+
expect(sc3.fields[2].type).to eq 'string'
|
106
|
+
end
|
107
|
+
it do
|
108
|
+
sc1 = Schema.parse(['foo:int', 'bar:float'])
|
109
|
+
sc2 = Schema.parse(['bar:double@foo'])
|
110
|
+
expect{ sc1.merge(sc2) }.to raise_error(ArgumentError)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#to_json' do
|
115
|
+
it do
|
116
|
+
sc = Schema.parse(['foo:int', 'bar:float@baz'])
|
117
|
+
expect(sc.to_json).to eq '[["foo","int"],["bar","float","baz"]]'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#from_json' do
|
122
|
+
it do
|
123
|
+
sc = Schema.new
|
124
|
+
sc.from_json [["foo","int"],["bar","float","baz"]]
|
125
|
+
expect(sc.fields.size).to eq 2
|
126
|
+
expect(sc.fields[0].name).to eq 'foo'
|
127
|
+
expect(sc.fields[0].type).to eq 'int'
|
128
|
+
expect(sc.fields[0].sql_alias).to be_nil
|
129
|
+
expect(sc.fields[1].name).to eq 'bar'
|
130
|
+
expect(sc.fields[1].type).to eq 'float'
|
131
|
+
expect(sc.fields[1].sql_alias).to eq 'baz'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'PartialDelete API' do
|
5
|
+
include_context 'spec symbols'
|
6
|
+
include_context 'common helper'
|
7
|
+
|
8
|
+
let :api do
|
9
|
+
API.new(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'partialdelete' do
|
13
|
+
let :from do
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
17
|
+
let :to do
|
18
|
+
3600 * 10
|
19
|
+
end
|
20
|
+
|
21
|
+
let :from_to do
|
22
|
+
{'from' => from.to_s, 'to' => to.to_s}
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should partial_delete successfully' do
|
26
|
+
# TODO: Use correnty values
|
27
|
+
stub_api_request(:post, "/v3/table/partialdelete/#{e(db_name)}/#{e(table_name)}").with(:body => from_to).
|
28
|
+
to_return(:body => {'database' => db_name, 'table' => table_name, 'job_id' => '1'}.to_json)
|
29
|
+
|
30
|
+
expect(api.partial_delete(db_name, table_name, to, from)).to eq('1')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return 404 error with non exist database name' do
|
34
|
+
db = 'no_such_db'
|
35
|
+
err_msg = "Couldn't find UserDatabase with name = #{db}"
|
36
|
+
stub_api_request(:post, "/v3/table/partialdelete/#{e(db)}/#{e(table_name)}").with(:body => from_to).
|
37
|
+
to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
38
|
+
|
39
|
+
expect {
|
40
|
+
api.partial_delete(db, table_name, to, from)
|
41
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should return 404 error with non exist table name' do
|
45
|
+
table = 'no_such_table'
|
46
|
+
err_msg = "Unknown table: #{table}"
|
47
|
+
stub_api_request(:post, "/v3/table/partialdelete/#{e(db_name)}/#{e(table)}").with(:body => from_to).
|
48
|
+
to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
49
|
+
|
50
|
+
expect {
|
51
|
+
api.partial_delete(db_name, table, to, from)
|
52
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: Add from / to parameters spec
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Result API' do
|
5
|
+
include_context 'spec symbols'
|
6
|
+
include_context 'common helper'
|
7
|
+
|
8
|
+
let :api do
|
9
|
+
API.new(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'create_result' do
|
13
|
+
it 'should create a new result' do
|
14
|
+
params = {'url' => result_url}
|
15
|
+
stub_api_request(:post, "/v3/result/create/#{e(result_name)}").with(:body => params).to_return(:body => {'result' => result_name}.to_json)
|
16
|
+
|
17
|
+
expect(api.create_result(result_name, result_url)).to be true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should return 422 error with invalid name' do
|
21
|
+
name = '1'
|
22
|
+
params = {'url' => result_url}
|
23
|
+
err_msg = "Validation failed: Name is too short" # " (minimum is 3 characters)"
|
24
|
+
stub_api_request(:post, "/v3/result/create/#{e(name)}").with(:body => params).
|
25
|
+
to_return(:status => 422, :body => {'message' => err_msg}.to_json)
|
26
|
+
|
27
|
+
expect {
|
28
|
+
api.create_result(name, result_url)
|
29
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return 422 error without url' do
|
33
|
+
params = {'url' => 'false'} # I want to use nil, but nil doesn't work on WebMock...
|
34
|
+
err_msg = "'url' parameter is required"
|
35
|
+
stub_api_request(:post, "/v3/result/create/#{e(result_name)}").with(:body => params).
|
36
|
+
to_return(:status => 422, :body => {'message' => err_msg}.to_json)
|
37
|
+
|
38
|
+
expect {
|
39
|
+
api.create_result(result_name, false)
|
40
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should return 409 error with duplicated name' do
|
44
|
+
params = {'url' => result_url}
|
45
|
+
err_msg = "Result must be unique"
|
46
|
+
stub_api_request(:post, "/v3/result/create/#{e(result_name)}").with(:body => params).
|
47
|
+
to_return(:status => 409, :body => {'message' => err_msg}.to_json)
|
48
|
+
|
49
|
+
expect {
|
50
|
+
api.create_result(result_name, result_url)
|
51
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'list_result' do
|
56
|
+
it 'should return name and url' do
|
57
|
+
stub_api_request(:get, '/v3/result/list').
|
58
|
+
to_return(:body => {'results' => [{'name' => 'name', 'url' => 'url'}]}.to_json)
|
59
|
+
expect(api.list_result).to eq([['name', 'url', nil]])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'delete_result' do
|
64
|
+
it 'should delete the result' do
|
65
|
+
stub_api_request(:post, "/v3/result/delete/#{e(result_name)}")
|
66
|
+
expect(api.delete_result(result_name)).to eq(true)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should raise error' do
|
70
|
+
stub_api_request(:post, "/v3/result/delete/#{e(result_name)}").
|
71
|
+
to_return(:status => 404)
|
72
|
+
expect {
|
73
|
+
api.delete_result(result_name)
|
74
|
+
}.to raise_error(TreasureData::APIError)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Schedule API' do
|
5
|
+
include_context 'spec symbols'
|
6
|
+
include_context 'common helper'
|
7
|
+
|
8
|
+
let :api do
|
9
|
+
API.new(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'create_schedule' do
|
13
|
+
let :opts do
|
14
|
+
{'cron' => cron, 'query' => query, 'database' => db_name}
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should create a new schedule' do
|
18
|
+
start = Time.now
|
19
|
+
stub_api_request(:post, "/v3/schedule/create/#{e(sched_name)}").
|
20
|
+
with(:body => opts.merge('type' => 'hive')).
|
21
|
+
to_return(:body => {'name' => sched_name, 'start' => start.to_s}.to_json)
|
22
|
+
|
23
|
+
expect(api.create_schedule(sched_name, opts.merge('type' => 'hive'))).to eq(start.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should create a dummy schedule' do
|
27
|
+
stub_api_request(:post, "/v3/schedule/create/#{e(sched_name)}").
|
28
|
+
with(:body => opts.merge('type' => 'hive')).
|
29
|
+
to_return(:body => {'name' => sched_name, 'start' => nil}.to_json)
|
30
|
+
|
31
|
+
expect(api.create_schedule(sched_name, opts.merge('type' => 'hive'))).to be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return 422 error with invalid name' do
|
35
|
+
name = '1'
|
36
|
+
err_msg = "Validation failed: Name is too short" # " (minimum is 3 characters)"
|
37
|
+
stub_api_request(:post, "/v3/schedule/create/#{e(name)}").
|
38
|
+
with(:body => opts.merge('type' => 'hive')).
|
39
|
+
to_return(:status => 422, :body => {'message' => err_msg}.to_json)
|
40
|
+
|
41
|
+
expect {
|
42
|
+
api.create_schedule(name, opts.merge('type' => 'hive'))
|
43
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'delete_schedule' do
|
48
|
+
it 'should delete the schedule' do
|
49
|
+
stub_api_request(:post, "/v3/schedule/delete/#{e(sched_name)}").
|
50
|
+
to_return(:body => {'cron' => 'cron', 'query' => 'query'}.to_json)
|
51
|
+
expect(api.delete_schedule(sched_name)).to eq(['cron', 'query'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'update_schedule' do
|
56
|
+
let :pig_query do
|
57
|
+
"OUT = FOREACH (GROUP plt364 ALL) GENERATE COUNT(plt364);\n" * 200
|
58
|
+
end
|
59
|
+
let :opts do
|
60
|
+
{'cron' => cron, 'query' => pig_query, 'database' => db_name}
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should not return 414 even if the query text is very long' do
|
64
|
+
stub_api_request(:post, "/v3/schedule/update/#{e(sched_name)}").
|
65
|
+
with(:body => opts.merge('type' => 'pig')).
|
66
|
+
to_return(:body => {'name' => sched_name, 'query' => pig_query}.to_json)
|
67
|
+
|
68
|
+
expect {
|
69
|
+
api.update_schedule(sched_name, opts.merge('type' => 'pig'))
|
70
|
+
}.not_to raise_error
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should update the schedule with the new query' do
|
74
|
+
stub_api_request(:post, "/v3/schedule/update/#{e(sched_name)}").
|
75
|
+
with(:body => opts.merge('type' => 'pig')).
|
76
|
+
to_return(:body => {'name' => sched_name, 'query' => pig_query}.to_json)
|
77
|
+
|
78
|
+
stub_api_request(:get, "/v3/schedule/list").
|
79
|
+
to_return(:body => {'schedules' => [{'name' => sched_name, 'query' => pig_query}]}.to_json)
|
80
|
+
|
81
|
+
expect(api.list_schedules.first[2]).to eq(pig_query)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'history' do
|
86
|
+
let :history do
|
87
|
+
['history', 'job_id', 'type', 'database', 'status', 'query', 'start_at', 'end_at', 'result', 'priority'].inject({}) { |r, e|
|
88
|
+
r[e] = e
|
89
|
+
r
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should return history records' do
|
94
|
+
stub_api_request(:get, "/v3/schedule/history/#{e(sched_name)}").
|
95
|
+
with(:query => {'from' => 0, 'to' => 100}).
|
96
|
+
to_return(:body => {'history' => [history]}.to_json)
|
97
|
+
expect(api.history(sched_name, 0, 100)).to eq([[nil, 'job_id', :type, 'status', 'query', 'start_at', 'end_at', 'result', 'priority', 'database']])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'run_schedule' do
|
102
|
+
it 'should return history records' do
|
103
|
+
stub_api_request(:post, "/v3/schedule/run/#{e(sched_name)}/123456789").
|
104
|
+
with(:body => {'num' => '5'}).
|
105
|
+
to_return(:body => {'jobs' => [{'job_id' => 'job_id', 'scheduled_at' => 'scheduled_at', 'type' => 'type'}]}.to_json)
|
106
|
+
expect(api.run_schedule(sched_name, 123456789, 5)).to eq([['job_id', :type, 'scheduled_at']])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|