aboisvert_aws 3.0.0

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.
Files changed (78) hide show
  1. data/History.txt +329 -0
  2. data/Manifest.txt +61 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +130 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1343 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +541 -0
  16. data/lib/ec2/right_ec2_ebs.rb +481 -0
  17. data/lib/ec2/right_ec2_images.rb +444 -0
  18. data/lib/ec2/right_ec2_instances.rb +788 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +184 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +491 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +422 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +590 -0
  26. data/lib/ec2/right_ec2_vpc2.rb +381 -0
  27. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  28. data/lib/elb/right_elb_interface.rb +573 -0
  29. data/lib/emr/right_emr_interface.rb +727 -0
  30. data/lib/iam/right_iam_access_keys.rb +71 -0
  31. data/lib/iam/right_iam_groups.rb +195 -0
  32. data/lib/iam/right_iam_interface.rb +341 -0
  33. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  34. data/lib/iam/right_iam_users.rb +251 -0
  35. data/lib/rds/right_rds_interface.rb +1384 -0
  36. data/lib/right_aws.rb +86 -0
  37. data/lib/route_53/right_route_53_interface.rb +640 -0
  38. data/lib/s3/right_s3.rb +1138 -0
  39. data/lib/s3/right_s3_interface.rb +1278 -0
  40. data/lib/sdb/active_sdb.rb +1107 -0
  41. data/lib/sdb/right_sdb_interface.rb +762 -0
  42. data/lib/sns/right_sns_interface.rb +286 -0
  43. data/lib/sqs/right_sqs.rb +387 -0
  44. data/lib/sqs/right_sqs_gen2.rb +342 -0
  45. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  46. data/lib/sqs/right_sqs_interface.rb +593 -0
  47. data/right_aws.gemspec +90 -0
  48. data/test/README.mdown +39 -0
  49. data/test/acf/test_helper.rb +2 -0
  50. data/test/acf/test_right_acf.rb +138 -0
  51. data/test/awsbase/test_helper.rb +2 -0
  52. data/test/awsbase/test_right_awsbase.rb +11 -0
  53. data/test/ec2/test_helper.rb +2 -0
  54. data/test/ec2/test_right_ec2.rb +107 -0
  55. data/test/elb/test_helper.rb +2 -0
  56. data/test/elb/test_right_elb.rb +43 -0
  57. data/test/http_connection.rb +87 -0
  58. data/test/rds/test_helper.rb +2 -0
  59. data/test/rds/test_right_rds.rb +120 -0
  60. data/test/route_53/fixtures/a_record.xml +18 -0
  61. data/test/route_53/fixtures/alias_record.xml +18 -0
  62. data/test/route_53/test_helper.rb +2 -0
  63. data/test/route_53/test_right_route_53.rb +141 -0
  64. data/test/s3/test_helper.rb +2 -0
  65. data/test/s3/test_right_s3.rb +528 -0
  66. data/test/s3/test_right_s3_stubbed.rb +97 -0
  67. data/test/sdb/test_active_sdb.rb +357 -0
  68. data/test/sdb/test_batch_put_attributes.rb +54 -0
  69. data/test/sdb/test_helper.rb +3 -0
  70. data/test/sdb/test_right_sdb.rb +253 -0
  71. data/test/sns/test_helper.rb +2 -0
  72. data/test/sns/test_right_sns.rb +153 -0
  73. data/test/sqs/test_helper.rb +2 -0
  74. data/test/sqs/test_right_sqs.rb +285 -0
  75. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  76. data/test/test_credentials.rb +37 -0
  77. data/test/ts_right_aws.rb +15 -0
  78. metadata +257 -0
@@ -0,0 +1,87 @@
1
+ =begin
2
+ Copyright (c) 2007 RightScale, Inc.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ 'Software'), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ =end
23
+
24
+ # Stub extension/redefinition of RightHttpConnection for testing purposes.
25
+ require 'net/http'
26
+ require 'rubygems'
27
+ require 'right_http_connection'
28
+
29
+ module Net
30
+ class HTTPResponse
31
+ alias_method :real_body, :body
32
+ def setmsg(msg)
33
+ @mymsg = msg
34
+ end
35
+
36
+ def body
37
+ # defined?() helps us to get rid of a bunch of 'warnings'
38
+ (defined?(@mymsg) && @mymsg) ? @mymsg : real_body
39
+ end
40
+ end
41
+ end
42
+
43
+ module Rightscale
44
+
45
+ class HttpConnection
46
+ @@response_stack = []
47
+
48
+ alias_method :real_request, :request
49
+
50
+ def request(request_params, &block)
51
+ if(@@response_stack.length == 0)
52
+ return real_request(request_params, &block)
53
+ end
54
+
55
+ if(block)
56
+ # Do something special
57
+ else
58
+ next_response = HttpConnection::pop()
59
+ classname = Net::HTTPResponse::CODE_TO_OBJ["#{next_response[:code]}"]
60
+ response = classname.new("1.1", next_response[:code], next_response[:msg])
61
+ if(next_response[:msg])
62
+ response.setmsg(next_response[:msg])
63
+ end
64
+ response
65
+ end
66
+ end
67
+
68
+ def self.reset
69
+ @@response_stack = []
70
+ end
71
+
72
+ def self.push(code, msg=nil)
73
+ response = {:code => code, :msg => msg}
74
+ @@response_stack << response
75
+ end
76
+
77
+ def self.pop
78
+ @@response_stack.pop
79
+ end
80
+
81
+ def self.length
82
+ @@response_stack.length
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../../lib/right_aws'
@@ -0,0 +1,120 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRds < Test::Unit::TestCase
4
+
5
+ STDOUT.sync = true
6
+
7
+ TEST_SG_NAME = 'RightRdsSGTest0123456789'
8
+
9
+ def setup
10
+ @rds = Rightscale::RdsInterface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key, :logger => Logger.new('/dev/null'))
11
+ end
12
+
13
+ def test_00_instances
14
+ assert_nothing_raised do
15
+ items = @rds.describe_db_instances
16
+ assert items.is_a?(Array)
17
+ end
18
+ #
19
+ assert_nothing_raised do
20
+ @rds.describe_db_instances do |response|
21
+ assert response.is_a?(Hash)
22
+ assert response[:db_instances].is_a?(Array)
23
+ end
24
+ end
25
+ end
26
+
27
+ def test_10_security_groups
28
+ assert_nothing_raised do
29
+ items = @rds.describe_db_security_groups
30
+ assert items.is_a?(Array)
31
+ end
32
+ #
33
+ assert_nothing_raised do
34
+ @rds.describe_db_security_groups do |response|
35
+ assert response.is_a?(Hash)
36
+ assert response[:db_security_groups].is_a?(Array)
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_11_remove_security_group
42
+ @rds.delete_db_security_group rescue nil
43
+ end
44
+
45
+ def test_12_create_security_group
46
+ sg = nil
47
+ assert_nothing_raised do
48
+ sg = @rds.create_db_security_group(TEST_SG_NAME, 'sg-description')
49
+ end
50
+ assert sg.is_a?(Hash)
51
+ end
52
+
53
+ def test_13_authorize
54
+ assert_nothing_raised do
55
+ sg = @rds.authorize_db_security_group_ingress(TEST_SG_NAME, :cidrip => '131.0.0.1/8')
56
+ assert sg.is_a?(Hash)
57
+ assert_equal 1, sg[:ip_ranges].size
58
+ end
59
+ assert_nothing_raised do
60
+ sg = @rds.authorize_db_security_group_ingress(TEST_SG_NAME, :ec2_security_group_owner => '826693181925',
61
+ :ec2_security_group_name => 'default' )
62
+ assert sg.is_a?(Hash)
63
+ assert_equal 1, sg[:ec2_security_groups].size
64
+ end
65
+ sleep 30
66
+ end
67
+
68
+ def test_14_revoke
69
+ assert_nothing_raised do
70
+ sg = @rds.revoke_db_security_group_ingress(TEST_SG_NAME, :cidrip => '131.0.0.1/8')
71
+ assert sg.is_a?(Hash)
72
+ end
73
+ assert_nothing_raised do
74
+ sg = @rds.revoke_db_security_group_ingress(TEST_SG_NAME, :ec2_security_group_owner => '826693181925',
75
+ :ec2_security_group_name => 'default' )
76
+ assert sg.is_a?(Hash)
77
+ end
78
+ sleep 30
79
+ #
80
+ sg = @rds.describe_db_security_groups(TEST_SG_NAME).first
81
+ assert_equal 0, sg[:ip_ranges].size
82
+ assert_equal 0, sg[:ec2_security_groups].size
83
+ end
84
+
85
+ def test_15_delete_security_group
86
+ assert_nothing_raised do
87
+ @rds.delete_db_security_group(TEST_SG_NAME)
88
+ end
89
+ end
90
+
91
+
92
+ def test_20_db_snapshots
93
+ assert_nothing_raised do
94
+ items = @rds.describe_db_snapshots
95
+ assert items.is_a?(Array)
96
+ end
97
+ #
98
+ assert_nothing_raised do
99
+ @rds.describe_db_snapshots do |response|
100
+ assert response.is_a?(Hash)
101
+ assert response[:db_snapshots].is_a?(Array)
102
+ end
103
+ end
104
+ end
105
+
106
+ def test_30_events
107
+ assert_nothing_raised do
108
+ items = @rds.describe_events
109
+ assert items.is_a?(Array)
110
+ end
111
+ #
112
+ assert_nothing_raised do
113
+ @rds.describe_events do |response|
114
+ assert response.is_a?(Hash)
115
+ assert response[:events].is_a?(Array)
116
+ end
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2011-05-05/">
3
+ <ChangeBatch>
4
+ <Changes>
5
+ <Change>
6
+ <Action>CREATE</Action>
7
+ <ResourceRecordSet>
8
+ <Name>host.right-aws.example.com.</Name>
9
+ <Type>A</Type>
10
+ <TTL>600</TTL>
11
+ <ResourceRecords>
12
+ <ResourceRecord><Value>10.0.0.1</Value></ResourceRecord>
13
+ </ResourceRecords>
14
+ </ResourceRecordSet>
15
+ </Change>
16
+ </Changes>
17
+ </ChangeBatch>
18
+ </ChangeResourceRecordSetsRequest>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2011-05-05/">
3
+ <ChangeBatch>
4
+ <Changes>
5
+ <Change>
6
+ <Action>CREATE</Action>
7
+ <ResourceRecordSet>
8
+ <Name>right-aws.example.com.</Name>
9
+ <Type>A</Type>
10
+ <AliasTarget>
11
+ <HostedZoneId>Z1234567890123</HostedZoneId>
12
+ <DNSName>example-load-balancer-1111111111.us-east-1.elb.amazonaws.com.</DNSName>
13
+ </AliasTarget>
14
+ </ResourceRecordSet>
15
+ </Change>
16
+ </Changes>
17
+ </ChangeBatch>
18
+ </ChangeResourceRecordSetsRequest>
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../../lib/right_aws'
@@ -0,0 +1,141 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRoute53 < Test::Unit::TestCase
4
+
5
+ STDOUT.sync = true
6
+ BALANCER_NAME = 'right-aws-test-lb'
7
+
8
+ def setup
9
+ @r53 = Rightscale::Route53Interface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key, :logger => Logger.new('/dev/null'))
10
+ @zone_config = {:name => "right-aws.example.com.", :config => {:comment => 'a comment'}}
11
+
12
+ @elb = Rightscale::ElbInterface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key, :logger => Logger.new('/dev/null'))
13
+ end
14
+
15
+ def teardown
16
+ @r53.list_hosted_zones.each do |zone|
17
+ next unless zone[:name] == @zone_config[:name]
18
+ zone_id = zone[:aws_id]
19
+ puts zone_id
20
+ records = @r53.list_resource_record_sets(zone_id)
21
+ # The NS and SOA records are provided by AWS and must not be deleted
22
+ records.reject! { |rr| %w[NS SOA].include? rr[:type] }
23
+ if records.any?
24
+ response = @r53.delete_resource_record_sets(zone_id, records)
25
+ puts response.inspect
26
+ end
27
+ puts @r53.delete_hosted_zone(zone_id).inspect
28
+ end
29
+ # Uncomment to shut down at the end of the day.
30
+ # @elb.delete_load_balancer BALANCER_NAME
31
+ end
32
+
33
+ def test_00_list_hosted_zones
34
+ items = @r53.list_hosted_zones
35
+ assert items.is_a?(Array)
36
+ end
37
+
38
+ def test_create_and_delete_zone
39
+ response = @r53.create_hosted_zone(@zone_config)
40
+ assert_equal response[:name], @zone_config[:name]
41
+ assert response[:aws_id].is_a?(String)
42
+ assert response[:name_servers].is_a?(Array)
43
+
44
+ response2 = @r53.delete_hosted_zone(response[:aws_id])
45
+ assert_equal response2[:status], 'PENDING'
46
+ end
47
+
48
+ def test_add_and_remove_A_record
49
+ zone = @r53.create_hosted_zone(@zone_config)
50
+ zone_id = zone[:aws_id]
51
+ # add
52
+ a_record = { :name => 'host.right-aws.example.com.', :type => 'A', :ttl => 600, :resource_records => ['10.0.0.1'] }
53
+ response = @r53.create_resource_record_sets(zone_id, [a_record.dup]) # .dup since it will get :action => :create
54
+ assert_equal response[:status], 'PENDING'
55
+
56
+ # It should be there now
57
+ records = @r53.list_resource_record_sets(zone_id)
58
+ assert records.is_a?(Array)
59
+ assert records.detect { |rr| rr == a_record }, "Could not find '#{a_record.inspect}' in '#{records.inspect}'"
60
+
61
+ # remove
62
+ response = @r53.delete_resource_record_sets(zone_id, [a_record.dup])
63
+ assert_equal response[:status], 'PENDING'
64
+
65
+ # It should not be there anymore
66
+ records = @r53.list_resource_record_sets(zone_id)
67
+ assert records.is_a?(Array)
68
+ assert ! records.detect { |rr| rr == a_record }, "Record '#{a_record.inspect}' is still in '#{records.inspect}'"
69
+
70
+ @r53.delete_hosted_zone(zone_id)
71
+ end
72
+
73
+ def test_add_and_remove_Alias_record
74
+ lb = find_or_create_load_balancer
75
+
76
+ zone = @r53.create_hosted_zone(@zone_config)
77
+ zone_id = zone[:aws_id]
78
+
79
+ # add
80
+ alias_target = { :hosted_zone_id => lb[:canonical_hosted_zone_name_id], :dns_name => lb[:dns_name] }
81
+ alias_record = { :name => 'right-aws.example.com', :type => 'A', :alias_target => alias_target }
82
+ response = @r53.create_resource_record_sets(zone_id, [alias_record.dup]) # .dup since it will get :action => :create
83
+ assert_equal response[:status], 'PENDING'
84
+
85
+ # It should be there now
86
+ records = @r53.list_resource_record_sets(zone_id)
87
+ assert records.is_a?(Array)
88
+ record = records.detect { |rr| rr[:alias_target] }
89
+ assert record, "Could not find '#{alias_record.inspect}' in '#{records.inspect}'"
90
+ # AWS adds final dots to names
91
+ assert_equal "#{alias_record[:name]}.", record[:name]
92
+ assert_equal "#{alias_target[:dns_name]}.", record[:alias_target][:dns_name]
93
+
94
+ # remove
95
+ response = @r53.delete_resource_record_sets(zone_id, [alias_record.dup])
96
+ assert_equal response[:status], 'PENDING'
97
+
98
+ # It should not be there anymore
99
+ records = @r53.list_resource_record_sets(zone_id)
100
+ assert records.is_a?(Array)
101
+ record = records.detect { |rr| rr[:alias_target] }
102
+ assert ! record, "Record '#{alias_record.inspect}' is still in '#{records.inspect}'"
103
+
104
+ @r53.delete_hosted_zone(zone_id)
105
+ end
106
+
107
+ def find_or_create_load_balancer
108
+ unless @elb.describe_load_balancers.detect { |lb| lb[:load_balancer_name] == BALANCER_NAME }
109
+ @elb.create_load_balancer(BALANCER_NAME, %w[us-east-1b], [])
110
+ puts "WARNING: Started load balancer. Remember to shut it down (see teardown)."
111
+ puts "NOTE: Tests might not pass during first few seconds after load balancer is created."
112
+ end
113
+ @elb.describe_load_balancers.detect { |lb| lb[:load_balancer_name] == BALANCER_NAME }
114
+ end
115
+
116
+ def test_rr_sets_to_xml
117
+ a_record = { :name => 'host.right-aws.example.com.', :type => 'A', :ttl => 600, :resource_records => ['10.0.0.1'], :action => :create }
118
+ expected = load_fixture('a_record.xml')
119
+ assert_equal expected, @r53.resource_record_sets_to_xml([a_record], '')
120
+
121
+ # Note final full stop
122
+ alias_target = { :hosted_zone_id => 'Z1234567890123', :dns_name => 'example-load-balancer-1111111111.us-east-1.elb.amazonaws.com.' }
123
+ alias_record = { :name => 'right-aws.example.com.', :type => 'A', :alias_target => alias_target, :action => :create }
124
+ expected = load_fixture('alias_record.xml')
125
+ assert_same_lines expected, @r53.resource_record_sets_to_xml([alias_record], '')
126
+ end
127
+
128
+ def load_fixture (name)
129
+ File.read(File.join(File.dirname(__FILE__), 'fixtures', name))
130
+ end
131
+
132
+ def assert_same_lines (expected, actual)
133
+ expected = expected.split "\n"
134
+ actual = actual.split "\n"
135
+ previous = []
136
+ while e = expected.shift and a = actual.shift
137
+ assert_equal e, a, "After:\n#{previous.join("\n")}"
138
+ previous << e
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../../lib/right_aws'
@@ -0,0 +1,528 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestS3 < Test::Unit::TestCase
4
+
5
+ RIGHT_OBJECT_TEXT = 'Right test message'
6
+ INTERFACE = Rightscale::S3Interface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
7
+ CONNECTION = Rightscale::S3.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
8
+
9
+ def setup
10
+ @s3 = INTERFACE
11
+ @bucket = 'right_s3_awesome_test_bucket_000B1_officedrop'
12
+ @bucket2 = 'right_s3_awesome_test_bucket_000B2_officedrop'
13
+ @key1 = 'test/woohoo1/'
14
+ @key2 = 'test1/key/woohoo2'
15
+ @key3 = 'test2/A%B@C_D&E?F+G=H"I'
16
+ @key1_copy = 'test/woohoo1_2'
17
+ @key1_new_name = 'test/woohoo1_3'
18
+ @key2_new_name = 'test1/key/woohoo2_new'
19
+ @s = CONNECTION
20
+ end
21
+
22
+ #---------------------------
23
+ # Rightscale::S3Interface
24
+ #---------------------------
25
+
26
+ def test_01_create_bucket
27
+ assert @s3.create_bucket(@bucket), 'Create_bucket fail'
28
+ end
29
+
30
+ def test_02_list_all_my_buckets
31
+ assert @s3.list_all_my_buckets.map{|bucket| bucket[:name]}.include?(@bucket), "#{@bucket} must exist in bucket list"
32
+ end
33
+
34
+ def test_03_list_empty_bucket
35
+ assert_equal 0, @s3.list_bucket(@bucket).size, "#{@bucket} isn't empty, arrgh!"
36
+ end
37
+
38
+ def test_04_put
39
+ assert @s3.put(@bucket, @key1, RIGHT_OBJECT_TEXT, 'x-amz-meta-family'=>'Woohoo1!'), 'Put bucket fail'
40
+ assert @s3.put(@bucket, @key2, RIGHT_OBJECT_TEXT, 'x-amz-meta-family'=>'Woohoo2!'), 'Put bucket fail'
41
+ assert @s3.put(@bucket, @key3, RIGHT_OBJECT_TEXT, 'x-amz-meta-family'=>'Woohoo3!'), 'Put bucket fail'
42
+ end
43
+
44
+ def test_05_get_and_get_object
45
+ assert_raise(Rightscale::AwsError) { @s3.get(@bucket, 'undefined/key') }
46
+ data1 = @s3.get(@bucket, @key1)
47
+ assert_equal RIGHT_OBJECT_TEXT, data1[:object], "Object text must be equal to '#{RIGHT_OBJECT_TEXT}'"
48
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key1), "Get_object text must return '#{RIGHT_OBJECT_TEXT}'"
49
+ assert_equal 'Woohoo1!', data1[:headers]['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
50
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key3), "Get_object text must return '#{RIGHT_OBJECT_TEXT}'"
51
+ end
52
+
53
+ def test_06_head
54
+ assert_equal 'Woohoo1!', @s3.head(@bucket,@key1)['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
55
+ end
56
+
57
+
58
+ def test_07_streaming_get
59
+ resp = String.new
60
+ assert_raise(Rightscale::AwsError) do
61
+ @s3.get(@bucket, 'undefined/key') do |chunk|
62
+ resp += chunk
63
+ end
64
+ end
65
+
66
+ resp = String.new
67
+ data1 = @s3.get(@bucket, @key1) do |chunk|
68
+ resp += chunk
69
+ end
70
+ assert_equal RIGHT_OBJECT_TEXT, resp, "Object text must be equal to '#{RIGHT_OBJECT_TEXT}'"
71
+ assert_equal @s3.get_object(@bucket, @key1), resp, "Streaming iface must return same as non-streaming"
72
+ assert_equal 'Woohoo1!', data1[:headers]['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
73
+ end
74
+
75
+ def test_08_keys
76
+ keys = @s3.list_bucket(@bucket).map{|b| b[:key]}
77
+ assert_equal keys.size, 3, "There should be 3 keys"
78
+ assert(keys.include?(@key1))
79
+ assert(keys.include?(@key2))
80
+ assert(keys.include?(@key3))
81
+ end
82
+
83
+ def test_09_copy_key
84
+ #--- test COPY
85
+ # copy a key
86
+ assert @s3.copy(@bucket, @key1, @bucket, @key1_copy)
87
+ # check it was copied well
88
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key1_copy), "copied object must have the same data"
89
+ # check meta-headers were copied
90
+ headers = @s3.head(@bucket, @key1_copy)
91
+ assert_equal 'Woohoo1!', headers['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
92
+ #--- test REPLACE
93
+ assert @s3.copy(@bucket, @key1, @bucket, @key1_copy, :replace, 'x-amz-meta-family' => 'oooops!')
94
+ # check it was copied well
95
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key1_copy), "copied object must have the same data"
96
+ # check meta-headers were overwrittenn
97
+ headers = @s3.head(@bucket, @key1_copy)
98
+ assert_equal 'oooops!', headers['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'oooops!'"
99
+ end
100
+
101
+ def test_10_move_key
102
+ # move a key
103
+ assert @s3.move(@bucket, @key1, @bucket, @key1_new_name)
104
+ # check it's data was moved correctly
105
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key1_new_name), "moved object must have the same data"
106
+ # check meta-headers were moved
107
+ headers = @s3.head(@bucket, @key1_new_name)
108
+ assert_equal 'Woohoo1!', headers['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
109
+ # check the original key is not exists any more
110
+ keys = @s3.list_bucket(@bucket).map{|b| b[:key]}
111
+ assert(!keys.include?(@key1))
112
+ end
113
+
114
+ def test_11_rename_key
115
+ # rename a key
116
+ assert @s3.rename(@bucket, @key2, @key2_new_name)
117
+ # check the new key data
118
+ assert_equal RIGHT_OBJECT_TEXT, @s3.get_object(@bucket, @key2_new_name), "moved object must have the same data"
119
+ # check meta-headers
120
+ headers = @s3.head(@bucket, @key2_new_name)
121
+ assert_equal 'Woohoo2!', headers['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo2!'"
122
+ # check the original key is not exists any more
123
+ keys = @s3.list_bucket(@bucket).map{|b| b[:key]}
124
+ assert(!keys.include?(@key2))
125
+ end
126
+ def test_12_retrieve_object
127
+ assert_raise(Rightscale::AwsError) { @s3.retrieve_object(:bucket => @bucket, :key => 'undefined/key') }
128
+ data1 = @s3.retrieve_object(:bucket => @bucket, :key => @key1_new_name)
129
+ assert_equal RIGHT_OBJECT_TEXT, data1[:object], "Object text must be equal to '#{RIGHT_OBJECT_TEXT}'"
130
+ assert_equal 'Woohoo1!', data1[:headers]['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
131
+ end
132
+ def test_13_delete_folder
133
+ assert_equal 1, @s3.delete_folder(@bucket, 'test').size, "Only one key(#{@key1}) must be deleted!"
134
+ end
135
+
136
+ def test_14_delete_bucket
137
+ assert_raise(Rightscale::AwsError) { @s3.delete_bucket(@bucket) }
138
+ assert @s3.clear_bucket(@bucket), 'Clear_bucket fail'
139
+ assert_equal 0, @s3.list_bucket(@bucket).size, 'Bucket must be empty'
140
+ assert @s3.delete_bucket(@bucket)
141
+ assert !@s3.list_all_my_buckets.map{|bucket| bucket[:name]}.include?(@bucket), "#{@bucket} must not exist"
142
+ end
143
+
144
+
145
+
146
+
147
+ #---------------------------
148
+ # Rightscale::S3 classes
149
+ #---------------------------
150
+
151
+ def test_20_s3
152
+ # create bucket
153
+ bucket = @s.bucket(@bucket, true)
154
+ assert bucket
155
+ # check that the bucket exists
156
+ assert @s.buckets.map{|b| b.name}.include?(@bucket)
157
+ # delete bucket
158
+ assert bucket.clear
159
+ assert bucket.delete
160
+ end
161
+
162
+ def test_21_bucket_create_put_get_key
163
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, true)
164
+ # check that the bucket exists
165
+ assert @s.buckets.map{|b| b.name}.include?(@bucket)
166
+ assert bucket.keys.empty?
167
+ # put data
168
+ assert bucket.put(@key3, RIGHT_OBJECT_TEXT, {'family'=>'123456'})
169
+ # get data and compare
170
+ assert_equal RIGHT_OBJECT_TEXT, bucket.get(@key3)
171
+ # get key object
172
+ key = bucket.key(@key3, true)
173
+ assert_equal Rightscale::S3::Key, key.class
174
+ assert key.exists?
175
+ assert_equal '123456', key.meta_headers['family']
176
+ end
177
+
178
+ def test_22_keys
179
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
180
+ # create first key
181
+ key3 = Rightscale::S3::Key.create(bucket, @key3)
182
+ key3.refresh
183
+ assert key3.exists?
184
+ assert_equal '123456', key3.meta_headers['family']
185
+ # create second key
186
+ key2 = Rightscale::S3::Key.create(bucket, @key2)
187
+ assert !key2.refresh
188
+ assert !key2.exists?
189
+ assert_raise(Rightscale::AwsError) { key2.head }
190
+ # store key
191
+ key2.meta_headers = {'family'=>'111222333'}
192
+ assert key2.put(RIGHT_OBJECT_TEXT)
193
+ # make sure that the key exists
194
+ assert key2.refresh
195
+ assert key2.exists?
196
+ assert key2.head
197
+ # get its data
198
+ assert_equal RIGHT_OBJECT_TEXT, key2.get
199
+ # drop key
200
+ assert key2.delete
201
+ assert !key2.exists?
202
+ end
203
+
204
+ def test_23_rename_key
205
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
206
+ # -- 1 -- (key based rename)
207
+ # create a key
208
+ key = bucket.key('test/copy/1')
209
+ key.put(RIGHT_OBJECT_TEXT)
210
+ original_key = key.clone
211
+ assert key.exists?, "'test/copy/1' should exist"
212
+ # rename it
213
+ key.rename('test/copy/2')
214
+ assert_equal 'test/copy/2', key.name
215
+ assert key.exists?, "'test/copy/2' should exist"
216
+ # the original key should not exist
217
+ assert !original_key.exists?, "'test/copy/1' should not exist"
218
+ # -- 2 -- (bucket based rename)
219
+ bucket.rename_key('test/copy/2', 'test/copy/3')
220
+ assert bucket.key('test/copy/3').exists?, "'test/copy/3' should exist"
221
+ assert !bucket.key('test/copy/2').exists?, "'test/copy/2' should not exist"
222
+ end
223
+
224
+ def test_24_copy_key
225
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
226
+ # -- 1 -- (key based copy)
227
+ # create a key
228
+ key = bucket.key('test/copy/10')
229
+ key.put(RIGHT_OBJECT_TEXT)
230
+ # make copy
231
+ new_key = key.copy('test/copy/11')
232
+ # make sure both the keys exist and have a correct data
233
+ assert key.exists?, "'test/copy/10' should exist"
234
+ assert new_key.exists?, "'test/copy/11' should exist"
235
+ assert_equal RIGHT_OBJECT_TEXT, key.get
236
+ assert_equal RIGHT_OBJECT_TEXT, new_key.get
237
+ # -- 2 -- (bucket based copy)
238
+ bucket.copy_key('test/copy/11', 'test/copy/12')
239
+ assert bucket.key('test/copy/11').exists?, "'test/copy/11' should exist"
240
+ assert bucket.key('test/copy/12').exists?, "'test/copy/12' should exist"
241
+ assert_equal RIGHT_OBJECT_TEXT, bucket.key('test/copy/11').get
242
+ assert_equal RIGHT_OBJECT_TEXT, bucket.key('test/copy/12').get
243
+ end
244
+
245
+ def test_25_move_key
246
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
247
+ # -- 1 -- (key based copy)
248
+ # create a key
249
+ key = bucket.key('test/copy/20')
250
+ key.put(RIGHT_OBJECT_TEXT)
251
+ # move
252
+ new_key = key.move('test/copy/21')
253
+ # make sure both the keys exist and have a correct data
254
+ assert !key.exists?, "'test/copy/20' should not exist"
255
+ assert new_key.exists?, "'test/copy/21' should exist"
256
+ assert_equal RIGHT_OBJECT_TEXT, new_key.get
257
+ # -- 2 -- (bucket based copy)
258
+ bucket.copy_key('test/copy/21', 'test/copy/22')
259
+ assert bucket.key('test/copy/21').exists?, "'test/copy/21' should not exist"
260
+ assert bucket.key('test/copy/22').exists?, "'test/copy/22' should exist"
261
+ assert_equal RIGHT_OBJECT_TEXT, bucket.key('test/copy/22').get
262
+ end
263
+
264
+ def test_26_save_meta
265
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
266
+ # create a key
267
+ key = bucket.key('test/copy/30')
268
+ key.put(RIGHT_OBJECT_TEXT)
269
+ assert key.meta_headers.right_blank?
270
+ # store some meta keys
271
+ meta = {'family' => 'oops','race' => 'troll'}
272
+ assert_equal meta, key.save_meta(meta)
273
+ # reload meta
274
+ assert_equal meta, key.reload_meta
275
+ end
276
+
277
+ def test_27_clear_delete
278
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
279
+ # add another key
280
+ bucket.put(@key2, RIGHT_OBJECT_TEXT)
281
+ # delete 'folder'
282
+ assert_equal 1, bucket.delete_folder(@key1).size
283
+ # delete
284
+ assert_raise(Rightscale::AwsError) { bucket.delete }
285
+ bucket.delete(:force => true)
286
+ end
287
+
288
+ # Grantees
289
+
290
+ def test_30_create_bucket
291
+ bucket = @s.bucket(@bucket, true, 'public-read')
292
+ assert bucket
293
+ end
294
+
295
+ def test_31_list_grantees
296
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
297
+ # get grantees list
298
+ grantees = bucket.grantees
299
+ # check that the grantees count equal to 2 (root, AllUsers)
300
+ assert_equal 2, grantees.size
301
+ end
302
+
303
+ def test_32_grant_revoke_drop
304
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
305
+ # Take 'AllUsers' grantee
306
+ grantee = Rightscale::S3::Grantee.new(bucket,'http://acs.amazonaws.com/groups/global/AllUsers')
307
+ # Check exists?
308
+ assert grantee.exists?
309
+ # Add grant as String
310
+ assert grantee.grant('WRITE')
311
+ # Add grants as Array
312
+ assert grantee.grant(['READ_ACP', 'WRITE_ACP'])
313
+ # Check perms count
314
+ assert_equal 4, grantee.perms.size
315
+ # revoke 'WRITE_ACP'
316
+ assert grantee.revoke('WRITE_ACP')
317
+ # Check manual perm removal method
318
+ grantee.perms -= ['READ_ACP']
319
+ grantee.apply
320
+ assert_equal 2, grantee.perms.size
321
+ # Check grantee removal if it has no permissions
322
+ assert grantee.perms = []
323
+ assert grantee.apply
324
+ assert !grantee.exists?
325
+ # Check multiple perms assignment
326
+ assert grantee.grant('FULL_CONTROL', 'READ', 'WRITE')
327
+ assert_equal ['FULL_CONTROL','READ','WRITE'].sort, grantee.perms.sort
328
+ # Check multiple perms removal
329
+ assert grantee.revoke('FULL_CONTROL', 'WRITE')
330
+ assert_equal ['READ'], grantee.perms
331
+ # check 'Drop' method
332
+ assert grantee.drop
333
+ assert !grantee.exists?
334
+ assert_equal 1, bucket.grantees.size
335
+ # Delete bucket
336
+ bucket.delete(:force => true)
337
+ end
338
+
339
+ def test_33_key_grantees
340
+ # Create bucket
341
+ bucket = @s.bucket(@bucket, true)
342
+ # Create key
343
+ key = bucket.key(@key1)
344
+ assert key.put(RIGHT_OBJECT_TEXT, 'public-read')
345
+ # Get grantees list (must be == 2)
346
+ grantees = key.grantees
347
+ assert grantees
348
+ assert_equal 2, grantees.size
349
+ # Take one of grantees and give him 'Write' perms
350
+ grantee = grantees[0]
351
+ assert grantee.grant('WRITE')
352
+ # Drop grantee
353
+ assert grantee.drop
354
+ # Drop bucket
355
+ bucket.delete(:force => true)
356
+ end
357
+
358
+ def test_34_bucket_create_put_with_perms
359
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, true)
360
+ # check that the bucket exists
361
+ assert @s.buckets.map{|b| b.name}.include?(@bucket)
362
+ assert bucket.keys.empty?
363
+ # put data (with canned ACL)
364
+ assert bucket.put(@key1, RIGHT_OBJECT_TEXT, {'family'=>'123456'}, "public-read")
365
+ # get data and compare
366
+ assert_equal RIGHT_OBJECT_TEXT, bucket.get(@key1)
367
+ # get key object
368
+ key = bucket.key(@key1, true)
369
+ assert_equal Rightscale::S3::Key, key.class
370
+ assert key.exists?
371
+ assert_equal '123456', key.meta_headers['family']
372
+ end
373
+
374
+ def test_35_key_put_with_perms
375
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
376
+ # create first key
377
+ key1 = Rightscale::S3::Key.create(bucket, @key1)
378
+ key1.refresh
379
+ assert key1.exists?
380
+ assert key1.put(RIGHT_OBJECT_TEXT, "public-read")
381
+ # get its data
382
+ assert_equal RIGHT_OBJECT_TEXT, key1.get
383
+ # drop key
384
+ assert key1.delete
385
+ assert !key1.exists?
386
+ end
387
+
388
+ def test_36_set_amazon_problems
389
+ original_problems = RightAws::S3Interface.amazon_problems
390
+ assert(original_problems.length > 0)
391
+ RightAws::S3Interface.amazon_problems= original_problems << "A New Problem"
392
+ new_problems = RightAws::S3Interface.amazon_problems
393
+ assert_equal(new_problems, original_problems)
394
+
395
+ RightAws::S3Interface.amazon_problems= nil
396
+ assert_nil(RightAws::S3Interface.amazon_problems)
397
+ end
398
+
399
+ def test_37_access_logging
400
+ bucket = Rightscale::S3::Bucket.create(@s, @bucket, false)
401
+ targetbucket = Rightscale::S3::Bucket.create(@s, @bucket2, true)
402
+ # Take 'AllUsers' grantee
403
+ grantee = Rightscale::S3::Grantee.new(targetbucket,'http://acs.amazonaws.com/groups/s3/LogDelivery')
404
+
405
+ assert grantee.grant(['READ_ACP', 'WRITE'])
406
+
407
+ assert bucket.enable_logging(:targetbucket => targetbucket, :targetprefix => "loggylogs/")
408
+ sleep 10
409
+
410
+ assert_equal({:enabled => true, :targetbucket => @bucket2, :targetprefix => "loggylogs/"}, bucket.logging_info)
411
+
412
+ assert bucket.disable_logging
413
+
414
+ # check 'Drop' method
415
+ assert grantee.drop
416
+ end
417
+
418
+ def test_40_delete_buckets
419
+ Rightscale::S3::Bucket.create(@s, @bucket, false).delete(:force => true)
420
+ Rightscale::S3::Bucket.create(@s, @bucket2, false).delete(:force => true)
421
+ end
422
+
423
+ def test_41_add_cache_control_response_parameter
424
+ @cache_control = 'max-age=3600'
425
+ perform_request( 'response-cache-control' => @cache_control ) do |response|
426
+ assert_equal response['Cache-Control'], @cache_control
427
+ end
428
+ end
429
+
430
+ def test_42_add_cache_control_and_content_type_and_content_disposition
431
+ @cache_control = 'max-age=3600'
432
+ @content_type = 'text/plain'
433
+ @content_disposition = 'attachment; filename=sample.txt'
434
+ perform_request(
435
+ 'response-cache-control' => @cache_control,
436
+ 'response-content-type' => @content_type,
437
+ 'response-content-disposition' => @content_disposition
438
+ ) do |response|
439
+ assert_equal response['Cache-Control'], @cache_control
440
+ assert_equal response['Content-Type'], @content_type
441
+ assert_equal response['Content-Disposition'], @content_disposition
442
+ end
443
+ end
444
+
445
+ def test_43_add_expires_and_content_type_and_content_disposition
446
+ @expires = 'Sun, 26 Jun 2011 02:58:26 GMT'
447
+ @content_type = 'text/plain'
448
+ @content_disposition = 'attachment; filename=sample.txt'
449
+ perform_request(
450
+ 'response-expires' => @expires,
451
+ 'response-content-type' => @content_type,
452
+ 'response-content-disposition' => @content_disposition
453
+ ) do |response|
454
+ assert_equal response['Expires'], @expires
455
+ assert_equal response['Content-Type'], @content_type
456
+ assert_equal response['Content-Disposition'], @content_disposition
457
+ end
458
+ end
459
+
460
+ def test_44_delete_multiple
461
+ bucket = RightAws::S3::Bucket.create(@s, @bucket, true)
462
+
463
+ key1 = Rightscale::S3::Key.create(bucket, @key1)
464
+ key2 = Rightscale::S3::Key.create(bucket, @key2)
465
+ key3 = Rightscale::S3::Key.create(bucket, @key3)
466
+
467
+ assert @s3.put(@bucket, @key1, RIGHT_OBJECT_TEXT), 'Put bucket fail'
468
+ assert @s3.put(@bucket, @key2, RIGHT_OBJECT_TEXT), 'Put bucket fail'
469
+ assert @s3.put(@bucket, @key3, RIGHT_OBJECT_TEXT), 'Put bucket fail'
470
+
471
+ key1.refresh
472
+ key2.refresh
473
+ key3.refresh
474
+
475
+ assert key1.exists?
476
+ assert key2.exists?
477
+ assert key3.exists?
478
+
479
+ result = @s3.delete_multiple(@bucket, [@key1, @key2, @key3])
480
+ assert result.empty?
481
+
482
+ key1.refresh
483
+ key2.refresh
484
+ key3.refresh
485
+
486
+ assert !key1.exists?
487
+ assert !key2.exists?
488
+ assert !key3.exists?
489
+ end
490
+
491
+ def test_45_delete_multiple_more_than_1000_objects
492
+ n = 1200
493
+ keys = (1..n).map { |i| "key-#{i}"}
494
+
495
+ keys.each do |key|
496
+ assert @s3.put(@bucket, key, RIGHT_OBJECT_TEXT), 'Put bucket fail'
497
+ end
498
+
499
+ result = @s3.delete_multiple(@bucket, keys)
500
+ assert result.empty?
501
+
502
+ keys_after = @s3.list_bucket(@bucket).map { |obj| obj[:key] }
503
+
504
+ keys.each do |key|
505
+ keys_after.include?(key)
506
+ end
507
+ end
508
+
509
+ private
510
+
511
+ def request( uri )
512
+ url = URI.parse( uri )
513
+
514
+ http = Net::HTTP.new(url.host, 443)
515
+ http.use_ssl = true
516
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
517
+ http.request(Net::HTTP::Get.new( url.request_uri ))
518
+ end
519
+
520
+ def perform_request( headers, &block )
521
+ @s3.create_bucket( @bucket )
522
+ @s3.put( @bucket, @key2, RIGHT_OBJECT_TEXT )
523
+ response = request( @s3.get_link( @bucket, @key2, nil, {}, headers ) )
524
+ block.call( response )
525
+ @s3.force_delete_bucket(@bucket)
526
+ end
527
+
528
+ end