td-client 0.8.62 → 0.8.63

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }