ahoward-helene 0.0.3

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 (72) hide show
  1. data/Rakefile +274 -0
  2. data/helene.gemspec +26 -0
  3. data/lib/helene.rb +113 -0
  4. data/lib/helene/attempt.rb +46 -0
  5. data/lib/helene/aws.rb +50 -0
  6. data/lib/helene/config.rb +147 -0
  7. data/lib/helene/content_type.rb +15 -0
  8. data/lib/helene/content_type.yml +661 -0
  9. data/lib/helene/error.rb +12 -0
  10. data/lib/helene/logging.rb +55 -0
  11. data/lib/helene/objectpool.rb +220 -0
  12. data/lib/helene/rails.rb +21 -0
  13. data/lib/helene/rightscale/acf/right_acf_interface.rb +379 -0
  14. data/lib/helene/rightscale/awsbase/benchmark_fix.rb +39 -0
  15. data/lib/helene/rightscale/awsbase/right_awsbase.rb +803 -0
  16. data/lib/helene/rightscale/awsbase/support.rb +111 -0
  17. data/lib/helene/rightscale/ec2/right_ec2.rb +1737 -0
  18. data/lib/helene/rightscale/net_fix.rb +160 -0
  19. data/lib/helene/rightscale/right_aws.rb +71 -0
  20. data/lib/helene/rightscale/right_http_connection.rb +507 -0
  21. data/lib/helene/rightscale/s3/right_s3.rb +1094 -0
  22. data/lib/helene/rightscale/s3/right_s3_interface.rb +1180 -0
  23. data/lib/helene/rightscale/sdb/active_sdb.rb +930 -0
  24. data/lib/helene/rightscale/sdb/right_sdb_interface.rb +696 -0
  25. data/lib/helene/rightscale/sqs/right_sqs.rb +388 -0
  26. data/lib/helene/rightscale/sqs/right_sqs_gen2.rb +286 -0
  27. data/lib/helene/rightscale/sqs/right_sqs_gen2_interface.rb +444 -0
  28. data/lib/helene/rightscale/sqs/right_sqs_interface.rb +596 -0
  29. data/lib/helene/s3.rb +34 -0
  30. data/lib/helene/s3/bucket.rb +379 -0
  31. data/lib/helene/s3/grantee.rb +134 -0
  32. data/lib/helene/s3/key.rb +162 -0
  33. data/lib/helene/s3/owner.rb +16 -0
  34. data/lib/helene/sdb.rb +9 -0
  35. data/lib/helene/sdb/base.rb +1204 -0
  36. data/lib/helene/sdb/base/associations.rb +481 -0
  37. data/lib/helene/sdb/base/attributes.rb +90 -0
  38. data/lib/helene/sdb/base/connection.rb +20 -0
  39. data/lib/helene/sdb/base/error.rb +20 -0
  40. data/lib/helene/sdb/base/hooks.rb +82 -0
  41. data/lib/helene/sdb/base/literal.rb +52 -0
  42. data/lib/helene/sdb/base/logging.rb +23 -0
  43. data/lib/helene/sdb/base/transactions.rb +53 -0
  44. data/lib/helene/sdb/base/type.rb +137 -0
  45. data/lib/helene/sdb/base/types.rb +123 -0
  46. data/lib/helene/sdb/base/validations.rb +256 -0
  47. data/lib/helene/sdb/cast.rb +114 -0
  48. data/lib/helene/sdb/connection.rb +36 -0
  49. data/lib/helene/sdb/error.rb +5 -0
  50. data/lib/helene/sdb/interface.rb +412 -0
  51. data/lib/helene/sdb/sentinel.rb +15 -0
  52. data/lib/helene/sleepcycle.rb +29 -0
  53. data/lib/helene/superhash.rb +297 -0
  54. data/lib/helene/util.rb +132 -0
  55. data/test/auth.rb +31 -0
  56. data/test/helper.rb +98 -0
  57. data/test/integration/begin.rb +0 -0
  58. data/test/integration/ensure.rb +8 -0
  59. data/test/integration/s3/bucket.rb +106 -0
  60. data/test/integration/sdb/associations.rb +45 -0
  61. data/test/integration/sdb/creating.rb +13 -0
  62. data/test/integration/sdb/emptiness.rb +56 -0
  63. data/test/integration/sdb/hooks.rb +19 -0
  64. data/test/integration/sdb/limits.rb +27 -0
  65. data/test/integration/sdb/saving.rb +21 -0
  66. data/test/integration/sdb/selecting.rb +39 -0
  67. data/test/integration/sdb/types.rb +31 -0
  68. data/test/integration/sdb/validations.rb +60 -0
  69. data/test/integration/setup.rb +27 -0
  70. data/test/integration/teardown.rb +21 -0
  71. data/test/loader.rb +39 -0
  72. metadata +139 -0
@@ -0,0 +1,31 @@
1
+ # TODO - needs to bootstrap from a test config file - for now rely on
2
+ #
3
+ # ENV['AWS_ACCESS_KEY_ID']
4
+ # ENV['AWS_SECRET_ACCESS_KEY']
5
+ #
6
+
7
+ config = YAML.load((File.read(File.expand_path("~/.aws.yml")) rescue "{}"))
8
+
9
+ if access_key_id = config["access_key_id"]
10
+ ENV['ACCESS_KEY_ID'] = access_key_id
11
+ ENV['AMAZON_ACCESS_KEY_ID'] = access_key_id
12
+ ACCESS_KEY_ID = access_key_id
13
+ AMAZON_ACCESS_KEY_ID = access_key_id
14
+ end
15
+
16
+ if secret_access_key = config["secret_access_key"]
17
+ ENV['SECRET_ACCESS_KEY'] = secret_access_key
18
+ ENV['AMAZON_SECRET_ACCESS_KEY'] = secret_access_key
19
+ ACCESS_SECRET_KEY = secret_access_key
20
+ AMAZON_SECRET_ACCESS_KEY = secret_access_key
21
+ end
22
+
23
+ if ca_file = config["ca_file"]
24
+ ENV['CA_FILE'] = ca_file
25
+ ENV['AMAZON_CA_FILE'] = ca_file
26
+ CA_FILE = ca_file
27
+ AMAZON_CA_FILE = ca_file
28
+
29
+ # It's too late to count on helene.rb to load this, so we need to do it:
30
+ Rightscale::HttpConnection.params[:ca_file] = ca_file
31
+ end
@@ -0,0 +1,98 @@
1
+ module Helene
2
+ module Test
3
+ module Models
4
+ def model(name, &block)
5
+ name = name.to_s
6
+ @models ||= {}
7
+ @models[name] ||= Class.new(Helene::Sdb::Base){ domain "helene-test-model-#{ name }" }
8
+ class_name = name.classify
9
+ ::Object.send(:remove_const, class_name) if ::Object.const_defined?(class_name)
10
+ ::Object.const_set(class_name, @models[name])
11
+ @models[name].module_eval(&block) if block
12
+ @models[name]
13
+ end
14
+
15
+ def models
16
+ ('a' .. 'e').map{|name| model(name)}
17
+ end
18
+
19
+ extend self
20
+ end
21
+
22
+ Helper = lambda do
23
+ def self.setup(&block)
24
+ define_method(:setup, &block)
25
+ end
26
+
27
+ alias_method '__assert__', 'assert'
28
+
29
+ def assert(*args, &block)
30
+ if block
31
+ label = 'assertion: ' + args.join(' ')
32
+ result = nil
33
+ assert_nothing_raised{ result = block.call }
34
+ __assert__(result, label)
35
+ result
36
+ else
37
+ __assert__(*args)
38
+ args.first
39
+ end
40
+ end
41
+
42
+ def eventually_assert(*args, &block)
43
+ options = args.extract_options!.to_options!
44
+ first = args.shift || caller.first(1)
45
+ label = "eventually_assert(#{ first.to_s.inspect })"
46
+
47
+ min = 0.01
48
+ max = 1.28
49
+ sleeps = []
50
+ m = min
51
+ while m < max; sleeps << m and m *= 2; end
52
+
53
+ a = Time.now.to_f
54
+ 42.times do |i|
55
+ bool =
56
+ begin
57
+ block.call
58
+ rescue => e
59
+ m, c, b = e.message, e.class, (e.backtrace||{}).join("\n")
60
+ STDERR.puts "\n#{ m }(#{ c })\n#{ b }"
61
+ false
62
+ end
63
+ if bool
64
+ args = [bool, label]
65
+ assert(*args)
66
+ return true
67
+ end
68
+ STDERR.puts "\n#{ label.to_s } (not true yet...)"
69
+ sleep(sleeps[ i % sleeps.size ])
70
+ end
71
+ b = Time.now.to_f
72
+ elapsed = b - a
73
+ STDERR.puts "\n#{ label.to_s } (never became true in #{ elapsed } seconds!)"
74
+ assert(false, label)
75
+ end
76
+
77
+ def subclass_of exception
78
+ class << exception
79
+ def ==(other) super or self > other end
80
+ end
81
+ exception
82
+ end
83
+
84
+ include Models
85
+ end
86
+ end
87
+ end
88
+
89
+ module Kernel
90
+ private
91
+ def testing(*args, &block)
92
+ Class.new(::Test::Unit::TestCase) do
93
+ module_eval &Helene::Test::Helper
94
+ module_eval(&block)
95
+ end
96
+ end
97
+ end
98
+
File without changes
@@ -0,0 +1,8 @@
1
+
2
+ testing 'ensure' do
3
+ should 'clean out all test models' do
4
+ models.threadify do |model|
5
+ assert_nothing_raised{ model.all.threadify{|record| record.delete} }
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,106 @@
1
+ testing Bucket = Helene::S3::Bucket do
2
+
3
+
4
+ context 'with a bucket created' do
5
+ setup do
6
+ create_bucket
7
+ end
8
+
9
+ context 'at the class level' do
10
+ should 'be able to delete a bucket' do
11
+ delete_bucket
12
+ end
13
+
14
+ should 'be able to list buckets' do
15
+ list = assert{ Bucket.list }
16
+ assert{ list.is_a?(Array) }
17
+ assert{ list.include?(bucket) }
18
+ end
19
+
20
+ should 'be able to instantiate a bucket by name' do
21
+ assert{ Bucket.new bucket.name }
22
+ end
23
+
24
+ should 'be able to generate a link to view all buckets' do
25
+ url = assert{ Bucket.url }
26
+ assert{ curl(url) =~ /ListAllMyBucketsResult/ }
27
+ end
28
+
29
+ should 'be able to generate a link to create a bucket' do
30
+ create_bucket_by_url
31
+ end
32
+
33
+ should 'be able to generate a link to delete a bucket' do
34
+ delete_bucket_by_url
35
+ end
36
+ end
37
+
38
+ context 'at the instance level' do
39
+ setup do
40
+ @pathname = File.expand_path(__FILE__)
41
+ @basename = File.basename(@pathname)
42
+ @data = IO.read(@pathname)
43
+ end
44
+
45
+ should 'be able to put a pathname' do
46
+ key = assert{ bucket.put(@pathname) }
47
+ assert{ curl(key.url) == @data }
48
+ end
49
+
50
+ should "be able to put an io - returning an object that knows it's url" do
51
+ key = assert{ open(@pathname){|io| bucket.put(io)} }
52
+ assert{ curl(key.url) == @data }
53
+ end
54
+
55
+ should "be able to put/get a path" do
56
+ key = assert{ bucket.put(@pathname) }
57
+ data = assert{ bucket.get(key.name) }
58
+ assert{ data == @data }
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+
65
+
66
+ def bucket_name(options = {})
67
+ "helene-s3-bucket-test-#{ Helene.uuid }"
68
+ end
69
+
70
+ def create_bucket(options = {})
71
+ @bucket ||= assert{ Bucket.create(bucket_name, options) }
72
+ # at_exit{ @bucket.delete(:force => true) rescue nil if @bucket unless $! }
73
+ at_exit{ Bucket.delete(@bucket, :force => true) rescue nil if @bucket }
74
+ end
75
+
76
+ def create_bucket_by_url
77
+ name = bucket_name
78
+ url ||= assert{ Bucket.url(:create, name) }
79
+ assert{ curl(url, :PUT) }
80
+ assert{ @bucket_url = Bucket.new(name) }
81
+ end
82
+
83
+ def delete_bucket_by_url
84
+ create_bucket_by_url unless @bucket_url
85
+ name = @bucket_url.name
86
+ url ||= assert{ Bucket.url(:delete, name) }
87
+ assert{ curl(url, :DELETE) }
88
+ assert_raises(subclass_of(Exception)){ Bucket.new(name) }
89
+ end
90
+
91
+ def bucket
92
+ @bucket
93
+ end
94
+
95
+ def delete_bucket(options = {})
96
+ create_bucket unless @bucket
97
+ assert{ Bucket.delete(@bucket, options) }
98
+ @bucket = nil
99
+ end
100
+
101
+ def curl(url, options = {})
102
+ options = {:method => options} unless options.is_a?(Hash)
103
+ method = options[:method] || :GET
104
+ `curl --silent --insecure --location --request #{ method.to_s } #{ url.inspect } 2>/dev/null`
105
+ end
106
+ end
@@ -0,0 +1,45 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'associations' do
4
+ context 'has_many' do
5
+ setup do
6
+ @a = model(:a) do
7
+ has_many :bs
8
+ end
9
+ @b = model(:b) do
10
+ attribute :a_id
11
+ end
12
+ end
13
+
14
+ should 'support simple has_many' do
15
+ a = assert{ @a.create! }
16
+ assert{ a.respond_to?(:bs) }
17
+ b = assert{ @b.create! }
18
+ assert{ b.respond_to?(:a_id) }
19
+ assert{ a.bs << b }
20
+ assert{ b.a_id == a.id }
21
+ end
22
+ end
23
+
24
+ context 'has_one' do
25
+ setup do
26
+ @a = model(:a) do
27
+ has_one :b
28
+ end
29
+ @b = model(:b) do
30
+ attribute :a_id
31
+ end
32
+ end
33
+
34
+ should 'support simple has_one' do
35
+ a = assert{ @a.create! }
36
+ assert{ a.respond_to?(:b) }
37
+ b = assert{ @b.create! }
38
+ assert{ b.respond_to?(:a_id) }
39
+ assert{ a.b = b }
40
+ assert{ b.a_id == a.id }
41
+ end
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,13 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'creating' do
4
+ setup do
5
+ @a = model(:a){}
6
+ end
7
+
8
+ should 'be able to create' do
9
+ assert{ @a.create! }
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,56 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'emptiness' do
4
+ setup do
5
+ @a = model(:a) do
6
+ attribute :x, :string
7
+ attribute :y, :set_of_string
8
+ end
9
+ end
10
+
11
+ perform = 'represent nil'
12
+ should perform do
13
+ a = assert{ @a.create! :x => nil }
14
+ assert{ a.x.nil? }
15
+ eventually_assert(perform){ a.reload; a.x.nil? }
16
+ end
17
+
18
+ perform = 'represent the empty list'
19
+ should perform do
20
+ a = assert{ @a.create! :y => [] }
21
+ assert{ a.y==[] }
22
+ eventually_assert(perform){ a.reload; a.y==[] }
23
+ end
24
+
25
+ perform = 'represent a list of just nil'
26
+ should perform do
27
+ a = assert{ @a.create! :y => [nil] }
28
+ assert{ a.y==[nil] }
29
+ eventually_assert(perform){ a.reload; a.y==[nil] }
30
+ end
31
+
32
+ perform = 'represent the empty string'
33
+ should perform do
34
+ a = assert{ @a.create! :x => '' }
35
+ assert{ a.x=='' }
36
+ eventually_assert(perform){ a.reload; a.x=='' }
37
+ end
38
+
39
+ perform = 'represent a list of just the empty string'
40
+ should perform do
41
+ a = assert{ @a.create! :y => [''] }
42
+ assert{ a.y==[''] }
43
+ eventually_assert(perform){ a.reload; a.y==[''] }
44
+ end
45
+
46
+ =begin
47
+ perform = 'represent a list nil and the empty string'
48
+ should perform do
49
+ a = assert{ @a.create! :y => [nil, ''] }
50
+ assert{ a.y==[nil, ''] }
51
+ eventually_assert(perform){ a.reload; a.y==[nil, ''] }
52
+ end
53
+ =end
54
+ end
55
+
56
+ end
@@ -0,0 +1,19 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'hooks' do
4
+ setup do
5
+ @a = model(:a) do
6
+ attribute :x, :string
7
+ before_save{ update :x => '42' }
8
+ end
9
+ end
10
+
11
+ perform = 'before_save'
12
+ should perform do
13
+ a = assert{ @a.create! }
14
+ assert{ a.x=='42' }
15
+ eventually_assert(perform){ a.reload; a.x=='42' }
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,27 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'limit > 2500' do
4
+ setup do
5
+ @a = model(:a)
6
+ end
7
+
8
+ perform = 'get all the results'
9
+ should perform do
10
+ n = 2501
11
+ assert_nothing_raised do
12
+ # if @a.count < n
13
+ records = Array.new(n){ @a.new }
14
+ a = Time.now.to_f
15
+ @a.batch_put records
16
+ b = Time.now.to_f
17
+ #puts(b - a)
18
+ # end
19
+ end
20
+ eventually_assert(perform) do
21
+ result = @a.find(:all, :limit => n)
22
+ assert result.size == n
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,21 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'saving' do
4
+ setup do
5
+ @a = model(:a)
6
+ @b = model(:b) do
7
+ attribute :foo, :null => false
8
+ end
9
+ end
10
+
11
+ should 'be able to save a valid object' do
12
+ assert{ @a.new.save }
13
+ assert{ @b.new(:foo=>'foo').save }
14
+ end
15
+
16
+ should 'not be able to save an invalid object' do
17
+ assert{ @b.new(:foo=>nil).save == false }
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,39 @@
1
+ testing Helene::Sdb::Base do
2
+
3
+ context 'selecting' do
4
+ setup do
5
+ @a = model(:a)
6
+ @b = model(:b)
7
+ @c = model(:c)
8
+ end
9
+
10
+ perform = 'be able to find by id'
11
+ should perform do
12
+ a = assert{ @a.create! }
13
+ eventually_assert(perform) do
14
+ found = @a.find(a.id)
15
+ found and found.id == a.id
16
+ end
17
+ end
18
+
19
+ perform = 'be able to find by many ids'
20
+ should perform do
21
+ a = assert{ @a.create! }
22
+ eventually_assert(perform) do
23
+ list = @a.find([a.id, a.id])
24
+ list.all?{|found| found.id==a.id}
25
+ end
26
+ end
27
+
28
+ perform = 'be able to find by > 20 ids'
29
+ should perform do
30
+ a = assert{ @a.create! }
31
+ ids = Array.new(42){ a.id }
32
+ eventually_assert(perform) do
33
+ list = assert{ @a.find(ids) }
34
+ list and list.all?{|found| found.id == a.id}
35
+ end
36
+ end
37
+ end
38
+
39
+ end