fmalamitsas-aws-s3 0.6.2.1254423625

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 (93) hide show
  1. data/CHANGELOG +107 -0
  2. data/COPYING +19 -0
  3. data/INSTALL +55 -0
  4. data/README.erb +58 -0
  5. data/Rakefile +334 -0
  6. data/TODO +26 -0
  7. data/aws-s3.gemspec +42 -0
  8. data/bin/s3sh +6 -0
  9. data/bin/setup.rb +10 -0
  10. data/lib/aws/s3.rb +60 -0
  11. data/lib/aws/s3/acl.rb +636 -0
  12. data/lib/aws/s3/authentication.rb +222 -0
  13. data/lib/aws/s3/base.rb +270 -0
  14. data/lib/aws/s3/bittorrent.rb +58 -0
  15. data/lib/aws/s3/bucket.rb +372 -0
  16. data/lib/aws/s3/connection.rb +288 -0
  17. data/lib/aws/s3/error.rb +69 -0
  18. data/lib/aws/s3/exceptions.rb +133 -0
  19. data/lib/aws/s3/extensions.rb +342 -0
  20. data/lib/aws/s3/logging.rb +317 -0
  21. data/lib/aws/s3/object.rb +626 -0
  22. data/lib/aws/s3/owner.rb +46 -0
  23. data/lib/aws/s3/parsing.rb +99 -0
  24. data/lib/aws/s3/response.rb +180 -0
  25. data/lib/aws/s3/service.rb +51 -0
  26. data/lib/aws/s3/version.rb +12 -0
  27. data/site/index.erb +41 -0
  28. data/site/public/images/box-and-gem.gif +0 -0
  29. data/site/public/images/favicon.ico +0 -0
  30. data/site/public/ruby.css +18 -0
  31. data/site/public/screen.css +99 -0
  32. data/support/faster-xml-simple/COPYING +18 -0
  33. data/support/faster-xml-simple/README +8 -0
  34. data/support/faster-xml-simple/Rakefile +54 -0
  35. data/support/faster-xml-simple/lib/faster_xml_simple.rb +190 -0
  36. data/support/faster-xml-simple/test/fixtures/test-1.rails.yml +4 -0
  37. data/support/faster-xml-simple/test/fixtures/test-1.xml +3 -0
  38. data/support/faster-xml-simple/test/fixtures/test-1.yml +4 -0
  39. data/support/faster-xml-simple/test/fixtures/test-2.rails.yml +6 -0
  40. data/support/faster-xml-simple/test/fixtures/test-2.xml +3 -0
  41. data/support/faster-xml-simple/test/fixtures/test-2.yml +6 -0
  42. data/support/faster-xml-simple/test/fixtures/test-3.rails.yml +6 -0
  43. data/support/faster-xml-simple/test/fixtures/test-3.xml +5 -0
  44. data/support/faster-xml-simple/test/fixtures/test-3.yml +6 -0
  45. data/support/faster-xml-simple/test/fixtures/test-4.rails.yml +5 -0
  46. data/support/faster-xml-simple/test/fixtures/test-4.xml +7 -0
  47. data/support/faster-xml-simple/test/fixtures/test-4.yml +5 -0
  48. data/support/faster-xml-simple/test/fixtures/test-5.rails.yml +8 -0
  49. data/support/faster-xml-simple/test/fixtures/test-5.xml +7 -0
  50. data/support/faster-xml-simple/test/fixtures/test-5.yml +8 -0
  51. data/support/faster-xml-simple/test/fixtures/test-6.rails.yml +43 -0
  52. data/support/faster-xml-simple/test/fixtures/test-6.xml +29 -0
  53. data/support/faster-xml-simple/test/fixtures/test-6.yml +41 -0
  54. data/support/faster-xml-simple/test/fixtures/test-7.rails.yml +23 -0
  55. data/support/faster-xml-simple/test/fixtures/test-7.xml +22 -0
  56. data/support/faster-xml-simple/test/fixtures/test-7.yml +22 -0
  57. data/support/faster-xml-simple/test/fixtures/test-8.rails.yml +14 -0
  58. data/support/faster-xml-simple/test/fixtures/test-8.xml +8 -0
  59. data/support/faster-xml-simple/test/fixtures/test-8.yml +11 -0
  60. data/support/faster-xml-simple/test/regression_test.rb +47 -0
  61. data/support/faster-xml-simple/test/test_helper.rb +17 -0
  62. data/support/faster-xml-simple/test/xml_simple_comparison_test.rb +46 -0
  63. data/support/rdoc/code_info.rb +211 -0
  64. data/test/acl_test.rb +254 -0
  65. data/test/authentication_test.rb +118 -0
  66. data/test/base_test.rb +136 -0
  67. data/test/bucket_test.rb +74 -0
  68. data/test/connection_test.rb +216 -0
  69. data/test/error_test.rb +70 -0
  70. data/test/extensions_test.rb +340 -0
  71. data/test/fixtures.rb +89 -0
  72. data/test/fixtures/buckets.yml +133 -0
  73. data/test/fixtures/errors.yml +34 -0
  74. data/test/fixtures/headers.yml +3 -0
  75. data/test/fixtures/logging.yml +15 -0
  76. data/test/fixtures/loglines.yml +5 -0
  77. data/test/fixtures/logs.yml +7 -0
  78. data/test/fixtures/policies.yml +16 -0
  79. data/test/logging_test.rb +89 -0
  80. data/test/mocks/fake_response.rb +26 -0
  81. data/test/object_test.rb +205 -0
  82. data/test/parsing_test.rb +66 -0
  83. data/test/remote/acl_test.rb +116 -0
  84. data/test/remote/bittorrent_test.rb +45 -0
  85. data/test/remote/bucket_test.rb +146 -0
  86. data/test/remote/logging_test.rb +82 -0
  87. data/test/remote/object_test.rb +379 -0
  88. data/test/remote/test_file.data +0 -0
  89. data/test/remote/test_helper.rb +33 -0
  90. data/test/response_test.rb +68 -0
  91. data/test/service_test.rb +23 -0
  92. data/test/test_helper.rb +118 -0
  93. metadata +241 -0
@@ -0,0 +1,89 @@
1
+ require 'yaml'
2
+
3
+ module AWS
4
+ module S3
5
+ # When this file is loaded, for each fixture file, a module is created within the Fixtures module
6
+ # with the same name as the fixture file. For each fixture in that fixture file, a singleton method is
7
+ # added to the module with the name of the given fixture, returning the value of the fixture.
8
+ #
9
+ # For example:
10
+ #
11
+ # A fixture in <tt>buckets.yml</tt> named <tt>empty_bucket_list</tt> with value <tt><foo>hi!</foo></tt>
12
+ # would be made available like so:
13
+ #
14
+ # Fixtures::Buckets.empty_bucket_list
15
+ # => "<foo>hi!</foo>"
16
+ #
17
+ # Alternatively you can treat the fixture module like a hash
18
+ #
19
+ # Fixtures::Buckets[:empty_bucket_list]
20
+ # => "<foo>hi!</foo>"
21
+ #
22
+ # You can find out all available fixtures by calling
23
+ #
24
+ # Fixtures.fixtures
25
+ # => ["Buckets"]
26
+ #
27
+ # And all the fixtures contained in a given fixture by calling
28
+ #
29
+ # Fixtures::Buckets.fixtures
30
+ # => ["bucket_list_with_more_than_one_bucket", "bucket_list_with_one_bucket", "empty_bucket_list"]
31
+ module Fixtures
32
+ class << self
33
+ def create_fixtures
34
+ files.each do |file|
35
+ create_fixture_for(file)
36
+ end
37
+ end
38
+
39
+ def create_fixture_for(file)
40
+ fixtures = YAML.load_file(path(file))
41
+ fixture_module = Module.new
42
+
43
+ fixtures.each do |name, value|
44
+ fixture_module.module_eval(<<-EVAL, __FILE__, __LINE__)
45
+ def #{name}
46
+ #{value.inspect}
47
+ end
48
+ module_function :#{name}
49
+ EVAL
50
+ end
51
+
52
+ fixture_module.module_eval(<<-EVAL, __FILE__, __LINE__)
53
+ module_function
54
+
55
+ def fixtures
56
+ #{fixtures.keys.sort.inspect}
57
+ end
58
+
59
+ def [](name)
60
+ send(name) if fixtures.include?(name.to_s)
61
+ end
62
+ EVAL
63
+
64
+ const_set(module_name(file), fixture_module)
65
+ end
66
+
67
+ def fixtures
68
+ constants.sort
69
+ end
70
+
71
+ private
72
+
73
+ def files
74
+ Dir.glob(File.dirname(__FILE__) + '/fixtures/*.yml').map {|fixture| File.basename(fixture)}
75
+ end
76
+
77
+ def module_name(file_name)
78
+ File.basename(file_name, '.*').capitalize
79
+ end
80
+
81
+ def path(file_name)
82
+ File.join(File.dirname(__FILE__), 'fixtures', file_name)
83
+ end
84
+ end
85
+
86
+ create_fixtures
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,133 @@
1
+ empty_bucket_list: >
2
+ <ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
3
+ <Owner>
4
+ <ID>ab00c3106e091f8fe23154c85678cda66628adb330bc00f02cf4a1c36d76bc48</ID>
5
+ <DisplayName>amazon</DisplayName>
6
+ </Owner>
7
+ <Buckets/>
8
+ </ListAllMyBucketsResult>
9
+
10
+
11
+ bucket_list_with_one_bucket: >
12
+ <ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
13
+ <Owner>
14
+ <ID>ab00c3106e091f8fe23154c85678cda66628adb330bc00f02cf4a1c36d76bc48</ID>
15
+ <DisplayName>amazon</DisplayName>
16
+ </Owner>
17
+ <Buckets>
18
+ <Bucket>
19
+ <Name>marcel_molina</Name>
20
+ <CreationDate>2006-10-04T15:58:38.000Z</CreationDate>
21
+ </Bucket>
22
+ </Buckets>
23
+ </ListAllMyBucketsResult>
24
+
25
+
26
+ bucket_list_with_more_than_one_bucket: >
27
+ <ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
28
+ <Owner>
29
+ <ID>ab00c3106e091f8fe23154c85678cda66628adb330bc00f02cf4a1c36d76bc48</ID>
30
+ <DisplayName>amazon</DisplayName>
31
+ </Owner>
32
+ <Buckets>
33
+ <Bucket>
34
+ <Name>marcel_molina</Name>
35
+ <CreationDate>2006-10-04T15:58:38.000Z</CreationDate>
36
+ </Bucket>
37
+ <Bucket>
38
+ <Name>marcel_molina_jr</Name>
39
+ <CreationDate>2006-10-04T16:01:30.000Z</CreationDate>
40
+ </Bucket>
41
+ </Buckets>
42
+ </ListAllMyBucketsResult>
43
+
44
+ empty_bucket: >
45
+ <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
46
+ <Name>marcel_molina</Name>
47
+ <Prefix></Prefix>
48
+ <Marker></Marker>
49
+ <MaxKeys>1000</MaxKeys>
50
+ <IsTruncated>false</IsTruncated>
51
+ </ListBucketResult>
52
+
53
+ bucket_with_one_key: >
54
+ <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
55
+ <Name>marcel_molina</Name>
56
+ <Prefix></Prefix>
57
+ <Marker></Marker>
58
+ <MaxKeys>1000</MaxKeys>
59
+ <IsTruncated>false</IsTruncated>
60
+ <Contents>
61
+ <Key>tongue_overload.jpg</Key>
62
+ <LastModified>2006-10-05T02:42:22.000Z</LastModified>
63
+ <ETag>&quot;f21f7c4e8ea6e34b268887b07d6da745&quot;</ETag>
64
+ <Size>60673</Size>
65
+ <Owner>
66
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
67
+ <DisplayName>mmolina@onramp.net</DisplayName>
68
+ </Owner>
69
+ <StorageClass>STANDARD</StorageClass>
70
+ </Contents>
71
+ </ListBucketResult>
72
+
73
+ bucket_with_more_than_one_key: >
74
+ <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
75
+ <Name>marcel_molina</Name>
76
+ <Prefix></Prefix>
77
+ <Marker></Marker>
78
+ <MaxKeys>1000</MaxKeys>
79
+ <IsTruncated>false</IsTruncated>
80
+ <Contents>
81
+ <Key>beluga_baby.jpg</Key>
82
+ <LastModified>2006-10-05T02:55:10.000Z</LastModified>
83
+ <ETag>&quot;b2453d4a39a7387674a8c505112a2f0b&quot;</ETag>
84
+ <Size>35807</Size>
85
+ <Owner>
86
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
87
+ <DisplayName>mmolina@onramp.net</DisplayName>
88
+ </Owner>
89
+ <StorageClass>STANDARD</StorageClass>
90
+ </Contents>
91
+ <Contents>
92
+ <Key>tongue_overload.jpg</Key>
93
+ <LastModified>2006-10-05T02:42:22.000Z</LastModified>
94
+ <ETag>&quot;f21f7c4e8ea6e34b268887b07d6da745&quot;</ETag>
95
+ <Size>60673</Size>
96
+ <Owner>
97
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
98
+ <DisplayName>mmolina@onramp.net</DisplayName>
99
+ </Owner>
100
+ <StorageClass>STANDARD</StorageClass>
101
+ </Contents>
102
+ </ListBucketResult>
103
+
104
+ truncated_bucket_with_more_than_one_key: >
105
+ <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
106
+ <Name>marcel_molina</Name>
107
+ <Prefix></Prefix>
108
+ <Marker></Marker>
109
+ <MaxKeys>2</MaxKeys>
110
+ <IsTruncated>true</IsTruncated>
111
+ <Contents>
112
+ <Key>beluga_baby.jpg</Key>
113
+ <LastModified>2006-10-05T02:55:10.000Z</LastModified>
114
+ <ETag>&quot;b2453d4a39a7387674a8c505112a2f0b&quot;</ETag>
115
+ <Size>35807</Size>
116
+ <Owner>
117
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
118
+ <DisplayName>mmolina@onramp.net</DisplayName>
119
+ </Owner>
120
+ <StorageClass>STANDARD</StorageClass>
121
+ </Contents>
122
+ <Contents>
123
+ <Key>tongue_overload.jpg</Key>
124
+ <LastModified>2006-10-05T02:42:22.000Z</LastModified>
125
+ <ETag>&quot;f21f7c4e8ea6e34b268887b07d6da745&quot;</ETag>
126
+ <Size>60673</Size>
127
+ <Owner>
128
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
129
+ <DisplayName>mmolina@onramp.net</DisplayName>
130
+ </Owner>
131
+ <StorageClass>STANDARD</StorageClass>
132
+ </Contents>
133
+ </ListBucketResult>
@@ -0,0 +1,34 @@
1
+ not_implemented: >
2
+ <Error>
3
+ <Code>NotImplemented</Code>
4
+ <Message>A header you provided implies functionality that is not implemented</Message>
5
+ <RequestId>D1D13A09AC92427F</RequestId>
6
+ <Header>Host</Header>
7
+ <HostId>oNZgzTTmWiovwGGwHXAzz+1vRmAJVAplS9TF7B0cuOGfEwoi7DYSTa/1Qhv90CfW</HostId>
8
+ </Error>
9
+
10
+ access_denied: >
11
+ <Error>
12
+ <Code>AccessDenied</Code>
13
+ <Message>Access Denied</Message>
14
+ <RequestId>F99F6D58B96C98E0</RequestId>
15
+ <HostId>XwCF7k3llrcEwtoHR7MusZ6ilCdF5DKDmwYpglvjKNjvwo24INCeXlEpo1M03Wxm</HostId>
16
+ </Error>
17
+
18
+ internal_error: >
19
+ <Error>
20
+ <Code>InternalError</Code>
21
+ <Message>Internal Error</Message>
22
+ <RequestId>F99F6D223B96C98E0</RequestId>
23
+ <HostId>XwCF7k3llrcEwtoHR7MusZ6ilCdF5DKDmwYpglvjKNjvwo24INCeXlEpo1M03Wxm</HostId>
24
+ </Error>
25
+
26
+ error_with_no_message: >
27
+ <Error>
28
+ <Code>InvalidArgument</Code>
29
+ <Message></Message>
30
+ <ArgumentValue>READ</ArgumentValue>
31
+ <RequestId>74A377B1C0FA2BCF</RequestId>
32
+ <HostId>cP4rqsAEtHpN6Ckv08Hr3LXjLzx15/YgyoSqzs779vMR8MrAFSodxZp96wtuMQuI</HostId>
33
+ <ArgumentName>x-amz-acl</ArgumentName>
34
+ </Error>
@@ -0,0 +1,3 @@
1
+ headers_including_one_piece_of_metadata:
2
+ x-amz-meta-test: foo
3
+ content_type: text/plain
@@ -0,0 +1,15 @@
1
+ logging_enabled: >
2
+ <BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
3
+ <LoggingEnabled>
4
+ <TargetBucket>mylogs</TargetBucket>
5
+ <TargetPrefix>access_log-</TargetPrefix>
6
+ </LoggingEnabled>
7
+ </BucketLoggingStatus>
8
+
9
+ logging_disabled: >
10
+ <BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
11
+ <!--<LoggingEnabled>
12
+ <TargetBucket>myLogsBucket</TargetBucket>
13
+ <TargetPrefix>add/this/prefix/to/my/log/files/access_log-</TargetPrefix>
14
+ </LoggingEnabled>-->
15
+ </BucketLoggingStatus>
@@ -0,0 +1,5 @@
1
+ bucket_get:
2
+ "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
3
+
4
+ browser_get:
5
+ "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
@@ -0,0 +1,7 @@
1
+ simple_log:
2
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
3
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:38:58 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8F6F3C4027849420 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 458 456 \"-\" \"-\"\n"
4
+
5
+ requests_from_a_browser:
6
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
7
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:27 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 88629578AFDDD9B5 REST.GET.TORRENT kiss.jpg \"GET /marcel/kiss.jpg?torrent HTTP/1.1\" 200 - 215 - 379 - \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
@@ -0,0 +1,16 @@
1
+ policy_with_one_grant: >
2
+ <AccessControlPolicy>
3
+ <Owner>
4
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
5
+ <DisplayName>mmolina@onramp.net</DisplayName>
6
+ </Owner>
7
+ <AccessControlList>
8
+ <Grant>
9
+ <Grantee xsi:type="CanonicalUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
10
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
11
+ <DisplayName>mmolina@onramp.net</DisplayName>
12
+ </Grantee>
13
+ <Permission>FULL_CONTROL</Permission>
14
+ </Grant>
15
+ </AccessControlList>
16
+ </AccessControlPolicy>
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class LoggingStatusReadingTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @disabled = logging_status(:logging_disabled)
7
+ @enabled = logging_status(:logging_enabled)
8
+ @new_status = Logging::Status.new('target_bucket' => 'foo', 'target_prefix' => 'access-log-')
9
+ end
10
+
11
+ def test_logging_enabled?
12
+ assert !@disabled.logging_enabled?
13
+ assert !@new_status.logging_enabled?
14
+ assert @enabled.logging_enabled?
15
+ end
16
+
17
+ def test_passing_in_prefix_and_bucket
18
+ assert_equal 'foo', @new_status.target_bucket
19
+ assert_equal 'access-log-', @new_status.target_prefix
20
+ assert !@new_status.logging_enabled?
21
+ end
22
+
23
+ private
24
+ def logging_status(fixture)
25
+ Logging::Status.new(Parsing::XmlParser.new(Fixtures::Logging[fixture.to_s]))
26
+ end
27
+ end
28
+
29
+ class LoggingStatusWritingTest < LoggingStatusReadingTest
30
+ def setup
31
+ super
32
+ @disabled = Logging::Status.new(Parsing::XmlParser.new(@disabled.to_xml))
33
+ @enabled = Logging::Status.new(Parsing::XmlParser.new(@enabled.to_xml))
34
+ end
35
+ end
36
+
37
+ class LogTest < Test::Unit::TestCase
38
+ def test_value_converted_to_log_lines
39
+ log_object = S3Object.new
40
+ log_object.value = Fixtures::Logs.simple_log.join
41
+ log = Logging::Log.new(log_object)
42
+ assert_nothing_raised do
43
+ log.lines
44
+ end
45
+
46
+ assert_equal 2, log.lines.size
47
+ assert_kind_of Logging::Log::Line, log.lines.first
48
+ assert_equal 'marcel', log.lines.first.bucket
49
+ end
50
+ end
51
+
52
+ class LogLineTest < Test::Unit::TestCase
53
+ def setup
54
+ @line = Logging::Log::Line.new(Fixtures::Loglines.bucket_get)
55
+ end
56
+
57
+ def test_field_accessors
58
+ expected_results = {
59
+ :owner => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
60
+ :bucket => 'marcel',
61
+ :time => Time.parse('Nov 14 2006 06:36:48 +0000'),
62
+ :remote_ip => '67.165.183.125',
63
+ :request_id => '8B5297D428A05432',
64
+ :requestor => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
65
+ :operation => 'REST.GET.BUCKET',
66
+ :key => nil,
67
+ :request_uri => 'GET /marcel HTTP/1.1',
68
+ :http_status => 200,
69
+ :error_code => nil,
70
+ :bytes_sent => 4534,
71
+ :object_size => nil,
72
+ :total_time => 398,
73
+ :turn_around_time => 395,
74
+ :referrer => nil,
75
+ :user_agent => nil
76
+ }
77
+
78
+ expected_results.each do |field, expected|
79
+ assert_equal expected, @line.send(field)
80
+ end
81
+
82
+ assert_equal expected_results, @line.attributes
83
+ end
84
+
85
+ def test_user_agent
86
+ line = Logging::Log::Line.new(Fixtures::Loglines.browser_get)
87
+ assert_equal 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0', line.user_agent
88
+ end
89
+ end
@@ -0,0 +1,26 @@
1
+ module AWS
2
+ module S3
3
+ class FakeResponse
4
+ attr_reader :code, :body, :headers
5
+ def initialize(options = {})
6
+ @code = options.delete(:code) || 200
7
+ @body = options.delete(:body) || ''
8
+ @headers = {'content-type' => 'application/xml'}.merge(options.delete(:headers) || {})
9
+ end
10
+
11
+ # For ErrorResponse
12
+ def response
13
+ body
14
+ end
15
+
16
+ def [](header)
17
+ headers[header]
18
+ end
19
+
20
+ def each(&block)
21
+ headers.each(&block)
22
+ end
23
+ alias_method :each_header, :each
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,205 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ObjectTest < Test::Unit::TestCase
4
+ def setup
5
+ bucket = Bucket.new(Parsing::XmlParser.new(Fixtures::Buckets.bucket_with_one_key))
6
+ @object = bucket.objects.first
7
+ end
8
+
9
+ def test_header_settings_reader_and_writer
10
+ headers = {'content-type' => 'text/plain'}
11
+ mock_connection_for(S3Object, :returns => {:headers => headers})
12
+
13
+ assert_nothing_raised do
14
+ @object.content_type
15
+ end
16
+
17
+ assert_equal 'text/plain', @object.content_type
18
+
19
+ assert_nothing_raised do
20
+ @object.content_type = 'image/jpg'
21
+ end
22
+
23
+ assert_equal 'image/jpg', @object.content_type
24
+
25
+ assert_raises(NoMethodError) do
26
+ @object.non_existant_header_setting
27
+ end
28
+ end
29
+
30
+ def test_key_name_validation
31
+ assert_raises(InvalidKeyName) do
32
+ S3Object.create(nil, '', 'marcel')
33
+ end
34
+
35
+ assert_raises(InvalidKeyName) do
36
+ huge_name = 'a' * 1500
37
+ S3Object.create(huge_name, '', 'marcel')
38
+ end
39
+ end
40
+
41
+ def test_content_type_inference
42
+ [
43
+ ['foo.jpg', {}, 'image/jpeg'],
44
+ ['foo.txt', {}, 'text/plain'],
45
+ ['foo', {}, nil],
46
+ ['foo.asdf', {}, nil],
47
+ ['foo.jpg', {:content_type => nil}, nil],
48
+ ['foo', {:content_type => 'image/jpg'}, 'image/jpg'],
49
+ ['foo.jpg', {:content_type => 'image/png'}, 'image/png'],
50
+ ['foo.asdf', {:content_type => 'image/jpg'}, 'image/jpg']
51
+ ].each do |key, options, content_type|
52
+ S3Object.send(:infer_content_type!, key, options)
53
+ assert_equal content_type, options[:content_type]
54
+ end
55
+ end
56
+
57
+ def test_object_has_owner
58
+ assert_kind_of Owner, @object.owner
59
+ end
60
+
61
+ def test_owner_attributes_are_accessible
62
+ owner = @object.owner
63
+ assert owner.id
64
+ assert owner.display_name
65
+ assert_equal 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1', owner.id
66
+ assert_equal 'mmolina@onramp.net', owner.display_name
67
+ end
68
+
69
+ def test_only_valid_attributes_accessible
70
+ assert_raises(NoMethodError) do
71
+ @object.owner.foo
72
+ end
73
+ end
74
+
75
+ def test_fetching_object_value_generates_value_object
76
+ mock_connection_for(S3Object, :returns => {:body => 'hello!'})
77
+ value = S3Object.value('foo', 'bar')
78
+ assert_kind_of S3Object::Value, value
79
+ assert_equal 'hello!', value
80
+ end
81
+
82
+ def test_fetching_file_by_name_raises_when_heuristic_fails
83
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
84
+ assert_raises(NoSuchKey) do
85
+ S3Object.find('not_tongue_overload.jpg', 'marcel_molina')
86
+ end
87
+
88
+ object = nil # Block scoping
89
+ assert_nothing_raised do
90
+ object = S3Object.find('tongue_overload.jpg', 'marcel_molina')
91
+ end
92
+ assert_kind_of S3Object, object
93
+ assert_equal 'tongue_overload.jpg', object.key
94
+ end
95
+
96
+ def test_about
97
+ headers = {'content-size' => '12345', 'date' => Time.now.httpdate, 'content-type' => 'application/xml'}
98
+ mock_connection_for(S3Object, :returns => [
99
+ {:headers => headers},
100
+ {:code => 404}
101
+ ]
102
+ )
103
+ about = S3Object.about('foo', 'bar')
104
+ assert_kind_of S3Object::About, about
105
+ assert_equal headers, about
106
+
107
+ assert_raises(NoSuchKey) do
108
+ S3Object.about('foo', 'bar')
109
+ end
110
+ end
111
+
112
+ def test_can_tell_that_an_s3object_does_not_exist
113
+ mock_connection_for(S3Object, :returns => {:code => 404})
114
+ assert_equal false, S3Object.exists?('foo', 'bar')
115
+ end
116
+
117
+ def test_can_tell_that_an_s3object_exists
118
+ mock_connection_for(S3Object, :returns => {:code => 200})
119
+ assert_equal true, S3Object.exists?('foo', 'bar')
120
+ end
121
+
122
+ def test_s3object_equality
123
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_more_than_one_key})
124
+ file1, file2 = Bucket.objects('does not matter')
125
+ assert file1 == file1
126
+ assert file2 == file2
127
+ assert !(file1 == file2) # /!\ Parens required /!\
128
+ end
129
+
130
+ def test_inspect
131
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
132
+ object = S3Object.find('tongue_overload.jpg', 'bucket does not matter')
133
+ assert object.path
134
+ assert_nothing_raised { object.inspect }
135
+ assert object.inspect[object.path]
136
+ end
137
+
138
+ def test_etag
139
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
140
+ file = S3Object.find('tongue_overload.jpg', 'bucket does not matter')
141
+ assert file.etag
142
+ assert_equal 'f21f7c4e8ea6e34b268887b07d6da745', file.etag
143
+ end
144
+
145
+ def test_fetching_information_about_an_object_that_does_not_exist_raises_no_such_key
146
+ mock_connection_for(S3Object, :returns => {:body => '', :code => 404})
147
+ assert_raises(NoSuchKey) do
148
+ S3Object.about('asdfasdfasdfas-this-does-not-exist', 'bucket does not matter')
149
+ end
150
+ end
151
+ end
152
+
153
+ class MetadataTest < Test::Unit::TestCase
154
+ def setup
155
+ @metadata = S3Object::Metadata.new(Fixtures::Headers.headers_including_one_piece_of_metadata)
156
+ end
157
+
158
+ def test_only_metadata_is_extracted
159
+ assert @metadata.to_headers.size == 1
160
+ assert @metadata.to_headers['x-amz-meta-test']
161
+ assert_equal 'foo', @metadata.to_headers['x-amz-meta-test']
162
+ end
163
+
164
+ def test_setting_new_metadata_normalizes_name
165
+ @metadata[:bar] = 'baz'
166
+ assert @metadata.to_headers.include?('x-amz-meta-bar')
167
+ @metadata['baz'] = 'quux'
168
+ assert @metadata.to_headers.include?('x-amz-meta-baz')
169
+ @metadata['x-amz-meta-quux'] = 'whatever'
170
+ assert @metadata.to_headers.include?('x-amz-meta-quux')
171
+ end
172
+
173
+ def test_clobbering_existing_header
174
+ @metadata[:bar] = 'baz'
175
+ assert_equal 'baz', @metadata.to_headers['x-amz-meta-bar']
176
+ @metadata[:bar] = 'quux'
177
+ assert_equal 'quux', @metadata.to_headers['x-amz-meta-bar']
178
+ @metadata['bar'] = 'foo'
179
+ assert_equal 'foo', @metadata.to_headers['x-amz-meta-bar']
180
+ @metadata['x-amz-meta-bar'] = 'bar'
181
+ assert_equal 'bar', @metadata.to_headers['x-amz-meta-bar']
182
+ end
183
+
184
+ def test_invalid_metadata
185
+ @metadata[:invalid_header] = ' ' * (S3Object::Metadata::SIZE_LIMIT + 1)
186
+ assert_raises InvalidMetadataValue do
187
+ @metadata.to_headers
188
+ end
189
+ end
190
+ end
191
+
192
+ class ValueTest < Test::Unit::TestCase
193
+ def setup
194
+ @response = FakeResponse.new(:body => 'hello there')
195
+ @value = S3Object::Value.new(@response)
196
+ end
197
+
198
+ def test_value_is_set_to_response_body
199
+ assert_equal @response.body, @value
200
+ end
201
+
202
+ def test_response_is_accessible_from_value_object
203
+ assert_equal @response, @value.response
204
+ end
205
+ end