td-client 0.8.42 → 0.8.43
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.
- data/ChangeLog +6 -0
- data/lib/td/client.rb +10 -10
- data/lib/td/client/api.rb +10 -8
- data/lib/td/client/version.rb +1 -1
- data/spec/spec_helper.rb +31 -0
- data/spec/td/client/api_spec.rb +81 -0
- data/spec/td/client/bulk_import_spec.rb +53 -0
- data/spec/td/client/db_api_spec.rb +38 -0
- data/spec/td/client/export_api_spec.rb +41 -0
- data/spec/td/client/job_api_spec.rb +106 -0
- data/spec/td/client/partial_delete_api_spec.rb +58 -0
- data/spec/td/client/result_api_spec.rb +54 -0
- data/spec/td/client/sched_api_spec.rb +36 -0
- data/spec/td/client/spec_resources.rb +91 -0
- metadata +35 -2
data/ChangeLog
CHANGED
data/lib/td/client.rb
CHANGED
@@ -32,8 +32,8 @@ class Client
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# => true
|
35
|
-
def create_database(db_name)
|
36
|
-
@api.create_database(db_name)
|
35
|
+
def create_database(db_name, opts={})
|
36
|
+
@api.create_database(db_name, opts)
|
37
37
|
end
|
38
38
|
|
39
39
|
# => true
|
@@ -120,8 +120,8 @@ class Client
|
|
120
120
|
end
|
121
121
|
|
122
122
|
# => Job
|
123
|
-
def query(db_name, q, result_url=nil, priority=nil, retry_limit=nil)
|
124
|
-
job_id = @api.hive_query(q, db_name, result_url, priority, retry_limit)
|
123
|
+
def query(db_name, q, result_url=nil, priority=nil, retry_limit=nil, opts={})
|
124
|
+
job_id = @api.hive_query(q, db_name, result_url, priority, retry_limit, opts)
|
125
125
|
Job.new(self, job_id, :hive, q)
|
126
126
|
end
|
127
127
|
|
@@ -174,14 +174,14 @@ class Client
|
|
174
174
|
end
|
175
175
|
|
176
176
|
# => Job
|
177
|
-
def partial_delete(db_name, table_name, to, from)
|
178
|
-
job_id = @api.partial_delete(db_name, table_name, to, from)
|
177
|
+
def partial_delete(db_name, table_name, to, from, opts={})
|
178
|
+
job_id = @api.partial_delete(db_name, table_name, to, from, opts)
|
179
179
|
Job.new(self, job_id, :partialdelete, nil)
|
180
180
|
end
|
181
181
|
|
182
182
|
# => nil
|
183
|
-
def create_bulk_import(name, database, table)
|
184
|
-
@api.create_bulk_import(name, database, table)
|
183
|
+
def create_bulk_import(name, database, table, opts={})
|
184
|
+
@api.create_bulk_import(name, database, table, opts)
|
185
185
|
end
|
186
186
|
|
187
187
|
# => nil
|
@@ -294,8 +294,8 @@ class Client
|
|
294
294
|
end
|
295
295
|
|
296
296
|
# => true
|
297
|
-
def create_result(name, url)
|
298
|
-
@api.create_result(name, url)
|
297
|
+
def create_result(name, url, opts={})
|
298
|
+
@api.create_result(name, url, opts)
|
299
299
|
end
|
300
300
|
|
301
301
|
# => true
|
data/lib/td/client/api.rb
CHANGED
@@ -216,8 +216,9 @@ class API
|
|
216
216
|
end
|
217
217
|
|
218
218
|
# => true
|
219
|
-
def create_database(db)
|
220
|
-
|
219
|
+
def create_database(db, opts={})
|
220
|
+
params = opts.dup
|
221
|
+
code, body, res = post("/v3/database/create/#{e db}", params)
|
221
222
|
if code != "200"
|
222
223
|
raise_error("Create database failed", res)
|
223
224
|
end
|
@@ -462,8 +463,8 @@ class API
|
|
462
463
|
end
|
463
464
|
|
464
465
|
# => jobId:String
|
465
|
-
def hive_query(q, db=nil, result_url=nil, priority=nil, retry_limit=nil)
|
466
|
-
params = {'query' => q}
|
466
|
+
def hive_query(q, db=nil, result_url=nil, priority=nil, retry_limit=nil, opts={})
|
467
|
+
params = {'query' => q}.merge(opts)
|
467
468
|
params['result'] = result_url if result_url
|
468
469
|
params['priority'] = priority if priority
|
469
470
|
params['retry_limit'] = retry_limit if retry_limit
|
@@ -496,8 +497,8 @@ class API
|
|
496
497
|
## Partial delete API
|
497
498
|
##
|
498
499
|
|
499
|
-
def partial_delete(db, table, to, from)
|
500
|
-
params =
|
500
|
+
def partial_delete(db, table, to, from, opts={})
|
501
|
+
params = opts.dup
|
501
502
|
params['to'] = to.to_s
|
502
503
|
params['from'] = from.to_s
|
503
504
|
code, body, res = post("/v3/table/partialdelete/#{e db}/#{e table}", params)
|
@@ -791,8 +792,9 @@ class API
|
|
791
792
|
end
|
792
793
|
|
793
794
|
# => true
|
794
|
-
def create_result(name, url)
|
795
|
-
|
795
|
+
def create_result(name, url, opts={})
|
796
|
+
params = {'url'=>url}.merge(opts)
|
797
|
+
code, body, res = post("/v3/result/create/#{e name}", params)
|
796
798
|
if code != "200"
|
797
799
|
raise_error("Create result table failed", res)
|
798
800
|
end
|
data/lib/td/client/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'simplecov'
|
3
5
|
SimpleCov.start
|
4
6
|
rescue LoadError
|
5
7
|
end
|
6
8
|
|
9
|
+
require 'rspec'
|
10
|
+
require 'webmock/rspec'
|
11
|
+
|
12
|
+
include WebMock::API
|
13
|
+
|
7
14
|
$LOAD_PATH << File.dirname(__FILE__)+"../lib"
|
8
15
|
require 'td-client'
|
9
16
|
|
10
17
|
include TreasureData
|
11
18
|
|
19
|
+
shared_context 'common helper' do
|
20
|
+
let :account_id do
|
21
|
+
1
|
22
|
+
end
|
23
|
+
|
24
|
+
let :headers do
|
25
|
+
{'Accept' => '*/*', 'Accept-Encoding' => 'deflate, gzip', 'Date' => /.*/, 'User-Agent' => 'Ruby'}
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_api_request(method, path, opts = nil)
|
29
|
+
scheme = 'http'
|
30
|
+
with_opts = {:header => headers}
|
31
|
+
if opts
|
32
|
+
scheme = 'https' if opts[:ssl]
|
33
|
+
with_opts[:query] = opts[:query] if opts[:query]
|
34
|
+
end
|
35
|
+
stub_request(method, "#{scheme}://api.treasure-data.com#{path}").with(with_opts)
|
36
|
+
end
|
37
|
+
|
38
|
+
def e(s)
|
39
|
+
require 'cgi'
|
40
|
+
CGI.escape(s.to_s)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe API do
|
4
|
+
it 'initialize should raise an error with invalid endpoint' do
|
5
|
+
expect {
|
6
|
+
API.new(nil, :endpoint => 'smtp://api.tester.com:1000')
|
7
|
+
}.to raise_error(RuntimeError, /Invalid endpoint:/)
|
8
|
+
end
|
9
|
+
|
10
|
+
VALID_NAMES = [
|
11
|
+
'abc',
|
12
|
+
'abc_cd',
|
13
|
+
'_abc_cd',
|
14
|
+
'_abc_',
|
15
|
+
'ab0_',
|
16
|
+
'ab0',
|
17
|
+
]
|
18
|
+
|
19
|
+
INVALID_NAMES = {
|
20
|
+
'a' => 'a__',
|
21
|
+
'a'*257 => 'a'*254+'__',
|
22
|
+
'abcD' => 'abcd',
|
23
|
+
'a-b*' => 'a_b_',
|
24
|
+
}
|
25
|
+
|
26
|
+
describe 'normalizer' do
|
27
|
+
it 'normalize_database_name should return normalized data' do
|
28
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
29
|
+
API.normalize_database_name(ng).should == ok
|
30
|
+
}
|
31
|
+
lambda {
|
32
|
+
API.normalize_database_name('')
|
33
|
+
}.should raise_error(RuntimeError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'normalize_table_name should return normalized data' do
|
37
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
38
|
+
API.normalize_table_name(ng).should == ok
|
39
|
+
}
|
40
|
+
lambda {
|
41
|
+
API.normalize_table_name('')
|
42
|
+
}.should raise_error(RuntimeError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'normalize_database_name should return valid data' do
|
46
|
+
VALID_NAMES.each {|ok|
|
47
|
+
API.normalize_database_name(ok).should == ok
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'validator' do
|
53
|
+
it 'validate_database_name should raise errors' do
|
54
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
55
|
+
lambda {
|
56
|
+
API.validate_database_name(ng)
|
57
|
+
}.should raise_error(RuntimeError)
|
58
|
+
}
|
59
|
+
lambda {
|
60
|
+
API.validate_database_name('')
|
61
|
+
}.should raise_error(RuntimeError)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'validate_table_name should raise errors' do
|
65
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
66
|
+
lambda {
|
67
|
+
API.validate_table_name(ng)
|
68
|
+
}.should raise_error(RuntimeError)
|
69
|
+
}
|
70
|
+
lambda {
|
71
|
+
API.validate_table_name('')
|
72
|
+
}.should raise_error(RuntimeError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'validate_database_name should return valid data' do
|
76
|
+
VALID_NAMES.each {|ok|
|
77
|
+
API.validate_database_name(ok)
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'BulkImport 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_bulk_import' do
|
13
|
+
it 'should create a new bulk_import' do
|
14
|
+
stub_api_request(:post, "/v3/bulk_import/create/#{e(bi_name)}/#{e(db_name)}/#{e(table_name)}")
|
15
|
+
.to_return(:body => {'bulk_import' => bi_name}.to_json)
|
16
|
+
|
17
|
+
api.create_bulk_import(bi_name, db_name, table_name).should be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should return 422 error with invalid name' do
|
21
|
+
name = '1'
|
22
|
+
err_msg = "Validation failed: Name is too short" # " (minimum is 3 characters)"
|
23
|
+
stub_api_request(:post, "/v3/bulk_import/create/#{e(name)}/#{e(db_name)}/#{e(table_name)}")
|
24
|
+
.to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
25
|
+
|
26
|
+
expect {
|
27
|
+
api.create_bulk_import(name, db_name, table_name)
|
28
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should return 404 error with non exist database name' do
|
32
|
+
db = 'no_such_db'
|
33
|
+
err_msg = "Couldn't find UserDatabase with name = #{db}"
|
34
|
+
stub_api_request(:post, "/v3/bulk_import/create/#{e(bi_name)}/#{e(db)}/#{e(table_name)}")
|
35
|
+
.to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
36
|
+
|
37
|
+
expect {
|
38
|
+
api.create_bulk_import(bi_name, db, table_name)
|
39
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should return 404 error with non exist table name' do
|
43
|
+
table = 'no_such_table'
|
44
|
+
err_msg = "Couldn't find UserTableReference with name = #{table}"
|
45
|
+
stub_api_request(:post, "/v3/bulk_import/create/#{e(bi_name)}/#{e(db_name)}/#{e(table)}")
|
46
|
+
.to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
47
|
+
|
48
|
+
expect {
|
49
|
+
api.create_bulk_import(bi_name, db_name, table)
|
50
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Database 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_database' do
|
13
|
+
it 'should create a new database' do
|
14
|
+
stub_api_request(:post, "/v3/database/create/#{e(db_name)}").to_return(:body => {'database' => db_name}.to_json)
|
15
|
+
|
16
|
+
api.create_database(db_name).should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return 400 error with invalid name' do
|
20
|
+
invalid_name = 'a'
|
21
|
+
err_msg = "Name must be 3 to 256 characters, got #{invalid_name.length} characters. name = '#{invalid_name}'"
|
22
|
+
stub_api_request(:post, "/v3/database/create/#{e(invalid_name)}").to_return(:status => 400, :body => {'message' => err_msg}.to_json)
|
23
|
+
|
24
|
+
expect {
|
25
|
+
api.create_database(invalid_name)
|
26
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return 409 error with duplicated name' do
|
30
|
+
err_msg = "Database #{db_name} already exists"
|
31
|
+
stub_api_request(:post, "/v3/database/create/#{e(db_name)}").to_return(:status => 409, :body => {'message' => err_msg}.to_json)
|
32
|
+
|
33
|
+
expect {
|
34
|
+
api.create_database(db_name)
|
35
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Export 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 'export' do
|
13
|
+
let :storage_type do
|
14
|
+
's3'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should export successfully' do
|
18
|
+
# TODO: Use correnty values
|
19
|
+
params = {'file_format' => 'json.gz', 'bucket' => 'bin', 'access_key_id' => 'id', 'secret_access_key' => 'secret'}
|
20
|
+
stub_api_request(:post, "/v3/export/run/#{e(db_name)}/#{e(table_name)}").with(:body => params.merge('storage_type' => storage_type))
|
21
|
+
.to_return(:body => {'database' => db_name, 'job_id' => '1', 'debug' => {}}.to_json)
|
22
|
+
|
23
|
+
api.export(db_name, table_name, storage_type, params).should == '1'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should return 400 error with invalid storage type' do
|
27
|
+
invalid_type = 'gridfs'
|
28
|
+
params = {'storage_type' => invalid_type}
|
29
|
+
err_msg = "Only s3 output type is supported: #{invalid_type}"
|
30
|
+
stub_api_request(:post, "/v3/export/run/#{e(db_name)}/#{e(table_name)}").with(:body => params)
|
31
|
+
.to_return(:status => 400, :body => {'message' => err_msg}.to_json)
|
32
|
+
|
33
|
+
expect {
|
34
|
+
api.export(db_name, table_name, invalid_type)
|
35
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
36
|
+
end
|
37
|
+
|
38
|
+
# TODO: Add other parameters spec
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'Job API' do
|
5
|
+
include_context 'spec symbols'
|
6
|
+
include_context 'job resources'
|
7
|
+
|
8
|
+
let :api do
|
9
|
+
API.new(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'list_jobs' do
|
13
|
+
it 'should returns 20 jobs by default' do
|
14
|
+
stub_api_request(:get, "/v3/job/list", :query => {'from' => '0'}).to_return(:body => {'jobs' => raw_jobs}.to_json)
|
15
|
+
jobs = api.list_jobs
|
16
|
+
jobs.size.should == 20
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should returns 10 jobs with to parameter' do
|
20
|
+
stub_api_request(:get, "/v3/job/list", :query => {'from' => '0', 'to' => '10'}).to_return(:body => {'jobs' => raw_jobs[0...10]}.to_json)
|
21
|
+
jobs = api.list_jobs(0, 10)
|
22
|
+
jobs.size.should == 10
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should returns 10 jobs with to status parameter' do
|
26
|
+
error_jobs = raw_jobs.select { |j| j['status'] == 'error' }
|
27
|
+
stub_api_request(:get, "/v3/job/list", :query => {'from' => '0', 'status' => 'error'}).to_return(:body => {'jobs' => error_jobs}.to_json)
|
28
|
+
jobs = api.list_jobs(0, nil, 'error')
|
29
|
+
jobs.size.should == error_jobs.size
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'show_job' do
|
34
|
+
(0...MAX_JOB).each { |i|
|
35
|
+
it "should get a job of id #{i}" do
|
36
|
+
job = raw_jobs[i]
|
37
|
+
stub_api_request(:get, "/v3/job/show/#{e(i)}").to_return(:body => job.to_json)
|
38
|
+
|
39
|
+
type, query, status, url, debug, start_at, end_at, result_url, hive_result_schema, priority, retry_limit, org, db = api.show_job(i)
|
40
|
+
type.should == job['type']
|
41
|
+
query.should == job['query']
|
42
|
+
status.should == job['status']
|
43
|
+
url.should == job['url']
|
44
|
+
debug.should == job['debug']
|
45
|
+
start_at.should == job['start_at']
|
46
|
+
end_at.should == job['end_at']
|
47
|
+
result_url.should == job['result_url']
|
48
|
+
hive_result_schema.should == job['hive_result_schema']
|
49
|
+
result_url.should == job['result_url']
|
50
|
+
priority.should == job['priority']
|
51
|
+
org.should == job['organization']
|
52
|
+
db.should == job['database']
|
53
|
+
end
|
54
|
+
}
|
55
|
+
|
56
|
+
it 'should return an error with unknown id' do
|
57
|
+
unknown_id = 10000000000
|
58
|
+
body = {"message" => "Couldn't find Job with account_id = #{account_id}, id = #{unknown_id}"}
|
59
|
+
stub_api_request(:get, "/v3/job/show/#{e(unknown_id)}").to_return(:status => 404, :body => body.to_json)
|
60
|
+
|
61
|
+
expect {
|
62
|
+
api.show_job(unknown_id)
|
63
|
+
}.to raise_error(TreasureData::NotFoundError, /^Couldn't find Job with account_id = #{account_id}, id = #{unknown_id}/)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should return an error with invalid id' do
|
67
|
+
invalid_id = 'bomb!'
|
68
|
+
body = {"message" => "'job_id' parameter is required but missing"}
|
69
|
+
stub_api_request(:get, "/v3/job/show/#{e(invalid_id)}").to_return(:status => 500, :body => body.to_json)
|
70
|
+
|
71
|
+
expect {
|
72
|
+
api.show_job(invalid_id)
|
73
|
+
}.to raise_error(TreasureData::APIError, /^'job_id' parameter is required but missing/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'hive_query' do
|
78
|
+
let :return_body do
|
79
|
+
{:body => {'job_id' => '1'}.to_json}
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'issue a query' do
|
83
|
+
params = {'query' => query}
|
84
|
+
stub_api_request(:post, "/v3/job/issue/hive/#{e(db_name)}").with(:body => params).to_return(return_body)
|
85
|
+
|
86
|
+
job_id = api.hive_query(query, db_name)
|
87
|
+
job_id.should == '1'
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'issue a query with result_url' do
|
91
|
+
params = {'query' => query, 'result' => 'td://@/test/table'}
|
92
|
+
stub_api_request(:post, "/v3/job/issue/hive/#{e(db_name)}").with(:body => params).to_return(return_body)
|
93
|
+
|
94
|
+
job_id = api.hive_query(query, db_name, 'td://@/test/table')
|
95
|
+
job_id.should == '1'
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'issue a query with priority' do
|
99
|
+
params = {'query' => query, 'priority' => '1'}
|
100
|
+
stub_api_request(:post, "/v3/job/issue/hive/#{e(db_name)}").with(:body => params).to_return(return_body)
|
101
|
+
|
102
|
+
job_id = api.hive_query(query, db_name, nil, 1)
|
103
|
+
job_id.should == '1'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
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
|
+
api.partial_delete(db_name, table_name, to, from).should == '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,54 @@
|
|
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})
|
16
|
+
|
17
|
+
api.create_result(result_name, result_url).should 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
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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)}").with(opts.merge('type' => 'hive'))
|
20
|
+
.to_return(:body => {'name' => sched_name, 'start' => start.to_s}.to_json)
|
21
|
+
|
22
|
+
api.create_schedule(sched_name, opts).should == start.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return 422 error with invalid name' do
|
26
|
+
name = '1'
|
27
|
+
err_msg = "Validation failed: Name is too short" # " (minimum is 3 characters)"
|
28
|
+
stub_api_request(:post, "/v3/schedule/create/#{e(name)}").with(opts.merge('type' => 'hive'))
|
29
|
+
.to_return(:status => 422, :body => {'message' => err_msg}.to_json)
|
30
|
+
|
31
|
+
expect {
|
32
|
+
api.create_schedule(name, opts)
|
33
|
+
}.to raise_error(TreasureData::APIError, /^#{err_msg}/)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/model'
|
3
|
+
|
4
|
+
shared_context 'spec symbols' do
|
5
|
+
let :db_name do
|
6
|
+
'db_test'
|
7
|
+
end
|
8
|
+
|
9
|
+
let :table_name do
|
10
|
+
'table_test'
|
11
|
+
end
|
12
|
+
|
13
|
+
let :sched_name do
|
14
|
+
'sched_test'
|
15
|
+
end
|
16
|
+
|
17
|
+
let :result_name do
|
18
|
+
'test'
|
19
|
+
end
|
20
|
+
|
21
|
+
let :bi_name do
|
22
|
+
'bi_test'
|
23
|
+
end
|
24
|
+
|
25
|
+
let :cron do
|
26
|
+
'* * * * *'
|
27
|
+
end
|
28
|
+
|
29
|
+
let :query do
|
30
|
+
'select 1'
|
31
|
+
end
|
32
|
+
let :result_url do
|
33
|
+
'td://@/test/table'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
shared_context 'database resources' do
|
38
|
+
include_context 'common helper'
|
39
|
+
|
40
|
+
let :db_names do
|
41
|
+
[
|
42
|
+
'cloud', 'yuffie', 'vincent', 'cid'
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
shared_context 'job resources' do
|
48
|
+
include_context 'database resources'
|
49
|
+
|
50
|
+
MAX_JOB = 20
|
51
|
+
|
52
|
+
let :job_types do
|
53
|
+
[
|
54
|
+
['HiveJob', 'hive'],
|
55
|
+
['ExportJob', 'export'],
|
56
|
+
['BulkImportJob', 'bulk_import'],
|
57
|
+
['PartialDeleteJob', 'partialdelete']
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
let :raw_jobs do
|
62
|
+
created_at = Time.at(1356966000)
|
63
|
+
types = job_types
|
64
|
+
dbs = db_names
|
65
|
+
(0...MAX_JOB).map { |i|
|
66
|
+
job_type = types[i % types.size]
|
67
|
+
status = i.odd? ? 'success' : 'error'
|
68
|
+
{
|
69
|
+
"job_id" => i,
|
70
|
+
"url" => "https://console.treasure-data.com/jobs/#{i.to_s}?target=query",
|
71
|
+
"database" => dbs[i % dbs.size].to_s,
|
72
|
+
"status" => status,
|
73
|
+
"type" => job_type[0].to_sym,
|
74
|
+
"query" => "select #{i}",
|
75
|
+
"priority" => i % 3,
|
76
|
+
"result" => nil,
|
77
|
+
"created_at" => created_at.to_s,
|
78
|
+
"updated_at" => (created_at + (i * 10)).to_s,
|
79
|
+
"start_at" => (created_at + (i * 10 * 60)).to_s,
|
80
|
+
"end_at" => (created_at + (i * 10 * 3600)).to_s,
|
81
|
+
'retry_limit' => 10,
|
82
|
+
'organization' => nil,
|
83
|
+
'hive_result_schema' => nil,
|
84
|
+
'debug' => {
|
85
|
+
'stderr' => "job #{i} #{status}",
|
86
|
+
'cmdout' => "job #{i} command",
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: td-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.43
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 2.8.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: webmock
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.9.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.9.0
|
46
62
|
description:
|
47
63
|
email:
|
48
64
|
executables: []
|
@@ -60,6 +76,15 @@ files:
|
|
60
76
|
- lib/td/client/version.rb
|
61
77
|
- spec/api_spec.rb
|
62
78
|
- spec/spec_helper.rb
|
79
|
+
- spec/td/client/api_spec.rb
|
80
|
+
- spec/td/client/bulk_import_spec.rb
|
81
|
+
- spec/td/client/db_api_spec.rb
|
82
|
+
- spec/td/client/export_api_spec.rb
|
83
|
+
- spec/td/client/job_api_spec.rb
|
84
|
+
- spec/td/client/partial_delete_api_spec.rb
|
85
|
+
- spec/td/client/result_api_spec.rb
|
86
|
+
- spec/td/client/sched_api_spec.rb
|
87
|
+
- spec/td/client/spec_resources.rb
|
63
88
|
- ChangeLog
|
64
89
|
- README.rdoc
|
65
90
|
homepage:
|
@@ -88,3 +113,11 @@ specification_version: 3
|
|
88
113
|
summary: Treasure Data API library for Ruby
|
89
114
|
test_files:
|
90
115
|
- spec/api_spec.rb
|
116
|
+
- spec/td/client/api_spec.rb
|
117
|
+
- spec/td/client/bulk_import_spec.rb
|
118
|
+
- spec/td/client/db_api_spec.rb
|
119
|
+
- spec/td/client/export_api_spec.rb
|
120
|
+
- spec/td/client/job_api_spec.rb
|
121
|
+
- spec/td/client/partial_delete_api_spec.rb
|
122
|
+
- spec/td/client/result_api_spec.rb
|
123
|
+
- spec/td/client/sched_api_spec.rb
|