plntr-fakes3 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module FakeS3
2
+ VERSION = "1.0.0-1"
3
+ end
@@ -0,0 +1,222 @@
1
+ require 'builder'
2
+ require 'time'
3
+
4
+ module FakeS3
5
+ class XmlAdapter
6
+ def self.buckets(bucket_objects)
7
+ output = ""
8
+ xml = Builder::XmlMarkup.new(:target => output)
9
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
10
+ xml.ListAllMyBucketsResult(:xmlns => "http://s3.amazonaws.com/doc/2006-03-01/") { |lam|
11
+ lam.Owner { |owner|
12
+ owner.ID("123")
13
+ owner.DisplayName("FakeS3")
14
+ }
15
+ lam.Buckets { |buckets|
16
+ bucket_objects.each do |bucket|
17
+ buckets.Bucket do |b|
18
+ b.Name(bucket.name)
19
+ b.CreationDate(bucket.creation_date.strftime("%Y-%m-%dT%H:%M:%S.000Z"))
20
+ end
21
+ end
22
+ }
23
+ }
24
+ output
25
+ end
26
+
27
+ def self.error(error)
28
+ output = ""
29
+ xml = Builder::XmlMarkup.new(:target => output)
30
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
31
+ xml.Error { |err|
32
+ err.Code(error.code)
33
+ err.Message(error.message)
34
+ err.Resource(error.resource)
35
+ err.RequestId(1)
36
+ }
37
+ output
38
+ end
39
+
40
+ # <?xml version="1.0" encoding="UTF-8"?>
41
+ #<Error>
42
+ # <Code>NoSuchKey</Code>
43
+ # <Message>The resource you requested does not exist</Message>
44
+ # <Resource>/mybucket/myfoto.jpg</Resource>
45
+ # <RequestId>4442587FB7D0A2F9</RequestId>
46
+ #</Error>
47
+ #
48
+ def self.error_no_such_bucket(name)
49
+ output = ""
50
+ xml = Builder::XmlMarkup.new(:target => output)
51
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
52
+ xml.Error { |err|
53
+ err.Code("NoSuchBucket")
54
+ err.Message("The resource you requested does not exist")
55
+ err.Resource(name)
56
+ err.RequestId(1)
57
+ }
58
+ output
59
+ end
60
+
61
+ def self.error_bucket_not_empty(name)
62
+ output = ""
63
+ xml = Builder::XmlMarkup.new(:target => output)
64
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
65
+ xml.Error { |err|
66
+ err.Code("BucketNotEmpty")
67
+ err.Message("The bucket you tried to delete is not empty.")
68
+ err.Resource(name)
69
+ err.RequestId(1)
70
+ }
71
+ output
72
+ end
73
+
74
+ def self.error_no_such_key(name)
75
+ output = ""
76
+ xml = Builder::XmlMarkup.new(:target => output)
77
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
78
+ xml.Error { |err|
79
+ err.Code("NoSuchKey")
80
+ err.Message("The specified key does not exist")
81
+ err.Key(name)
82
+ err.RequestId(1)
83
+ err.HostId(2)
84
+ }
85
+ output
86
+ end
87
+
88
+ def self.bucket(bucket)
89
+ output = ""
90
+ xml = Builder::XmlMarkup.new(:target => output)
91
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
92
+ xml.ListBucketResult(:xmlns => "http://s3.amazonaws.com/doc/2006-03-01/") { |lbr|
93
+ lbr.Name(bucket.name)
94
+ lbr.Prefix
95
+ lbr.Marker
96
+ lbr.MaxKeys("1000")
97
+ lbr.IsTruncated("false")
98
+ }
99
+ output
100
+ end
101
+
102
+ # A bucket query gives back the bucket along with contents
103
+ # <Contents>
104
+ #<Key>Nelson</Key>
105
+ # <LastModified>2006-01-01T12:00:00.000Z</LastModified>
106
+ # <ETag>&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;</ETag>
107
+ # <Size>5</Size>
108
+ # <StorageClass>STANDARD</StorageClass>
109
+ # <Owner>
110
+ # <ID>bcaf161ca5fb16fd081034f</ID>
111
+ # <DisplayName>webfile</DisplayName>
112
+ # </Owner>
113
+ # </Contents>
114
+
115
+ def self.append_objects_to_list_bucket_result(lbr,objects)
116
+ return if objects.nil? or objects.size == 0
117
+
118
+ if objects.index(nil)
119
+ require 'ruby-debug'
120
+ Debugger.start
121
+ debugger
122
+ end
123
+
124
+ objects.each do |s3_object|
125
+ lbr.Contents { |contents|
126
+ contents.Key(s3_object.name)
127
+ contents.LastModified(s3_object.modified_date)
128
+ contents.ETag("\"#{s3_object.md5}\"")
129
+ contents.Size(s3_object.size)
130
+ contents.StorageClass("STANDARD")
131
+
132
+ contents.Owner { |owner|
133
+ owner.ID("abc")
134
+ owner.DisplayName("You")
135
+ }
136
+ }
137
+ end
138
+ end
139
+
140
+ def self.append_common_prefixes_to_list_bucket_result(lbr, prefixes)
141
+ return if prefixes.nil? or prefixes.size == 0
142
+
143
+ prefixes.each do |common_prefix|
144
+ lbr.CommonPrefixes { |contents| contents.Prefix(common_prefix) }
145
+ end
146
+ end
147
+
148
+ def self.bucket_query(bucket_query)
149
+ output = ""
150
+ bucket = bucket_query.bucket
151
+ xml = Builder::XmlMarkup.new(:target => output)
152
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
153
+ xml.ListBucketResult(:xmlns => "http://s3.amazonaws.com/doc/2006-03-01/") { |lbr|
154
+ lbr.Name(bucket.name)
155
+ lbr.Prefix(bucket_query.prefix)
156
+ lbr.Marker(bucket_query.marker)
157
+ lbr.MaxKeys(bucket_query.max_keys)
158
+ lbr.IsTruncated(bucket_query.is_truncated?)
159
+ append_objects_to_list_bucket_result(lbr,bucket_query.matches)
160
+ append_common_prefixes_to_list_bucket_result(lbr, bucket_query.common_prefixes)
161
+ }
162
+ output
163
+ end
164
+
165
+ # ACL xml
166
+ def self.acl(object = nil)
167
+ output = ""
168
+ xml = Builder::XmlMarkup.new(:target => output)
169
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
170
+ xml.AccessControlPolicy(:xmlns => "http://s3.amazonaws.com/doc/2006-03-01/") { |acp|
171
+ acp.Owner do |owner|
172
+ owner.ID("abc")
173
+ owner.DisplayName("You")
174
+ end
175
+ acp.AccessControlList do |acl|
176
+ acl.Grant do |grant|
177
+ grant.Grantee("xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xsi:type" => "CanonicalUser") do |grantee|
178
+ grantee.ID("abc")
179
+ grantee.DisplayName("You")
180
+ end
181
+ grant.Permission("FULL_CONTROL")
182
+ end
183
+ end
184
+ }
185
+ output
186
+ end
187
+
188
+ # <CopyObjectResult>
189
+ # <LastModified>2009-10-28T22:32:00</LastModified>
190
+ # <ETag>"9b2cf535f27731c974343645a3985328"</ETag>
191
+ # </CopyObjectResult>
192
+ def self.copy_object_result(object)
193
+ output = ""
194
+ xml = Builder::XmlMarkup.new(:target => output)
195
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
196
+ xml.CopyObjectResult { |result|
197
+ result.LastModified(object.modified_date)
198
+ result.ETag("\"#{object.md5}\"")
199
+ }
200
+ output
201
+ end
202
+
203
+ # <CompleteMultipartUploadResult>
204
+ # <Location>http://Example-Bucket.s3.amazonaws.com/Example-Object</Location>
205
+ # <Bucket>Example-Bucket</Bucket>
206
+ # <Key>Example-Object</Key>
207
+ # <ETag>"3858f62230ac3c915f300c664312c11f-9"</ETag>
208
+ # </CompleteMultipartUploadResult>
209
+ def self.complete_multipart_result(object)
210
+ output = ""
211
+ xml = Builder::XmlMarkup.new(:target => output)
212
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
213
+ xml.CompleteMultipartUploadResult { |result|
214
+ result.Location("TODO: implement")
215
+ result.Bucket("TODO: implement")
216
+ result.Key(object.name)
217
+ result.ETag("\"#{object.md5}\"")
218
+ }
219
+ output
220
+ end
221
+ end
222
+ end
data/lib/fakes3.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'fakes3/version'
2
+ require 'fakes3/file_store'
3
+ require 'fakes3/server'
data/static/button.svg ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="110px" height="20px" viewBox="0 0 110 20" enable-background="new 0 0 110 20" xml:space="preserve"> <image id="image0" width="110" height="20" x="0" y="0" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG4AAAAUCAMAAABbPPhuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN AAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABL1BMVEUAUJX///8AUJUAUJUA UJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUAUJUA UJUAUJUAUJUAUJUAUJUAUJUAUJU5e7Rmns59r9uAs917sNx6r9yDtN5lnc0vdK9EhLtzq9o/i8wp fsYhecQdd8Mke8U9iss6fLU4e7RyqtougccfeMNQjcx0otRjmNAhesQzhMliodVKib8+i8zT4PDI 2OyTtdyvx+ShvuD///8qf8dOlNCAstwlfMU7fbZ/st0gecQ5g8e7z+iErNibw+QyhMnq8Pj19/vf 6PTG3fAwg8jm8PhNlND5+/12rNs0hcluqNh3rdtNisDn8fl5rtvH3fBnns4xdbCcw+VhoNU5fLVo oM99sNsds+t8AAAAHXRSTlMAAAZux/NbG8+ZCNAobZoK+dNcn/VgLF+dB2/L9Kp1EagAAAABYktH RAH/Ai3eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsECgU1BHGi1AAAAmZJREFUSMe9 lgtT1DAQxytwgoLC+X4BeiegGEUkCXqXtgkomlabqvh+P77/Z3A3SXst5Wa4cY6duUmbbPaX/HeT XhAEE5NTrcXx2ckTFQuC6Zml5Zu3Ot3x2O2V1VOnK7iJmbU7d9fvkTHZ/Qedjdm5Ae7Mw81HW0ef Thkfjbf9+EmvVQoaTC33HU2ghdGQWZGIbSuVGHF/Wzu7K6tn5z1u4em661bO4sMnFRgmo6NRKvas 39lrO0GDxecvChzDqMpFjCTjUiJH0gZOy1BIDS+JbcBXigTfQxFTHBZJ6oK+tEWx/QoEPedwHVLB pSpzkYWSVClKuDK13WGrc5RBkAgbo8HXwENOKL5nfli6oK/flIKen0dct8TlAibyEkdC+MUqaeAS lVMdc21UCj4J+GYMZOESMsEYumiOS7VB3+57QbsoaBXnc1fiUlhxrngDlykrFQwzwGTWF8VhsGWQ OleSsVxFPui7965CP3zsXbhYxYGYFEKVOIjLIFoDZz1tnq2VOCJB1IQY1y0L3KcC97mBw6XhgoEk MWDmc1DD2fCY1gzKQ5MBjpLUKI45wG4X9MuuF/PrXvtSrVQgdxmkIIWn3K4Oc08LnFsy4sAhiQ3m TEgByS5w0sSwP8qUiXHYBv3mS2X/+w9XKoODgHUmIC2h5eG2hApJE0ci0MtERAvoCXWJSzOnoR12 J+GnPwi/eq3L9WNeMc7cGYt9wskwD830gW4nBq/ddL4q65dY02CXIflvs2fuSnGJTS4Nv6L5iNfx YXbgir46u7bZH+cHqLvRnqt9Xn//+Xtsn1f483Dt+o3j+vPwD8d6fpTeP3ACAAAAJXRFWHRkYXRl OmNyZWF0ZQAyMDE2LTExLTA0VDEwOjA1OjUzLTA3OjAwJ5wXuQAAACV0RVh0ZGF0ZTptb2RpZnkA MjAxNi0xMS0wNFQxMDowNTo1My0wNzowMFbBrwUAAAAASUVORK5CYII="/>
4
+ </svg>
data/static/logo.png ADDED
Binary file
@@ -0,0 +1,58 @@
1
+ require 'test/test_helper'
2
+ require 'aws-sdk-v1'
3
+
4
+ class AwsSdkCommandsTest < Test::Unit::TestCase
5
+ def setup
6
+ @s3 = AWS::S3.new(:access_key_id => '123',
7
+ :secret_access_key => 'abc',
8
+ :s3_endpoint => 'localhost',
9
+ :s3_port => 10453,
10
+ :use_ssl => false)
11
+ end
12
+
13
+ def test_copy_to
14
+ bucket = @s3.buckets["test_copy_to"]
15
+ object = bucket.objects["key1"]
16
+ object.write("asdf")
17
+
18
+ assert object.exists?
19
+ object.copy_to("key2")
20
+
21
+ assert_equal 2, bucket.objects.count
22
+ end
23
+
24
+ def test_multipart_upload
25
+ bucket = @s3.buckets["test_multipart_upload"]
26
+ object = bucket.objects["key1"]
27
+ object.write("thisisaverybigfile", :multipart_threshold => 5)
28
+ assert object.exists?
29
+ assert_equal "thisisaverybigfile", object.read
30
+ end
31
+
32
+ def test_metadata
33
+ file_path = './test_root/test_metadata/metaobject'
34
+ FileUtils.rm_rf file_path
35
+
36
+ bucket = @s3.buckets["test_metadata"]
37
+ object = bucket.objects["metaobject"]
38
+ object.write(
39
+ 'data',
40
+ # this is sent as header x-amz-storage-class
41
+ :storage_class => 'REDUCED_REDUNDANCY',
42
+ # this is sent as header x-amz-meta-custom1
43
+ :metadata => {
44
+ "custom1" => "foobar"
45
+ }
46
+ )
47
+ assert object.exists?
48
+ metadata_file = YAML.load(IO.read("#{file_path}/.fakes3_metadataFFF/metadata"))
49
+
50
+ assert metadata_file.has_key?(:custom_metadata), 'Metadata file does not contain a :custom_metadata key'
51
+ assert metadata_file[:custom_metadata].has_key?('custom1'), ':custom_metadata does not contain field "custom1"'
52
+ assert_equal 'foobar', metadata_file[:custom_metadata]['custom1'], '"custom1" does not equal expected value "foobar"'
53
+
54
+ assert metadata_file.has_key?(:amazon_metadata), 'Metadata file does not contain an :amazon_metadata key'
55
+ assert metadata_file[:amazon_metadata].has_key?('storage-class'), ':amazon_metadata does not contain field "storage-class"'
56
+ assert_equal 'REDUCED_REDUNDANCY', metadata_file[:amazon_metadata]['storage-class'], '"storage-class" does not equal expected value "REDUCED_REDUNDANCY"'
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ require 'test/test_helper'
2
+ require 'aws-sdk'
3
+
4
+ class AwsSdkV2CommandsTest < Test::Unit::TestCase
5
+ def setup
6
+ @creds = Aws::Credentials.new('123', 'abc')
7
+ @s3 = Aws::S3::Client.new(credentials: @creds, region: 'us-east-1', endpoint: 'http://localhost:10453/')
8
+ @resource = Aws::S3::Resource.new(client: @s3)
9
+ @bucket = @resource.create_bucket(bucket: 'v2_bucket')
10
+
11
+ # Delete all objects to avoid sharing state between tests
12
+ @bucket.objects.each(&:delete)
13
+ end
14
+
15
+ def test_create_bucket
16
+ bucket = @resource.create_bucket(bucket: 'v2_create_bucket')
17
+ assert_not_nil bucket
18
+
19
+ bucket_names = @resource.buckets.map(&:name)
20
+ assert(bucket_names.index("v2_create_bucket") >= 0)
21
+ end
22
+
23
+ def test_destroy_bucket
24
+ @bucket.delete
25
+
26
+ begin
27
+ @s3.head_bucket(bucket: 'v2_bucket')
28
+ assert_fail("Shouldn't succeed here")
29
+ rescue
30
+ end
31
+ end
32
+
33
+ def test_create_object
34
+ object = @bucket.object('key')
35
+ object.put(body: 'test')
36
+
37
+ assert_equal 'test', object.get.body.string
38
+ end
39
+
40
+ def test_delete_object
41
+ object = @bucket.object('exists')
42
+ object.put(body: 'test')
43
+
44
+ assert_equal 'test', object.get.body.string
45
+
46
+ object.delete
47
+
48
+ assert_raise Aws::S3::Errors::NoSuchKey do
49
+ object.get
50
+ end
51
+ end
52
+
53
+ # TODO - get this test working
54
+ #
55
+ #def test_copy_object
56
+ # object = @bucket.object("key_one")
57
+ # object.put(body: 'asdf')
58
+
59
+ # # TODO: explore why 'key1' won't work but 'key_one' will
60
+ # object2 = @bucket.object('key_two')
61
+ # object2.copy_from(copy_source: 'testing_copy/key_one')
62
+
63
+ # assert_equal 2, @bucket.objects.count
64
+ #end
65
+ end
data/test/boto_test.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'test/test_helper'
2
+ require 'fileutils'
3
+
4
+ class BotoTest < Test::Unit::TestCase
5
+ def setup
6
+ cmdpath = File.expand_path(File.join(File.dirname(__FILE__),'botocmd.py'))
7
+ @botocmd = "python #{cmdpath} -t localhost -p 10453"
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_store
14
+ File.open(__FILE__,'rb') do |input|
15
+ File.open("/tmp/fakes3_upload",'wb') do |output|
16
+ output << input.read
17
+ end
18
+ end
19
+ output = `#{@botocmd} put /tmp/fakes3_upload s3://s3cmd_bucket/upload`
20
+ assert_match(/stored/,output)
21
+
22
+ FileUtils.rm("/tmp/fakes3_upload")
23
+ end
24
+
25
+ end
data/test/botocmd.py ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/python
2
+ # -*- coding: utf-8 -*-
3
+ # fakes3cmd.py -- an s3cmd-like script that accepts a custom host and portname
4
+ import re
5
+ import os
6
+ from optparse import OptionParser
7
+
8
+ try:
9
+ from boto.s3.connection import S3Connection, OrdinaryCallingFormat
10
+ from boto.s3.key import Key
11
+ except ImportError:
12
+ raise Exception('You must install the boto package for python')
13
+
14
+
15
+ class FakeS3Cmd(object):
16
+ COMMANDS = ['mb', 'rb', 'put', ]
17
+ def __init__(self, host, port):
18
+ self.host = host
19
+ self.port = port
20
+ self.conn = None
21
+ self._connect()
22
+
23
+ def _connect(self):
24
+ print 'Connecting: %s:%s' % (self.host, self.port)
25
+ self.conn = S3Connection(is_secure=False,
26
+ calling_format=OrdinaryCallingFormat(),
27
+ aws_access_key_id='',
28
+ aws_secret_access_key='',
29
+ port=self.port, host=self.host)
30
+
31
+
32
+ @staticmethod
33
+ def _parse_uri(path):
34
+ match = re.match(r's3://([^/]+)(?:/(.*))?', path, re.I)
35
+ ## (bucket, key)
36
+ return match.groups()
37
+
38
+ def mb(self, path, *args):
39
+ if not self.conn:
40
+ self._connect()
41
+
42
+ bucket, _ = self._parse_uri(path)
43
+ self.conn.create_bucket(bucket)
44
+ print 'made bucket: [%s]' % bucket
45
+
46
+ def rb(self, path, *args):
47
+ if not self.conn:
48
+ self._connect()
49
+
50
+ bucket, _ = self._parse_uri(path)
51
+ self.conn.delete_bucket(bucket)
52
+ print 'removed bucket: [%s]' % bucket
53
+
54
+ def put(self, *args):
55
+ if not self.conn:
56
+ self._connect()
57
+
58
+ args = list(args)
59
+ path = args.pop()
60
+ bucket_name, prefix = self._parse_uri(path)
61
+ bucket = self.conn.create_bucket(bucket_name)
62
+ for src_file in args:
63
+ key = Key(bucket)
64
+ key.key = os.path.join(prefix, os.path.basename(src_file))
65
+ key.set_contents_from_filename(src_file)
66
+ print 'stored: [%s]' % key.key
67
+
68
+
69
+ if __name__ == "__main__":
70
+ # check for options. TODO: This requires a more verbose help message
71
+ # to explain how the positional arguments work.
72
+ parser = OptionParser()
73
+ parser.add_option("-t", "--host", type="string", default='localhost')
74
+ parser.add_option("-p", "--port", type='int', default=80)
75
+ o, args = parser.parse_args()
76
+
77
+ if len(args) < 2:
78
+ raise ValueError('you must minimally supply a desired command and s3 uri')
79
+
80
+ cmd = args.pop(0)
81
+
82
+ if cmd not in FakeS3Cmd.COMMANDS:
83
+ raise ValueError('%s is not a valid command' % cmd)
84
+
85
+ fs3 = FakeS3Cmd(o.host, o.port)
86
+ handler = getattr(fs3, cmd)
87
+ handler(*args)
data/test/cli_test.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'test/test_helper'
2
+ require 'test/minitest_helper'
3
+ require 'fakes3/cli'
4
+
5
+
6
+ class CLITest < Test::Unit::TestCase
7
+ def setup
8
+ super
9
+ FakeS3::Server.any_instance.stubs(:serve)
10
+ end
11
+
12
+ def test_quiet_mode
13
+ script = FakeS3::CLI.new([], :root => '.', :port => 4567, :quiet => true)
14
+ assert_output('') do
15
+ script.invoke(:server)
16
+ end
17
+ end
18
+ end
data/test/local_s3_cfg ADDED
@@ -0,0 +1,34 @@
1
+ [default]
2
+ access_key = abc
3
+ acl_public = False
4
+ bucket_location = US
5
+ cloudfront_host = cloudfront.amazonaws.com
6
+ cloudfront_resource = /2008-06-30/distribution
7
+ default_mime_type = binary/octet-stream
8
+ delete_removed = False
9
+ dry_run = False
10
+ encoding = UTF-8
11
+ encrypt = False
12
+ force = False
13
+ get_continue = False
14
+ gpg_command = None
15
+ gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
16
+ gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
17
+ gpg_passphrase =
18
+ guess_mime_type = True
19
+ host_base = localhost:10453
20
+ host_bucket = %(bucket)s.localhost:10453
21
+ human_readable_sizes = False
22
+ list_md5 = False
23
+ preserve_attrs = True
24
+ progress_meter = True
25
+ proxy_host =
26
+ proxy_port = 0
27
+ recursive = False
28
+ recv_chunk = 4096
29
+ secret_key = def
30
+ send_chunk = 4096
31
+ simpledb_host = sdb.amazonaws.com
32
+ skip_existing = False
33
+ use_https = False
34
+ verbosity = WARNING
@@ -0,0 +1,46 @@
1
+ # LICENSE:
2
+ #
3
+ # (The MIT License)
4
+ #
5
+ # Copyright © Ryan Davis, seattle.rb
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
+
13
+ # The following is from minitest:
14
+ # TODO - decide whether to switch to minitest or what to do about these:
15
+
16
+ def capture_io
17
+ require 'stringio'
18
+
19
+ captured_stdout, captured_stderr = StringIO.new, StringIO.new
20
+
21
+ orig_stdout, orig_stderr = $stdout, $stderr
22
+ $stdout, $stderr = captured_stdout, captured_stderr
23
+
24
+ begin
25
+ yield
26
+ ensure
27
+ $stdout = orig_stdout
28
+ $stderr = orig_stderr
29
+ end
30
+
31
+ return captured_stdout.string, captured_stderr.string
32
+ end
33
+
34
+ def assert_output stdout = nil, stderr = nil
35
+ out, err = capture_io do
36
+ yield
37
+ end
38
+
39
+ err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr
40
+ out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout
41
+
42
+ y = send err_msg, stderr, err, "In stderr" if err_msg
43
+ x = send out_msg, stdout, out, "In stdout" if out_msg
44
+
45
+ (!stdout || x) && (!stderr || y)
46
+ end
data/test/post_test.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'test/test_helper'
2
+ require 'rest-client'
3
+
4
+ class PostTest < Test::Unit::TestCase
5
+ # Make sure you have a posttest.localhost in your /etc/hosts/
6
+ def setup
7
+ @url='http://posttest.localhost:10453/'
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_options
14
+ RestClient.options(@url) do |response|
15
+ assert_equal(response.code, 200)
16
+ assert_equal(response.headers[:access_control_allow_origin],"*")
17
+ assert_equal(response.headers[:access_control_allow_methods], "PUT, POST, HEAD, GET, OPTIONS")
18
+ assert_equal(response.headers[:access_control_allow_headers], "Accept, Content-Type, Authorization, Content-Length, ETag, X-CSRF-Token")
19
+ assert_equal(response.headers[:access_control_expose_headers], "ETag")
20
+ end
21
+ end
22
+
23
+ def test_redirect
24
+ res = RestClient.post(
25
+ @url,
26
+ 'key'=>'uploads/12345/${filename}',
27
+ 'success_action_redirect'=>'http://somewhere.else.com/',
28
+ 'file'=>File.new(__FILE__,"rb")
29
+ ) { |response|
30
+ assert_equal(response.code, 307)
31
+ assert_equal(response.headers[:location], 'http://somewhere.else.com/')
32
+ }
33
+ end
34
+
35
+ def test_status_200
36
+ res = RestClient.post(
37
+ @url,
38
+ 'key'=>'uploads/12345/${filename}',
39
+ 'success_action_status'=>'200',
40
+ 'file'=>File.new(__FILE__,"rb")
41
+ ) { |response|
42
+ assert_equal(response.code, 200)
43
+ }
44
+ end
45
+
46
+ def test_status_201
47
+ res = RestClient.post(
48
+ @url,
49
+ 'key'=>'uploads/12345/${filename}',
50
+ 'success_action_status'=>'201',
51
+ 'file'=>File.new(__FILE__,"rb")
52
+ ) { |response|
53
+ assert_equal(response.code, 201)
54
+ assert_match(%r{^\<\?xml.*uploads/12345/post_test\.rb}m, response.body)
55
+ }
56
+ end
57
+
58
+ end