td-client 0.8.62 → 0.8.63

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.
@@ -1,5 +1,5 @@
1
1
  module TreasureData
2
2
  class Client
3
- VERSION = '0.8.62'
3
+ VERSION = '0.8.63'
4
4
  end
5
5
  end
@@ -14,6 +14,7 @@ include WebMock::API
14
14
  $LOAD_PATH << File.dirname(__FILE__)+"../lib"
15
15
  require 'td-client'
16
16
  require 'msgpack'
17
+ require 'json'
17
18
 
18
19
  include TreasureData
19
20
 
@@ -126,15 +126,11 @@ describe API do
126
126
 
127
127
  describe "'validate_column_name'" do
128
128
  it 'should raise a ParameterValidationError exception' do
129
- INVALID_NAMES.each_pair {|ng,ok|
129
+ ['/', '', 'D'].each { |ng|
130
130
  lambda {
131
131
  API.validate_column_name(ng)
132
132
  }.should raise_error(ParameterValidationError)
133
133
  }
134
- # empty
135
- lambda {
136
- API.validate_column_name('')
137
- }.should raise_error(ParameterValidationError)
138
134
  end
139
135
 
140
136
  it 'should return valid data' do
@@ -18,14 +18,14 @@ describe 'BulkImport API' do
18
18
  end
19
19
 
20
20
  it 'should return 422 error with invalid name' do
21
- name = '1'
21
+ name = 'D'
22
22
  err_msg = "Validation failed: Name is too short" # " (minimum is 3 characters)"
23
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)
24
+ .to_return(:status => 422, :body => {'message' => err_msg}.to_json)
25
25
 
26
26
  expect {
27
27
  api.create_bulk_import(name, db_name, table_name)
28
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
28
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
29
29
  end
30
30
 
31
31
  it 'should return 404 error with non exist database name' do
@@ -36,7 +36,7 @@ describe 'BulkImport API' do
36
36
 
37
37
  expect {
38
38
  api.create_bulk_import(bi_name, db, table_name)
39
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
39
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
40
40
  end
41
41
 
42
42
  it 'should return 404 error with non exist table name' do
@@ -47,7 +47,7 @@ describe 'BulkImport API' do
47
47
 
48
48
  expect {
49
49
  api.create_bulk_import(bi_name, db_name, table)
50
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
50
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
51
51
  end
52
52
  end
53
53
  end
@@ -9,9 +9,14 @@ describe 'Database API' do
9
9
  API.new(nil)
10
10
  end
11
11
 
12
- describe 'create_database' do
12
+ let :client do
13
+ Client.new(apikey)
14
+ end
15
+
16
+ describe "'create_database' API" do
13
17
  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)
18
+ stub_api_request(:post, "/v3/database/create/#{e(db_name)}")
19
+ .to_return(:body => {'database' => db_name}.to_json)
15
20
 
16
21
  api.create_database(db_name).should be_true
17
22
  end
@@ -19,20 +24,100 @@ describe 'Database API' do
19
24
  it 'should return 400 error with invalid name' do
20
25
  invalid_name = 'a'
21
26
  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)
27
+ stub_api_request(:post, "/v3/database/create/#{e(invalid_name)}")
28
+ .to_return(:status => 400, :body => {'message' => err_msg}.to_json)
23
29
 
24
30
  expect {
25
31
  api.create_database(invalid_name)
26
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
32
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
27
33
  end
28
34
 
29
35
  it 'should return 409 error with duplicated name' do
30
36
  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)
37
+ stub_api_request(:post, "/v3/database/create/#{e(db_name)}")
38
+ .to_return(:status => 409, :body => {'message' => err_msg}.to_json)
32
39
 
33
40
  expect {
34
41
  api.create_database(db_name)
35
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
42
+ }.to raise_error(TreasureData::AlreadyExistsError, /#{err_msg}/)
43
+ end
44
+ end
45
+
46
+ describe "'list_databases' API" do
47
+ it 'should list the databases with count, created_at, updated_at, organization, and permission' do
48
+ databases = [
49
+ ["db_1", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC", nil, "administrator"],
50
+ ["db_2", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC", nil, "full_access"],
51
+ ["db_3", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC", nil, "import_only"],
52
+ ["db_4", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC", nil, "query_only"]
53
+ ]
54
+ stub_api_request(:get, "/v3/database/list")
55
+ .to_return(:body => {'databases' => [
56
+ {'name' => databases[0][0], 'count' => databases[0][1], 'created_at' => databases[0][2], 'updated_at' => databases[0][3], 'organization' => databases[0][4], 'permission' => databases[0][5]},
57
+ {'name' => databases[1][0], 'count' => databases[1][1], 'created_at' => databases[1][2], 'updated_at' => databases[1][3], 'organization' => databases[1][4], 'permission' => databases[1][5]},
58
+ {'name' => databases[2][0], 'count' => databases[2][1], 'created_at' => databases[2][2], 'updated_at' => databases[2][3], 'organization' => databases[2][4], 'permission' => databases[2][5]},
59
+ {'name' => databases[3][0], 'count' => databases[3][1], 'created_at' => databases[3][2], 'updated_at' => databases[3][3], 'organization' => databases[3][4], 'permission' => databases[3][5]}
60
+ ]}.to_json)
61
+
62
+ db_list = api.list_databases
63
+ databases.each {|db|
64
+ expect(db_list[db[0]]).to eq(db[1..-1])
65
+ }
66
+ end
67
+ end
68
+
69
+ describe "'databases' Client API" do
70
+ it 'should return an array of Databases objects containing name, count, created_at, updated_at, organization, and permission' do
71
+ databases = [
72
+ ["db_1", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC", nil, "administrator"],
73
+ ["db_2", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC", nil, "full_access"],
74
+ ["db_3", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC", nil, "import_only"],
75
+ ["db_4", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC", nil, "query_only"]
76
+ ]
77
+ stub_api_request(:get, "/v3/database/list")
78
+ .to_return(:body => {'databases' => [
79
+ {'name' => databases[0][0], 'count' => databases[0][1], 'created_at' => databases[0][2], 'updated_at' => databases[0][3], 'organization' => databases[0][4], 'permission' => databases[0][5]},
80
+ {'name' => databases[1][0], 'count' => databases[1][1], 'created_at' => databases[1][2], 'updated_at' => databases[1][3], 'organization' => databases[1][4], 'permission' => databases[1][5]},
81
+ {'name' => databases[2][0], 'count' => databases[2][1], 'created_at' => databases[2][2], 'updated_at' => databases[2][3], 'organization' => databases[2][4], 'permission' => databases[2][5]},
82
+ {'name' => databases[3][0], 'count' => databases[3][1], 'created_at' => databases[3][2], 'updated_at' => databases[3][3], 'organization' => databases[3][4], 'permission' => databases[3][5]}
83
+ ]}.to_json)
84
+
85
+ db_list = client.databases
86
+ databases.length.times {|i|
87
+ expect(db_list[i].name).to eq(databases[i][0])
88
+ expect(db_list[i].count).to eq(databases[i][1])
89
+ expect(db_list[i].created_at).to eq(Time.parse(databases[i][2]))
90
+ expect(db_list[i].updated_at).to eq(Time.parse(databases[i][3]))
91
+ expect(db_list[i].org_name).to eq(databases[i][4])
92
+ expect(db_list[i].permission).to eq(databases[i][5].to_sym)
93
+ }
94
+ end
95
+ end
96
+
97
+ describe "'database' Client API" do
98
+ it "should return the Databases object corresponding to the name and containing count, created_at, updated_at, organization, and permission" do
99
+ databases = [
100
+ ["db_1", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC", nil, "administrator"],
101
+ ["db_2", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC", nil, "full_access"],
102
+ ["db_3", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC", nil, "import_only"],
103
+ ["db_4", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC", nil, "query_only"]
104
+ ]
105
+ stub_api_request(:get, "/v3/database/list")
106
+ .to_return(:body => {'databases' => [
107
+ {'name' => databases[0][0], 'count' => databases[0][1], 'created_at' => databases[0][2], 'updated_at' => databases[0][3], 'organization' => databases[0][4], 'permission' => databases[0][5]},
108
+ {'name' => databases[1][0], 'count' => databases[1][1], 'created_at' => databases[1][2], 'updated_at' => databases[1][3], 'organization' => databases[1][4], 'permission' => databases[1][5]},
109
+ {'name' => databases[2][0], 'count' => databases[2][1], 'created_at' => databases[2][2], 'updated_at' => databases[2][3], 'organization' => databases[2][4], 'permission' => databases[2][5]},
110
+ {'name' => databases[3][0], 'count' => databases[3][1], 'created_at' => databases[3][2], 'updated_at' => databases[3][3], 'organization' => databases[3][4], 'permission' => databases[3][5]}
111
+ ]}.to_json)
112
+
113
+ i = 1
114
+ db = client.database(databases[i][0])
115
+ expect(db.name).to eq(databases[i][0])
116
+ expect(db.count).to eq(databases[i][1])
117
+ expect(db.created_at).to eq(Time.parse(databases[i][2]))
118
+ expect(db.updated_at).to eq(Time.parse(databases[i][3]))
119
+ expect(db.org_name).to eq(databases[i][4])
120
+ expect(db.permission).to eq(databases[i][5].to_sym)
36
121
  end
37
122
  end
38
123
  end
@@ -32,7 +32,7 @@ describe 'Export API' do
32
32
 
33
33
  expect {
34
34
  api.export(db_name, table_name, invalid_type)
35
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
35
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
36
36
  end
37
37
 
38
38
  # TODO: Add other parameters spec
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'td/client/spec_resources'
3
+ require 'json'
3
4
 
4
5
  describe 'Job API' do
5
6
  include_context 'spec symbols'
@@ -13,9 +14,35 @@ describe 'Job API' do
13
14
  it 'should returns 20 jobs by default' do
14
15
  stub_api_request(:get, "/v3/job/list", :query => {'from' => '0'}).to_return(:body => {'jobs' => raw_jobs}.to_json)
15
16
  jobs = api.list_jobs
17
+ puts jobs.size
16
18
  jobs.size.should == 20
17
19
  end
18
20
 
21
+ (0...MAX_JOB).each {|i|
22
+ it "should get the correct fields for job #{i} of 20" do
23
+ job = raw_jobs[i]
24
+ stub_api_request(:get, "/v3/job/list", :query => {'from' => '0'}).to_return(:body => {'jobs' => raw_jobs}.to_json)
25
+
26
+ jobs = api.list_jobs
27
+ jobs[i..i].map {|job_id, type, status, query, start_at, end_at, cpu_time,
28
+ result_size, result_url, priority, retry_limit, org, db|
29
+ job_id.should == job['job_id']
30
+ type.should == job['type']
31
+ status.should == job['status']
32
+ query.should == job['query']
33
+ start_at.should == job['start_at']
34
+ end_at.should == job['end_at']
35
+ cpu_time.should == job['cpu_time']
36
+ result_size.should == job['result_size']
37
+ result_url.should == job['result_url']
38
+ priority.should == job['priority']
39
+ retry_limit.should == job['retry_limit']
40
+ org.should == job['organization']
41
+ db.should == job['database']
42
+ }
43
+ end
44
+ }
45
+
19
46
  it 'should returns 10 jobs with to parameter' do
20
47
  stub_api_request(:get, "/v3/job/list", :query => {'from' => '0', 'to' => '10'}).to_return(:body => {'jobs' => raw_jobs[0...10]}.to_json)
21
48
  jobs = api.list_jobs(0, 10)
@@ -28,15 +55,19 @@ describe 'Job API' do
28
55
  jobs = api.list_jobs(0, nil, 'error')
29
56
  jobs.size.should == error_jobs.size
30
57
  end
58
+
59
+ #it 'should contain the result_size field' do
60
+
31
61
  end
32
62
 
33
63
  describe 'show_job' do
34
64
  (0...MAX_JOB).each { |i|
35
- it "should get a job of id #{i}" do
65
+ it "should get the correct fields for job #{i}" do
36
66
  job = raw_jobs[i]
37
67
  stub_api_request(:get, "/v3/job/show/#{e(i)}").to_return(:body => job.to_json)
38
68
 
39
- type, query, status, url, debug, start_at, end_at, result_url, hive_result_schema, priority, retry_limit, org, db = api.show_job(i)
69
+ type, query, status, url, debug, start_at, end_at, cpu_time,
70
+ result_size, result_url, hive_result_schema, priority, retry_limit, org, db = api.show_job(i)
40
71
  type.should == job['type']
41
72
  query.should == job['query']
42
73
  status.should == job['status']
@@ -44,6 +75,8 @@ describe 'Job API' do
44
75
  debug.should == job['debug']
45
76
  start_at.should == job['start_at']
46
77
  end_at.should == job['end_at']
78
+ cpu_time.should == job['cpu_time']
79
+ result_size.should == job['result_size']
47
80
  result_url.should == job['result_url']
48
81
  hive_result_schema.should == job['hive_result_schema']
49
82
  result_url.should == job['result_url']
@@ -60,7 +93,7 @@ describe 'Job API' do
60
93
 
61
94
  expect {
62
95
  api.show_job(unknown_id)
63
- }.to raise_error(TreasureData::NotFoundError, /^Couldn't find Job with account_id = #{account_id}, id = #{unknown_id}/)
96
+ }.to raise_error(TreasureData::NotFoundError, /Couldn't find Job with account_id = #{account_id}, id = #{unknown_id}/)
64
97
  end
65
98
 
66
99
  it 'should return an error with invalid id' do
@@ -70,13 +103,13 @@ describe 'Job API' do
70
103
 
71
104
  expect {
72
105
  api.show_job(invalid_id)
73
- }.to raise_error(TreasureData::APIError, /^'job_id' parameter is required but missing/)
106
+ }.to raise_error(TreasureData::APIError, /'job_id' parameter is required but missing/)
74
107
  end
75
108
  end
76
109
 
77
110
  describe 'job status' do
78
111
  (0...MAX_JOB).each { |i|
79
- it 'should return the status of a job #{i}' do
112
+ it "should return the status of a job #{i}" do
80
113
  job_id = i.to_s
81
114
  raw_job = raw_jobs[i]
82
115
  result_job = {
@@ -38,7 +38,7 @@ describe 'PartialDelete API' do
38
38
 
39
39
  expect {
40
40
  api.partial_delete(db, table_name, to, from)
41
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
41
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
42
42
  end
43
43
 
44
44
  it 'should return 404 error with non exist table name' do
@@ -49,7 +49,7 @@ describe 'PartialDelete API' do
49
49
 
50
50
  expect {
51
51
  api.partial_delete(db_name, table, to, from)
52
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
52
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
53
53
  end
54
54
 
55
55
  # TODO: Add from / to parameters spec
@@ -26,7 +26,7 @@ describe 'Result API' do
26
26
 
27
27
  expect {
28
28
  api.create_result(name, result_url)
29
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
29
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
30
30
  end
31
31
 
32
32
  it 'should return 422 error without url' do
@@ -37,7 +37,7 @@ describe 'Result API' do
37
37
 
38
38
  expect {
39
39
  api.create_result(result_name, false)
40
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
40
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
41
41
  end
42
42
 
43
43
  it 'should return 409 error with duplicated name' do
@@ -48,7 +48,7 @@ describe 'Result API' do
48
48
 
49
49
  expect {
50
50
  api.create_result(result_name, result_url)
51
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
51
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
52
52
  end
53
53
  end
54
54
  end
@@ -16,7 +16,8 @@ describe 'Schedule API' do
16
16
 
17
17
  it 'should create a new schedule' do
18
18
  start = Time.now
19
- stub_api_request(:post, "/v3/schedule/create/#{e(sched_name)}").with(opts.merge('type' => 'hive'))
19
+ stub_api_request(:post, "/v3/schedule/create/#{e(sched_name)}")
20
+ .with(opts.merge('type' => 'hive'))
20
21
  .to_return(:body => {'name' => sched_name, 'start' => start.to_s}.to_json)
21
22
 
22
23
  api.create_schedule(sched_name, opts).should == start.to_s
@@ -25,12 +26,44 @@ describe 'Schedule API' do
25
26
  it 'should return 422 error with invalid name' do
26
27
  name = '1'
27
28
  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
+ stub_api_request(:post, "/v3/schedule/create/#{e(name)}")
30
+ .with(opts.merge('type' => 'hive'))
29
31
  .to_return(:status => 422, :body => {'message' => err_msg}.to_json)
30
32
 
31
33
  expect {
32
34
  api.create_schedule(name, opts)
33
- }.to raise_error(TreasureData::APIError, /^#{err_msg}/)
35
+ }.to raise_error(TreasureData::APIError, /#{err_msg}/)
36
+ end
37
+ end
38
+
39
+ describe 'update_schedule' do
40
+ let :pig_query do
41
+ "OUT = FOREACH (GROUP plt364 ALL) GENERATE COUNT(plt364);\n" * 200
42
+ end
43
+ let :opts do
44
+ {'cron' => cron, 'query' => pig_query, 'database' => db_name}
45
+ end
46
+
47
+ it 'should not return 414 even if the query text is very long' do
48
+ stub_api_request(:post, "/v3/schedule/update/#{e(sched_name)}")
49
+ .with(opts.merge('type' => 'pig'))
50
+ .to_return(:body => {'name' => sched_name, 'query' => pig_query}.to_json)
51
+
52
+ err_msg = "Update schedule failed: Request-URI Too Long"
53
+ expect {
54
+ api.update_schedule(sched_name, opts)
55
+ }.not_to raise_error
56
+ end
57
+
58
+ it 'should update the schedule with the new query' do
59
+ stub_api_request(:post, "/v3/schedule/update/#{e(sched_name)}")
60
+ .with(opts.merge('type' => 'pig'))
61
+ .to_return(:body => {'name' => sched_name, 'query' => pig_query}.to_json)
62
+
63
+ stub_api_request(:get, "/v3/schedule/list")
64
+ .to_return(:body => {'schedules' => [{'name' => sched_name, 'query' => pig_query}]}.to_json)
65
+
66
+ expect(api.list_schedules.first[2]).to eq(pig_query)
34
67
  end
35
68
  end
36
69
  end
@@ -2,6 +2,10 @@ require 'spec_helper'
2
2
  require 'td/client/model'
3
3
 
4
4
  shared_context 'spec symbols' do
5
+ let :apikey do
6
+ '1/0123456789ABCDEFG'
7
+ end
8
+
5
9
  let :db_name do
6
10
  'db_test'
7
11
  end
@@ -66,22 +70,24 @@ shared_context 'job resources' do
66
70
  job_type = types[i % types.size]
67
71
  status = i.odd? ? 'success' : 'error'
68
72
  {
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,
73
+ "job_id" => i,
74
+ "url" => "https://console.treasure-data.com/jobs/#{i.to_s}?target=query",
75
+ "database" => dbs[i % dbs.size].to_s,
76
+ "status" => status,
77
+ "type" => job_type[0].to_sym,
78
+ "query" => "select #{i}",
79
+ "priority" => i % 3,
80
+ "result" => nil,
81
+ "created_at" => created_at.to_s,
82
+ "updated_at" => (created_at + (i * 10)).to_s,
83
+ "start_at" => (created_at + (i * 10 * 60)).to_s,
84
+ "end_at" => (created_at + (i * 10 * 3600)).to_s,
85
+ "cpu_time" => i * 100 + i,
86
+ "result_size" => i * 1000,
87
+ 'retry_limit' => 10,
88
+ 'organization' => nil,
83
89
  'hive_result_schema' => nil,
84
- 'debug' => {
90
+ 'debug' => {
85
91
  'stderr' => "job #{i} #{status}",
86
92
  'cmdout' => "job #{i} command",
87
93
  }