mock_etcd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 015357f4c0aa1fe5d9d9ecd43c306141cb0ef216
4
+ data.tar.gz: e9bc9f511f06c27a34722b8c479ddcf597dce730
5
+ SHA512:
6
+ metadata.gz: 921bb6d7dbcb9c29cfce9dcb2bafe47976538ddb4c93b56e050beae047338a499871ad46c8d986fd2f3f5d2e5398c7bf47e91af5e1ca5baa46b9cf1dae6f3f00
7
+ data.tar.gz: efbbe728e6ae110561b2fc09bcefcde7518b8992248cc8735a615bc6add646d80981833dd9cefacbbf2b5ca5bcdaa6f9ef68b91ba95cd95e4e4d911919cf1ea8
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mock_etcd.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 kajisha
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ # MockEtcd
2
+
3
+ MockEtcd is mock for [etcd-ruby](https://github.com/ranjib/etcd-ruby)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ group :test do
11
+ gem 'mock_etcd'
12
+ end
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install mock_etcd
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/kajisha/mock_etcd/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,10 @@
1
+ require 'mock_etcd/version'
2
+ require 'mock_etcd/client'
3
+
4
+ module MockEtcd
5
+ def self.client(opts = {})
6
+ MockEtcd::Client.new(opts) do |config|
7
+ yield config if block_given?
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,177 @@
1
+ require 'etcd/client'
2
+ require 'webmock'
3
+ include WebMock::API
4
+
5
+ module MockEtcd
6
+ class Client < Etcd::Client
7
+ attr_reader :nodes
8
+
9
+ def initialize(opts = {})
10
+ @index = 0
11
+ @nodes = {}
12
+
13
+ super
14
+ end
15
+ def api_execute(path, method, options = {})
16
+ stub_request! path, method, options
17
+
18
+ super
19
+ end
20
+
21
+ private
22
+
23
+ def stub_request!(path, method, options)
24
+ key = path.split(key_endpoint).last
25
+
26
+ case method
27
+ when :get
28
+ stub_get_request key, path, options
29
+ when :post
30
+ stub_post_request key, path, options
31
+ when :put
32
+ stub_put_request key, path, options
33
+ when :delete
34
+ stub_delete_request key, path, options
35
+ end
36
+ end
37
+
38
+ def stub_get_request(key, path, options)
39
+ node = find_node(key)
40
+ stub_key_not_found(:get, key, path) and return unless node
41
+
42
+ stub_request(:get, uri(path))
43
+ .to_return(status: 200, body: response_body('get', key, node), headers: response_header(node))
44
+ end
45
+
46
+ def stub_post_request(key, path, options)
47
+ node = create_node_with_index(key, options[:params][:value])
48
+
49
+ stub_request(:post, uri(path))
50
+ .with(body: 'value=' + URI.encode_www_form([options[:params][:value]]), headers: request_header)
51
+ .to_return(status: 201, body: response_body('create', key, node), headers: response_header(node))
52
+ end
53
+
54
+ def stub_put_request(key, path, options)
55
+ node = create_node(key, options[:params][:value])
56
+
57
+ stub_request(:put, uri(path))
58
+ .with(body: 'value=' + URI.encode_www_form([options[:params][:value]]), headers: request_header)
59
+ .to_return(status: 200, body: response_body('set', key, node), headers: response_header(node))
60
+ end
61
+
62
+ def stub_delete_request(key, path, options)
63
+ node = destroy_node(key)
64
+ stub_key_not_found(:delete, key, path) and return unless node
65
+
66
+ stub_request(:delete, uri(path))
67
+ .with(headers: request_header)
68
+ .to_return(status: 200, body: response_body('delete', key, node), headers: response_header(node))
69
+ end
70
+
71
+ def stub_key_not_found(method, key, path)
72
+ stub_request(method, uri(path))
73
+ .to_return(status: 404, headers: {'X-Etcd-Index' => @index}, body: response_key_not_found(key))
74
+ end
75
+
76
+ def find_node(key)
77
+ @nodes[key]
78
+ end
79
+
80
+ def create_node(key, value)
81
+ next_index!
82
+
83
+ node = {
84
+ 'key' => key,
85
+ 'value' => value,
86
+ 'modifiedIndex' => @index,
87
+ 'createdIndex' => @index
88
+ }
89
+
90
+ @nodes[key] = node
91
+ end
92
+
93
+ def create_node_with_index(key, value)
94
+ next_index!
95
+
96
+ node = {
97
+ 'key' => "#{key}/#{@index}",
98
+ 'value' => value,
99
+ 'modifiedIndex' => @index,
100
+ 'createdIndex' => @index
101
+ }
102
+
103
+ if @nodes.has_key?(key)
104
+ @nodes[key] << node
105
+ else
106
+ @nodes[key] = [node]
107
+ end
108
+
109
+ node
110
+ end
111
+
112
+ def destroy_node(key)
113
+ if node = find_node(key)
114
+ node['value'] = nil
115
+ end
116
+
117
+ @nodes.delete(key)
118
+ end
119
+
120
+ def next_index!
121
+ @index = @index + 1
122
+ end
123
+
124
+ def uri(path)
125
+ "http://#{host}:#{port}#{path}"
126
+ end
127
+
128
+ def request_header
129
+ {
130
+ 'Accept' => '*/*',
131
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
132
+ 'User-Agent' => 'Ruby'
133
+ }
134
+ end
135
+
136
+ def response_body(action, key, node)
137
+ if node.is_a?(Array)
138
+ {
139
+ 'action' => action,
140
+ 'node' => {
141
+ 'key' => key,
142
+ 'dir' => true,
143
+ 'nodes' => node
144
+ },
145
+ 'modifiedIndex' => node.first['modifiedIndex'],
146
+ 'createdIndex' => node.first['createdIndex']
147
+ }.to_json
148
+ else
149
+ {
150
+ 'action' => action,
151
+ 'node' => node
152
+ }.to_json
153
+ end
154
+ end
155
+
156
+ def response_key_not_found(key)
157
+ {
158
+ 'errorCode' => 100,
159
+ 'message' => 'Key not found',
160
+ 'cause' => key,
161
+ 'index' => @index
162
+ }.to_json
163
+ end
164
+
165
+ # FIXME Raft index and Raft term.
166
+ def response_header(node)
167
+ node = node.is_a?(Array) ? node.last : node
168
+
169
+ {
170
+ 'Content-Type' => 'application/json',
171
+ 'X-Etcd-Index' => node['createdIndex'],
172
+ 'X-Raft-Index' => 300000 * rand,
173
+ 'X-Raft-Term' => 4
174
+ }
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,3 @@
1
+ module MockEtcd
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mock_etcd/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'mock_etcd'
8
+ spec.version = MockEtcd::VERSION
9
+ spec.authors = ['kajisha']
10
+ spec.email = ['kajisha@gmail.com']
11
+ spec.summary = %q{mock etcd-ruby}
12
+ spec.description = %q{mock etcd-ruby}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'etcd'
22
+ spec.add_runtime_dependency 'webmock'
23
+ spec.add_development_dependency 'bundler', '~> 1.7'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'pry'
26
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mock_etcd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kajisha
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: etcd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: webmock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: mock etcd-ruby
84
+ email:
85
+ - kajisha@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/mock_etcd.rb
96
+ - lib/mock_etcd/client.rb
97
+ - lib/mock_etcd/version.rb
98
+ - mock_etcd.gemspec
99
+ homepage: ''
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.2.2
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: mock etcd-ruby
123
+ test_files: []