dm-adapter-simpledb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
3
+
4
+ class Enemy
5
+ include DataMapper::Resource
6
+
7
+ property :id, String, :key => true
8
+ property :name, String, :key => true
9
+ property :age, Integer
10
+ property :wealth, Float
11
+ property :birthday, Date
12
+ property :created_at, DateTime
13
+ end
14
+
15
+ describe 'with nils records saved and retreived' do
16
+ before(:all) do
17
+ @person_attrs = { :id => "person-#{Time.now.to_f.to_s}", :name => 'Jeremy Boles', :age => 25, :wealth => 25.00, :birthday => Date.today }
18
+ @jeremy = Enemy.create(@person_attrs.merge(:id => Time.now.to_f.to_s, :name => "Jeremy Boles", :age => 25))
19
+ @danielle = Enemy.create(@person_attrs.merge(:id => Time.now.to_f.to_s, :name => "Danielle", :age => nil, :birthday => nil))
20
+ @adapter.wait_for_consistency
21
+ end
22
+
23
+ after(:all) do
24
+ @jeremy.destroy
25
+ @danielle.destroy
26
+ @adapter.wait_for_consistency
27
+ end
28
+
29
+ it 'should get all records' do
30
+ Enemy.all.length.should == 2
31
+ end
32
+
33
+ it 'should retrieve nil values' do
34
+ records = people = Enemy.all(:name => "Danielle")
35
+ people.length.should == 1
36
+ people[0].age.should == nil
37
+ people[0].birthday.should == nil
38
+ end
39
+
40
+ it 'should find based on nil values' do
41
+ @people = Enemy.all(:age => nil)
42
+ @people.should include(@danielle)
43
+ end
44
+
45
+ end
@@ -0,0 +1,71 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
3
+ require Pathname(__FILE__).dirname.expand_path + '../lib/simpledb_adapter/sdb_array'
4
+ require 'spec/autorun'
5
+
6
+ describe 'with multiple records saved' do
7
+
8
+ class Hobbyist
9
+ include DataMapper::Resource
10
+ property :name, String, :key => true
11
+ property :hobbies, SdbArray
12
+ end
13
+
14
+ before(:each) do
15
+ @jeremy = Hobbyist.create(:name => "Jeremy Boles", :hobbies => ["biking", "diving", "chess"])
16
+ @danielle = Hobbyist.create(:name => "Danille Boles", :hobbies => ["swimming", "diving"])
17
+ @keegan = Hobbyist.create(:name => "Keegan Jones", :hobbies => ["painting"])
18
+ @adapter.wait_for_consistency
19
+ end
20
+
21
+ after(:each) do
22
+ @jeremy.destroy
23
+ @danielle.destroy
24
+ @keegan.destroy
25
+ end
26
+
27
+ it 'should store hobbies as array' do
28
+ person = Hobbyist.first(:name => 'Jeremy Boles')
29
+ person.hobbies.sort.should == ["biking", "diving", "chess"].sort
30
+ end
31
+
32
+ it 'should allow updates to array' do
33
+ person = Hobbyist.first(:name => 'Jeremy Boles')
34
+ person.hobbies = ["lego"]
35
+ person.save
36
+ @adapter.wait_for_consistency
37
+ lego_person = Hobbyist.first(:name => 'Jeremy Boles')
38
+ lego_person.hobbies.should == "lego"
39
+ end
40
+
41
+ it 'should allow deletion of array' do
42
+ person = Hobbyist.first(:name => 'Jeremy Boles')
43
+ person.hobbies = []
44
+ person.save
45
+ @adapter.wait_for_consistency
46
+ lego_person = Hobbyist.first(:name => 'Jeremy Boles')
47
+ lego_person.hobbies.should == nil
48
+ end
49
+
50
+ it 'should find all records with diving hobby' do
51
+ people = Hobbyist.all(:hobbies => 'diving')
52
+ people.should include(@jeremy)
53
+ people.should include(@danielle)
54
+ people.should_not include(@keegan)
55
+ end
56
+
57
+ it 'should find all records with painting hobby' do
58
+ people = Hobbyist.all(:hobbies => ['painting'])
59
+ people.should_not include(@jeremy)
60
+ people.should_not include(@danielle)
61
+ people.should include(@keegan)
62
+ end
63
+
64
+ it "should find all records with like operator" do
65
+ people = Hobbyist.all(:hobbies.like => 'pa%')
66
+ people.should_not include(@jeremy)
67
+ people.should_not include(@danielle)
68
+ people.should include(@keegan)
69
+ end
70
+
71
+ end
@@ -0,0 +1,162 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
3
+
4
+ class Friend
5
+ include DataMapper::Resource
6
+
7
+ property :id, String, :key => true
8
+ property :name, String, :key => true
9
+ property :long_name, String
10
+ property :long_name_two, String
11
+ property :age, Integer
12
+ property :wealth, Float
13
+ property :birthday, Date
14
+ property :created_at, DateTime
15
+ property :long_string, String
16
+
17
+ belongs_to :network
18
+ end
19
+
20
+ class Network
21
+ include DataMapper::Resource
22
+
23
+ property :id, String, :key => true
24
+ property :name, String, :key => true
25
+
26
+ has n, :friends
27
+ end
28
+
29
+ describe DataMapper::Adapters::SimpleDBAdapter do
30
+
31
+ LONG_VALUE =<<-EOF
32
+ #!/bin/sh
33
+
34
+ set -o errexit
35
+
36
+ ################################################################################
37
+ # build
38
+ #
39
+ # This hook is responsible for running a full "build" of the project for the
40
+ # purpose of Continuus Integration
41
+ #
42
+ ################################################################################
43
+
44
+ rake
45
+ # && rake metrics:all
46
+
47
+ #more
48
+ EOF
49
+
50
+ before(:each) do
51
+
52
+
53
+ @friend_attrs = { :id => "person-#{Time.now.to_f.to_s}", :name => 'Jeremy Boles', :age => 25, :wealth => 25.00, :birthday => Date.today,
54
+ :long_name => 'short', :long_name_two => 'short', :long_string => LONG_VALUE}
55
+ #.gsub("\n","br")
56
+ @friend = Friend.new(@friend_attrs)
57
+ end
58
+
59
+ it 'should create a record' do
60
+ @friend.save.should be_true
61
+ @friend.id.should_not be_nil
62
+ @friend.destroy
63
+ end
64
+
65
+ describe 'with a saved record' do
66
+ before(:each) { @friend.save; sleep(0.4) } #sleep or it might not be on SDB at when the test checks it
67
+ after(:each) { @friend.destroy; sleep(0.4) } #same issues for the next test could still be there
68
+
69
+ it 'should get a record' do
70
+ person = Friend.get!(@friend.id, @friend.name)
71
+ person.should_not be_nil
72
+ person.wealth.should == @friend.wealth
73
+ end
74
+
75
+ it 'should not get records of the wrong type by id' do
76
+ Network.get(@friend.id, @friend.name).should == nil
77
+ lambda { Network.get!(@friend.id, @friend.name) }.should raise_error(DataMapper::ObjectNotFoundError)
78
+ end
79
+
80
+ it 'should update a record' do
81
+ person = Friend.get!(@friend.id, @friend.name)
82
+ person.wealth = 100.00
83
+ person.save
84
+ sleep(0.3)
85
+ person = Friend.get!(@friend.id, @friend.name)
86
+ person.wealth.should_not == @friend.wealth
87
+ person.age.should == @friend.age
88
+ person.id.should == @friend.id
89
+ person.name.should == @friend.name
90
+ end
91
+
92
+ it 'should update a record with a long string over 1024' do
93
+ person = Friend.get!(@friend.id, @friend.name)
94
+ long_string = "*" * 1026
95
+ person.long_name = long_string
96
+ person.save
97
+ sleep(0.3)
98
+ person = Friend.get!(@friend.id, @friend.name)
99
+ person.long_name.should == long_string
100
+ person.id.should == @friend.id
101
+ person.name.should == @friend.name
102
+ end
103
+
104
+ it 'should update a record with with two long strings over 1024' do
105
+ person = Friend.get!(@friend.id, @friend.name)
106
+ long_string = "*" * 1026
107
+ long_string_two = (0...2222).map{ ('a'..'z').to_a[rand(26)] }.join
108
+ person.long_name = long_string
109
+ person.long_name_two = long_string_two
110
+ person.save
111
+ sleep(0.3)
112
+ person = Friend.get!(@friend.id, @friend.name)
113
+ person.long_name.should == long_string
114
+ person.long_name_two.should == long_string_two
115
+ person.id.should == @friend.id
116
+ person.name.should == @friend.name
117
+ end
118
+
119
+ it 'should save a record with string in the correct order' do
120
+ person = Friend.get!(@friend.id, @friend.name)
121
+ person.long_string.should == LONG_VALUE#.gsub("\n","br")
122
+ end
123
+
124
+ it 'should destroy a record' do
125
+ @friend.destroy.should be_true
126
+ sleep(0.4) #make sure SDB propigates change
127
+ lambda {Friend.get!(@friend.id, @friend.name)}.should raise_error(DataMapper::ObjectNotFoundError)
128
+ persons = Friend.all(:name => @friend.name)
129
+ persons.length.should == 0
130
+ end
131
+
132
+ describe '#query' do
133
+ before(:each) do
134
+ @domain = Friend.repository(:default).adapter.sdb_options[:domain]
135
+ end
136
+ it "should return an array of records" do
137
+ records = Friend.repository(:default).adapter.query("SELECT age, wealth from #{@domain} where age = '25'")
138
+ records.should == [{"wealth"=>["25.0"], "age"=>["25"]}]
139
+ end
140
+ it "should return empty array if no matches" do
141
+ records = Friend.repository(:default).adapter.query("SELECT age, wealth from #{@domain} where age = '15'")
142
+ records.should be_empty
143
+ end
144
+ it "should raise an error if query is invalid" do
145
+ lambda do
146
+ records = Friend.repository(:default).adapter.query("SELECT gaga")
147
+ end.should raise_error(RightAws::AwsError)
148
+ end
149
+ end
150
+ describe 'aggregate' do
151
+ it "should respond to count(*)" do
152
+ Friend.count.should == 1
153
+ end
154
+ it "should not respond to any other aggregates" do
155
+ lambda { Friend.min(:age) }.should raise_error(ArgumentError)
156
+ lambda { Friend.max(:age) }.should raise_error(ArgumentError)
157
+ lambda { Friend.avg(:age) }.should raise_error(ArgumentError)
158
+ lambda { Friend.sum(:age) }.should raise_error(ArgumentError)
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
@@ -0,0 +1,67 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.parent.expand_path + 'lib/simpledb_adapter'
3
+ require 'logger'
4
+ require 'fileutils'
5
+ require 'spec'
6
+
7
+ DOMAIN_FILE_MESSAGE = <<END
8
+ !!! ATTENTION !!!
9
+ In order to operate, these specs need a throwaway SimpleDB domain to operate
10
+ in. This domain WILL BE DELETED BEFORE EVERY SUITE IS RUN. In order to
11
+ avoid unexpected data loss, you are required to manually configure the
12
+ throwaway domain. In order to configure the domain, create a file in the
13
+ project root directory named THROW_AWAY_SDB_DOMAIN. It's contents should be
14
+ the name of the SimpleDB domain to use for tests. E.g.
15
+
16
+ $ echo dm_simpledb_adapter_test > THROW_AWAY_SDB_DOMAIN
17
+
18
+ END
19
+
20
+ Spec::Runner.configure do |config|
21
+ access_key = ENV['AMAZON_ACCESS_KEY_ID']
22
+ secret_key = ENV['AMAZON_SECRET_ACCESS_KEY']
23
+ domain_file = File.expand_path('../THROW_AWAY_SDB_DOMAIN', File.dirname(__FILE__))
24
+ test_domain = if File.exist?(domain_file)
25
+ File.read(domain_file).strip
26
+ else
27
+ warn DOMAIN_FILE_MESSAGE
28
+ exit 1
29
+ end
30
+
31
+ #For those that don't like to mess up their ENV
32
+ if access_key==nil && secret_key==nil
33
+ lines = File.readlines(File.join(File.dirname(__FILE__),'..','aws_config'))
34
+ access_key = lines[0].strip
35
+ secret_key = lines[1].strip
36
+ end
37
+
38
+ # Run just once
39
+ config.before :suite do
40
+ FileUtils.mkdir_p('log') unless File.exists?('log')
41
+ log_file = "log/dm-sdb.log"
42
+ FileUtils.touch(log_file)
43
+ log = Logger.new(log_file)
44
+
45
+ $control_sdb ||= RightAws::SdbInterface.new(
46
+ access_key, secret_key, :domain => test_domain)
47
+
48
+ DataMapper.logger.set_log(log_file, :debug)
49
+ DataMapper.setup(:default, {
50
+ :adapter => 'simpledb',
51
+ :access_key => access_key,
52
+ :secret_key => secret_key,
53
+ :domain => test_domain,
54
+ :logger => log,
55
+ :wait_for_consistency => :manual
56
+ })
57
+ end
58
+
59
+ # Run before each group
60
+ config.before :all do
61
+ @adapter = DataMapper::Repository.adapters[:default]
62
+ @sdb ||= $control_sdb
63
+ @sdb.delete_domain(test_domain)
64
+ @sdb.create_domain(test_domain)
65
+ @domain = test_domain
66
+ end
67
+ end
@@ -0,0 +1,167 @@
1
+ require 'rake'
2
+
3
+ namespace :devver do
4
+
5
+ APP_CALL = 'devver'
6
+ # List any test files you do not want to run on Devver. This array can contain names and regular expressions.
7
+ EXCLUDED_TEST_FILES = []
8
+
9
+ desc "Runs all units functionals and integration tests on Devver"
10
+ task :test do
11
+ errors = %w(devver:test:units devver:test:functionals devver:test:integration).collect do |task|
12
+ begin
13
+ Rake::Task[task].invoke
14
+ nil
15
+ rescue => e
16
+ task
17
+ end
18
+ end.compact
19
+ abort "Errors running #{errors.join(", ").to_s}!" if errors.any?
20
+ end
21
+
22
+ desc "Forces Devver to rerun migration files"
23
+ task :migrate do
24
+ command = "#{APP_CALL} --db"
25
+ puts command
26
+ system(command)
27
+ end
28
+
29
+ desc "Forces Devver to sync all changed files"
30
+ task :sync do
31
+ command = "#{APP_CALL} --sync"
32
+ puts command
33
+ system(command)
34
+ end
35
+
36
+ desc "Delete the Devver project ID for this project. The next time you connect to Devver, you'll be assigned a new project ID"
37
+ task :reset do
38
+ command = "rm .devver/project_id"
39
+ system(command)
40
+ puts "Your project has been reset successfully"
41
+ end
42
+
43
+ desc "Delete all of the project files on the server and resync"
44
+ task :reload do
45
+ command = "#{APP_CALL} --reload"
46
+ puts command
47
+ system(command)
48
+ end
49
+
50
+ desc "Runs all specs on Devver"
51
+ task :spec do
52
+ devvertest('spec/**/*_spec.rb')
53
+ end
54
+
55
+ namespace :spec do
56
+ desc "Runs all model specs on Devver"
57
+ task :model do
58
+ devvertest('spec/models/**/*_spec.rb')
59
+ end
60
+
61
+ desc "Runs all request specs on Devver"
62
+ task :request do
63
+ devvertest('spec/requests/**/*_spec.rb')
64
+ end
65
+
66
+ desc "Runs all controller specs on Devver"
67
+ task :controller do
68
+ devvertest('spec/controllers/**/*_spec.rb')
69
+ end
70
+
71
+ desc "Runs all view specs on Devver"
72
+ task :view do
73
+ devvertest('spec/views/**/*_spec.rb')
74
+ end
75
+
76
+ desc "Runs all helper specs on Devver"
77
+ task :helper do
78
+ devvertest('spec/helpers/**/*_spec.rb')
79
+ end
80
+
81
+ desc "Runs all lib specs on Devver"
82
+ task :lib do
83
+ devvertest('spec/lib/**/*_spec.rb')
84
+ end
85
+
86
+ end
87
+
88
+
89
+ namespace :test do
90
+ desc "Runs all unit tests on Devver"
91
+ task :units do
92
+ devvertest('test/unit/**/*_test.rb')
93
+ end
94
+
95
+ desc "Runs all functional tests on Devver"
96
+ task :functionals do
97
+ devvertest('test/functional/**/*_test.rb')
98
+ end
99
+
100
+ desc "Runs all integration tests on Devver"
101
+ task :integration do
102
+ devvertest('test/integration/**/*_test.rb')
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+ def remove_excluded_files(files)
109
+ removed_files = []
110
+ files.each do |file|
111
+ EXCLUDED_TEST_FILES.each do |exclude|
112
+ removed_files << file if exclude===file
113
+ end
114
+ end
115
+ removed_files = removed_files.flatten
116
+ files = files - removed_files
117
+ [files, removed_files]
118
+ end
119
+
120
+ def run_tests_locally(files)
121
+ puts "Running the excluded test files locally"
122
+ # Run RSpec files
123
+ if files.first=~/_spec.rb/
124
+ command ="spec "
125
+ else # Run Test::Unit files
126
+ command = 'ruby -e "ARGV.each{|f| load f unless f =~ /^-/}" '
127
+ end
128
+ command += files.join(" ")
129
+ puts command
130
+ results = system(command)
131
+ raise RuntimeError.new("Command failed with status (1)") unless results
132
+ end
133
+
134
+ def get_env_var(var_name)
135
+ ENV[var_name] || ENV[var_name.upcase]
136
+ end
137
+
138
+ def devvertest(pattern)
139
+ reload = get_env_var('reload')=='true' ? true : false
140
+ #default sync to true
141
+ sync = true
142
+ sync = false if get_env_var('sync')=='false'
143
+ cache = get_env_var('cache')=='true' ? true : false
144
+ db = get_env_var('db')=='true' ? true : false
145
+ run_excluded = get_env_var('run_excluded')
146
+ if run_excluded=='true' || run_excluded=='after'
147
+ run_excluded = 'after'
148
+ elsif run_excluded=='only'
149
+ run_excluded = 'only'
150
+ else
151
+ run_excluded = ''
152
+ end
153
+
154
+ files = FileList[pattern].to_a
155
+ files, removed_files = remove_excluded_files(files)
156
+
157
+ if run_excluded!='only'
158
+ command = "#{APP_CALL} #{'--reload' if reload} #{'--nosync' if !sync} #{'--db' if db} #{'--cache' if cache} #{files.join(' ')}"
159
+ puts command
160
+ results = system(command)
161
+ raise RuntimeError.new("Command failed with status (1)") unless results
162
+ end
163
+
164
+ if run_excluded=='only' || run_excluded=='after'
165
+ run_tests_locally(removed_files) if removed_files.length > 0
166
+ end
167
+ end