aws-sessionstore-dynamodb 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -5
- data/.yardopts +3 -2
- data/CHANGELOG.md +24 -0
- data/CODE_OF_CONDUCT.md +4 -0
- data/CONTRIBUTING.md +61 -0
- data/Gemfile +7 -19
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +17 -63
- data/Rakefile +37 -14
- data/VERSION +1 -0
- data/aws-sessionstore-dynamodb.gemspec +7 -5
- data/doc-src/templates/default/layout/html/footer.erb +10 -0
- data/doc-src/templates/default/layout/html/layout.erb +31 -0
- data/lib/aws-sessionstore-dynamodb.rb +0 -15
- data/lib/aws/session_store/dynamo_db/configuration.rb +2 -29
- data/lib/aws/session_store/dynamo_db/errors/base_handler.rb +0 -14
- data/lib/aws/session_store/dynamo_db/errors/default_handler.rb +0 -14
- data/lib/aws/session_store/dynamo_db/garbage_collection.rb +2 -15
- data/lib/aws/session_store/dynamo_db/invalid_id_error.rb +0 -14
- data/lib/aws/session_store/dynamo_db/lock_wait_timeout_error.rb +0 -14
- data/lib/aws/session_store/dynamo_db/locking/base.rb +14 -17
- data/lib/aws/session_store/dynamo_db/locking/null.rb +0 -14
- data/lib/aws/session_store/dynamo_db/locking/pessimistic.rb +0 -16
- data/lib/aws/session_store/dynamo_db/missing_secret_key_error.rb +0 -14
- data/lib/aws/session_store/dynamo_db/rack_middleware.rb +11 -24
- data/lib/aws/session_store/dynamo_db/table.rb +1 -14
- data/lib/aws/session_store/dynamo_db/version.rb +1 -15
- data/spec/aws/session_store/dynamo_db/app_config.yml +6 -6
- data/spec/aws/session_store/dynamo_db/configuration_spec.rb +28 -51
- data/spec/aws/session_store/dynamo_db/error/default_error_handler_spec.rb +23 -21
- data/spec/aws/session_store/dynamo_db/garbage_collection_spec.rb +68 -69
- data/spec/aws/session_store/dynamo_db/locking/threaded_sessions_spec.rb +17 -16
- data/spec/aws/session_store/dynamo_db/rack_middleware_database_spec.rb +47 -46
- data/spec/aws/session_store/dynamo_db/rack_middleware_spec.rb +59 -61
- data/spec/aws/session_store/dynamo_db/table_spec.rb +9 -7
- data/spec/spec_helper.rb +14 -11
- metadata +27 -29
- data/lib/aws/session_store/dynamo_db/railtie.rb +0 -28
- data/lib/aws/session_store/dynamo_db/tasks/session_table.rake +0 -21
- data/lib/rails/generators/sessionstore/dynamodb/dynamodb_generator.rb +0 -55
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/USAGE +0 -13
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/dynamodb.yml +0 -71
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore_migration.rb +0 -10
- data/spec/aws/session_store/dynamo_db/config/dynamo_db_session.yml +0 -24
- data/spec/aws/session_store/dynamo_db/rails_app_config.yml +0 -24
- data/tasks/test.rake +0 -29
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
@@ -11,7 +13,6 @@
|
|
11
13
|
# ANY KIND, either express or implied. See the License for the specific
|
12
14
|
# language governing permissions and limitations under the License.
|
13
15
|
|
14
|
-
|
15
16
|
require 'spec_helper'
|
16
17
|
|
17
18
|
describe Aws::SessionStore::DynamoDB do
|
@@ -20,43 +21,44 @@ describe Aws::SessionStore::DynamoDB do
|
|
20
21
|
instance_exec(&ConstantHelpers)
|
21
22
|
|
22
23
|
before do
|
23
|
-
@options = { :
|
24
|
+
@options = { dynamo_db_client: client, secret_key: 'meltingbutter' }
|
24
25
|
end
|
25
26
|
|
26
27
|
let(:base_app) { MultiplierApplication.new }
|
27
28
|
let(:app) { Aws::SessionStore::DynamoDB::RackMiddleware.new(base_app, @options) }
|
28
29
|
let(:client) { double('Aws::DynamoDB::Client') }
|
29
30
|
|
30
|
-
context
|
31
|
-
it
|
32
|
-
client.
|
33
|
-
|
31
|
+
context 'Error handling for Rack Middleware with default error handler' do
|
32
|
+
it 'raises error for missing secret key' do
|
33
|
+
allow(client).to receive(:update_item).and_raise(missing_key_error)
|
34
|
+
expect { get '/' }.to raise_error(missing_key_error)
|
34
35
|
end
|
35
36
|
|
36
|
-
it
|
37
|
-
client.
|
38
|
-
|
37
|
+
it 'catches exception for inaccurate table name and raises error ' do
|
38
|
+
allow(client).to receive(:update_item).and_raise(resource_error)
|
39
|
+
expect { get '/' }.to raise_error(resource_error)
|
39
40
|
end
|
40
41
|
|
41
|
-
it
|
42
|
-
client.
|
43
|
-
client.
|
44
|
-
|
45
|
-
|
42
|
+
it 'catches exception for inaccurate table key' do
|
43
|
+
allow(client).to receive(:update_item).and_raise(key_error)
|
44
|
+
allow(client).to receive(:get_item).and_raise(key_error)
|
45
|
+
|
46
|
+
get '/'
|
47
|
+
expect(last_request.env['rack.errors'].string).to include(key_error_msg)
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
context
|
50
|
-
it
|
51
|
+
context 'Test ExceptionHandler with true as return value for handle_error' do
|
52
|
+
it 'raises all errors' do
|
51
53
|
@options[:raise_errors] = true
|
52
|
-
client.
|
53
|
-
|
54
|
+
allow(client).to receive(:update_item).and_raise(client_error)
|
55
|
+
expect { get '/' }.to raise_error(client_error)
|
54
56
|
end
|
55
57
|
|
56
|
-
it
|
58
|
+
it 'catches exception for inaccurate table key and raises error' do
|
57
59
|
@options[:raise_errors] = true
|
58
|
-
client.
|
59
|
-
|
60
|
+
allow(client).to receive(:update_item).and_raise(key_error)
|
61
|
+
expect { get '/' }.to raise_error(key_error)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
@@ -14,80 +16,79 @@
|
|
14
16
|
require 'spec_helper'
|
15
17
|
|
16
18
|
describe Aws::SessionStore::DynamoDB::GarbageCollection do
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def items(min, max)
|
20
|
+
items = []
|
21
|
+
(min..max).each do |i|
|
22
|
+
items << { 'session_id' => { s: i.to_s } }
|
21
23
|
end
|
22
|
-
|
24
|
+
items
|
23
25
|
end
|
24
26
|
|
25
27
|
def format_scan_result
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
items = []
|
29
|
+
(31..49).each do |i|
|
30
|
+
items << { 'session_id' => { s: i.to_s } }
|
29
31
|
end
|
30
32
|
|
31
|
-
|
32
|
-
rqst_array << {:
|
33
|
-
rqst_array
|
33
|
+
items.each_with_object([]) do |item, rqst_array|
|
34
|
+
rqst_array << { delete_request: { key: item } }
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
38
|
def collect_garbage
|
38
|
-
options = { :
|
39
|
+
options = { dynamo_db_client: dynamo_db_client, max_age: 100, max_stale: 100 }
|
39
40
|
Aws::SessionStore::DynamoDB::GarbageCollection.collect_garbage(options)
|
40
41
|
end
|
41
42
|
|
42
|
-
let(:scan_resp1)
|
43
|
+
let(:scan_resp1) do
|
43
44
|
resp = {
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
45
|
+
items: items(0, 49),
|
46
|
+
count: 50,
|
47
|
+
scanned_count: 1000,
|
48
|
+
last_evaluated_key: {}
|
48
49
|
}
|
49
|
-
|
50
|
+
end
|
50
51
|
|
51
|
-
let(:scan_resp2)
|
52
|
+
let(:scan_resp2) do
|
52
53
|
{
|
53
|
-
:
|
54
|
-
:
|
54
|
+
items: items(0, 31),
|
55
|
+
last_evaluated_key: { 'session_id' => { s: '31' } }
|
55
56
|
}
|
56
|
-
|
57
|
+
end
|
57
58
|
|
58
|
-
let(:scan_resp3)
|
59
|
+
let(:scan_resp3) do
|
59
60
|
{
|
60
|
-
:
|
61
|
-
:
|
61
|
+
items: items(31, 49),
|
62
|
+
last_evaluated_key: {}
|
62
63
|
}
|
63
|
-
|
64
|
+
end
|
64
65
|
|
65
|
-
let(:write_resp1)
|
66
|
+
let(:write_resp1) do
|
66
67
|
{
|
67
|
-
:
|
68
|
+
unprocessed_items: {}
|
68
69
|
}
|
69
|
-
|
70
|
+
end
|
70
71
|
|
71
|
-
let(:write_resp2)
|
72
|
+
let(:write_resp2) do
|
72
73
|
{
|
73
|
-
:
|
74
|
-
|
74
|
+
unprocessed_items: {
|
75
|
+
'sessions' => [
|
75
76
|
{
|
76
|
-
:
|
77
|
-
:
|
78
|
-
|
77
|
+
delete_request: {
|
78
|
+
key: {
|
79
|
+
'session_id' =>
|
79
80
|
{
|
80
|
-
:
|
81
|
+
s: '1'
|
81
82
|
}
|
82
83
|
}
|
83
84
|
}
|
84
85
|
},
|
85
86
|
{
|
86
|
-
:
|
87
|
-
:
|
88
|
-
|
87
|
+
delete_request: {
|
88
|
+
key: {
|
89
|
+
'session_id' =>
|
89
90
|
{
|
90
|
-
:
|
91
|
+
s: '17'
|
91
92
|
}
|
92
93
|
}
|
93
94
|
}
|
@@ -95,64 +96,62 @@ describe Aws::SessionStore::DynamoDB::GarbageCollection do
|
|
95
96
|
]
|
96
97
|
}
|
97
98
|
}
|
98
|
-
|
99
|
+
end
|
99
100
|
|
100
101
|
let(:dynamo_db_client) {Aws::DynamoDB::Client.new}
|
101
102
|
|
102
|
-
context
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
dynamo_db_client.should_receive(:batch_write_item).
|
103
|
+
context 'Mock DynamoDB client with garbage collection' do
|
104
|
+
it 'processes scan result greater than 25 and deletes in batches of 25' do
|
105
|
+
expect(dynamo_db_client).to receive(:scan)
|
106
|
+
.exactly(1).times.and_return(scan_resp1)
|
107
|
+
expect(dynamo_db_client).to receive(:batch_write_item).
|
108
108
|
exactly(2).times.and_return(write_resp1)
|
109
109
|
collect_garbage
|
110
110
|
end
|
111
111
|
|
112
|
-
it
|
113
|
-
dynamo_db_client.
|
112
|
+
it 'gets scan results then returns last evaluated key and resumes scanning' do
|
113
|
+
expect(dynamo_db_client).to receive(:scan).
|
114
114
|
exactly(1).times.and_return(scan_resp2)
|
115
|
-
dynamo_db_client.
|
115
|
+
expect(dynamo_db_client).to receive(:scan).
|
116
116
|
exactly(1).times.with(hash_including(exclusive_start_key: scan_resp2[:last_evaluated_key])).
|
117
117
|
and_return(scan_resp3)
|
118
|
-
dynamo_db_client.
|
118
|
+
expect(dynamo_db_client).to receive(:batch_write_item).
|
119
119
|
exactly(3).times.and_return(write_resp1)
|
120
|
-
|
120
|
+
collect_garbage
|
121
121
|
end
|
122
122
|
|
123
|
-
it
|
124
|
-
dynamo_db_client.
|
123
|
+
it 'it formats unprocessed_items and then batch deletes them' do
|
124
|
+
expect(dynamo_db_client).to receive(:scan).
|
125
125
|
exactly(1).times.and_return(scan_resp3)
|
126
|
-
dynamo_db_client.
|
127
|
-
with(:
|
126
|
+
expect(dynamo_db_client).to receive(:batch_write_item).ordered.
|
127
|
+
with(request_items: { 'sessions' => format_scan_result }).
|
128
128
|
and_return(write_resp2)
|
129
|
-
dynamo_db_client.
|
130
|
-
:
|
131
|
-
|
132
|
-
"sessions" => [
|
129
|
+
expect(dynamo_db_client).to receive(:batch_write_item).ordered.with(
|
130
|
+
request_items: {
|
131
|
+
'sessions' => [
|
133
132
|
{
|
134
|
-
:
|
135
|
-
:
|
136
|
-
|
133
|
+
delete_request: {
|
134
|
+
key: {
|
135
|
+
'session_id' =>
|
137
136
|
{
|
138
|
-
:
|
137
|
+
s: '1'
|
139
138
|
}
|
140
139
|
}
|
141
140
|
}
|
142
141
|
},
|
143
142
|
{
|
144
|
-
:
|
145
|
-
:
|
146
|
-
|
143
|
+
delete_request: {
|
144
|
+
key: {
|
145
|
+
'session_id' =>
|
147
146
|
{
|
148
|
-
:
|
147
|
+
s: '17'
|
149
148
|
}
|
150
149
|
}
|
151
150
|
}
|
152
151
|
}
|
153
152
|
]
|
154
153
|
}
|
155
|
-
|
154
|
+
).and_return(write_resp1)
|
156
155
|
collect_garbage
|
157
156
|
end
|
158
157
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
@@ -11,7 +13,6 @@
|
|
11
13
|
# ANY KIND, either express or implied. See the License for the specific
|
12
14
|
# language governing permissions and limitations under the License.
|
13
15
|
|
14
|
-
|
15
16
|
require 'spec_helper'
|
16
17
|
|
17
18
|
describe Aws::SessionStore::DynamoDB::RackMiddleware do
|
@@ -20,17 +21,17 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
|
|
20
21
|
def thread(mul_val, time, check)
|
21
22
|
Thread.new do
|
22
23
|
sleep(time)
|
23
|
-
get
|
24
|
-
last_request.session[:multiplier].
|
24
|
+
get '/'
|
25
|
+
expect(last_request.session[:multiplier]).to eq(mul_val) if check
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
def thread_exception(error)
|
29
|
-
Thread.new { expect { get
|
30
|
+
Thread.new { expect { get '/' }.to raise_error(error) }
|
30
31
|
end
|
31
32
|
|
32
33
|
def update_item_mock(options, update_method)
|
33
|
-
if options[:return_values] ==
|
34
|
+
if options[:return_values] == 'UPDATED_NEW' && options.key?(:expected)
|
34
35
|
sleep(0.50)
|
35
36
|
update_method.call(options)
|
36
37
|
else
|
@@ -41,23 +42,23 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
|
|
41
42
|
let(:base_app) { MultiplierApplication.new }
|
42
43
|
let(:app) { Aws::SessionStore::DynamoDB::RackMiddleware.new(base_app, @options) }
|
43
44
|
|
44
|
-
context
|
45
|
+
context 'Mock Multiple Threaded Sessions', integration: true do
|
45
46
|
before do
|
46
47
|
@options = Aws::SessionStore::DynamoDB::Configuration.new.to_hash
|
47
48
|
@options[:enable_locking] = true
|
48
49
|
@options[:secret_key] = 'watermelon_smiles'
|
49
50
|
|
50
51
|
update_method = @options[:dynamo_db_client].method(:update_item)
|
51
|
-
@options[:dynamo_db_client].
|
52
|
+
expect(@options[:dynamo_db_client]).to receive(:update_item).at_least(:once) do |options|
|
52
53
|
update_item_mock(options, update_method)
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
it
|
57
|
+
it 'should wait for lock' do
|
57
58
|
@options[:lock_expiry_time] = 2000
|
58
59
|
|
59
|
-
get
|
60
|
-
last_request.session[:multiplier].
|
60
|
+
get '/'
|
61
|
+
expect(last_request.session[:multiplier]).to eq(1)
|
61
62
|
|
62
63
|
t1 = thread(2, 0, false)
|
63
64
|
t2 = thread(4, 0.25, true)
|
@@ -65,11 +66,11 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
|
|
65
66
|
t2.join
|
66
67
|
end
|
67
68
|
|
68
|
-
it
|
69
|
+
it 'should bust lock' do
|
69
70
|
@options[:lock_expiry_time] = 100
|
70
71
|
|
71
|
-
get
|
72
|
-
last_request.session[:multiplier].
|
72
|
+
get '/'
|
73
|
+
expect(last_request.session[:multiplier]).to eq(1)
|
73
74
|
|
74
75
|
t1 = thread_exception(Aws::DynamoDB::Errors::ConditionalCheckFailedException)
|
75
76
|
t2 = thread(2, 0.25, true)
|
@@ -77,13 +78,13 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
|
|
77
78
|
t2.join
|
78
79
|
end
|
79
80
|
|
80
|
-
it
|
81
|
+
it 'should throw exceeded time spent aquiring lock error' do
|
81
82
|
@options[:lock_expiry_time] = 1000
|
82
83
|
@options[:lock_retry_delay] = 100
|
83
84
|
@options[:lock_max_wait_time] = 0.25
|
84
85
|
|
85
|
-
get
|
86
|
-
last_request.session[:multiplier].
|
86
|
+
get '/'
|
87
|
+
expect(last_request.session[:multiplier]).to eq(1)
|
87
88
|
|
88
89
|
t1 = thread(2, 0, false)
|
89
90
|
sleep(0.25)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
@@ -22,28 +24,28 @@ module Aws
|
|
22
24
|
instance_exec(&ConstantHelpers)
|
23
25
|
|
24
26
|
before do
|
25
|
-
@options = { :
|
27
|
+
@options = { secret_key: 'watermelon_cherries' }
|
26
28
|
end
|
27
29
|
|
28
30
|
# Table options for client
|
29
31
|
def table_opts(sid)
|
30
32
|
{
|
31
|
-
:
|
32
|
-
:
|
33
|
+
table_name: Configuration::DEFAULTS[:table_name],
|
34
|
+
key: { Configuration::DEFAULTS[:table_key] => sid }
|
33
35
|
}
|
34
36
|
end
|
35
37
|
|
36
38
|
# Attributes to be retrieved via client
|
37
39
|
def attr_opts
|
38
40
|
{
|
39
|
-
:
|
40
|
-
:
|
41
|
+
attributes_to_get: %w[data created_at locked_at],
|
42
|
+
consistent_read: true
|
41
43
|
}
|
42
44
|
end
|
43
45
|
|
44
46
|
def extract_time(sid)
|
45
47
|
options = table_opts(sid).merge(attr_opts)
|
46
|
-
Time.at((client.get_item(options)[:item][
|
48
|
+
Time.at((client.get_item(options)[:item]['created_at']).to_f)
|
47
49
|
end
|
48
50
|
|
49
51
|
let(:base_app) { MultiplierApplication.new }
|
@@ -51,76 +53,75 @@ module Aws
|
|
51
53
|
let(:config) { Configuration.new }
|
52
54
|
let(:client) { config.dynamo_db_client }
|
53
55
|
|
54
|
-
context
|
55
|
-
it
|
56
|
-
get
|
57
|
-
last_request.session[:multiplier].
|
56
|
+
context 'Testing best case session storage', integration: true do
|
57
|
+
it 'stores session data in session object' do
|
58
|
+
get '/'
|
59
|
+
expect(last_request.session[:multiplier]).to eq(1)
|
58
60
|
end
|
59
61
|
|
60
|
-
it
|
61
|
-
get
|
62
|
-
last_response.body.
|
63
|
-
last_response['Set-Cookie'].
|
62
|
+
it 'creates a new HTTP cookie when Cookie not supplied' do
|
63
|
+
get '/'
|
64
|
+
expect(last_response.body).to eq('All good!')
|
65
|
+
expect(last_response['Set-Cookie']).to be_truthy
|
64
66
|
end
|
65
67
|
|
66
|
-
it
|
67
|
-
get
|
68
|
-
last_response['Set-Cookie'].
|
69
|
-
|
68
|
+
it 'does not rewrite Cookie if cookie previously/accuarately set' do
|
69
|
+
get '/'
|
70
|
+
expect(last_response['Set-Cookie']).not_to be_nil
|
70
71
|
|
71
|
-
get
|
72
|
-
last_response['Set-Cookie'].
|
72
|
+
get '/'
|
73
|
+
expect(last_response['Set-Cookie']).to be_nil
|
73
74
|
end
|
74
75
|
|
75
|
-
it
|
76
|
+
it 'does not set cookie when defer option is specified' do
|
76
77
|
@options[:defer] = true
|
77
|
-
get
|
78
|
-
last_response['Set-Cookie'].
|
78
|
+
get '/'
|
79
|
+
expect(last_response['Set-Cookie']).to be_nil
|
79
80
|
end
|
80
81
|
|
81
|
-
it
|
82
|
-
get
|
83
|
-
last_response['Set-Cookie'].
|
84
|
-
last_response['Set-Cookie'].
|
82
|
+
it 'creates new session with false/nonexistant http-cookie id' do
|
83
|
+
get '/', {}, invalid_cookie.merge(invalid_session_data)
|
84
|
+
expect(last_response['Set-Cookie']).not_to eq('rack.session=ApplePieBlueberries')
|
85
|
+
expect(last_response['Set-Cookie']).not_to be_nil
|
85
86
|
end
|
86
87
|
|
87
|
-
it
|
88
|
+
it 'expires after specified time and sets date for cookie to expire' do
|
88
89
|
@options[:expire_after] = 1
|
89
|
-
get
|
90
|
+
get '/'
|
90
91
|
session_cookie = last_response['Set-Cookie']
|
91
92
|
sleep(1.2)
|
92
93
|
|
93
|
-
get
|
94
|
-
last_response['Set-Cookie'].
|
95
|
-
last_response['Set-Cookie'].
|
94
|
+
get '/'
|
95
|
+
expect(last_response['Set-Cookie']).not_to be_nil
|
96
|
+
expect(last_response['Set-Cookie']).not_to eq(session_cookie)
|
96
97
|
end
|
97
98
|
|
98
|
-
it
|
99
|
+
it 'will not set a session cookie when defer is true' do
|
99
100
|
@options[:defer] = true
|
100
|
-
get
|
101
|
-
last_response['Set-Cookie'].
|
101
|
+
get '/'
|
102
|
+
expect(last_response['Set-Cookie']).to be_nil
|
102
103
|
end
|
103
104
|
|
104
|
-
it
|
105
|
-
get
|
106
|
-
last_request.env[
|
105
|
+
it 'adds the created at attribute for a new session' do
|
106
|
+
get '/'
|
107
|
+
expect(last_request.env['dynamo_db.new_session']).to eq('true')
|
107
108
|
sid = last_response['Set-Cookie'].split(/[;\=]/)[1]
|
108
109
|
time = extract_time(sid)
|
109
|
-
time.
|
110
|
+
expect(time).to be_within(2).of(Time.now)
|
110
111
|
|
111
|
-
get
|
112
|
-
last_request.env['dynamo_db.new_session'].
|
112
|
+
get '/'
|
113
|
+
expect(last_request.env['dynamo_db.new_session']).to be_nil
|
113
114
|
end
|
114
115
|
|
115
|
-
it
|
116
|
+
it 'releases pessimistic lock at finish of transaction' do
|
116
117
|
@options[:enable_locking] = true
|
117
|
-
get
|
118
|
-
last_request.env[
|
118
|
+
get '/'
|
119
|
+
expect(last_request.env['dynamo_db.new_session']).to eq('true')
|
119
120
|
sid = last_response['Set-Cookie'].split(/[;\=]/)[1]
|
120
121
|
|
121
|
-
get
|
122
|
+
get '/'
|
122
123
|
options = table_opts(sid).merge(attr_opts)
|
123
|
-
client.get_item(options)[:item][
|
124
|
+
expect(client.get_item(options)[:item]['locked_at']).to be_nil
|
124
125
|
end
|
125
126
|
end
|
126
127
|
end
|