ruby_nos 0.0.1
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.
- checksums.yaml +15 -0
- data/.gitignore +8 -0
- data/.travis.yml +10 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +61 -0
- data/LICENSE +21 -0
- data/README.md +64 -0
- data/Rakefile +19 -0
- data/config/environment.rb +17 -0
- data/lib/initializable.rb +14 -0
- data/lib/ruby_nos.rb +64 -0
- data/lib/ruby_nos/agent.rb +127 -0
- data/lib/ruby_nos/aliasing.rb +15 -0
- data/lib/ruby_nos/cloud.rb +80 -0
- data/lib/ruby_nos/endpoint.rb +43 -0
- data/lib/ruby_nos/formatter.rb +25 -0
- data/lib/ruby_nos/list.rb +34 -0
- data/lib/ruby_nos/message.rb +47 -0
- data/lib/ruby_nos/processor.rb +133 -0
- data/lib/ruby_nos/remote_agent.rb +41 -0
- data/lib/ruby_nos/rest_api.rb +23 -0
- data/lib/ruby_nos/signature_generator.rb +22 -0
- data/lib/ruby_nos/udp_receptor.rb +47 -0
- data/lib/ruby_nos/udp_sender.rb +26 -0
- data/lib/ruby_nos/version.rb +3 -0
- data/ruby_nos.gemspec +22 -0
- data/spec/ruby_nos.spec.rb +7 -0
- data/spec/ruby_nos/agent_spec.rb +120 -0
- data/spec/ruby_nos/cloud_spec.rb +107 -0
- data/spec/ruby_nos/endpoint_spec.rb +38 -0
- data/spec/ruby_nos/formatter_spec.rb +34 -0
- data/spec/ruby_nos/list_spec.rb +54 -0
- data/spec/ruby_nos/message_spec.rb +47 -0
- data/spec/ruby_nos/processor_spec.rb +104 -0
- data/spec/ruby_nos/remote_agent_spec.rb +57 -0
- data/spec/ruby_nos/rest_api_spec.rb +23 -0
- data/spec/ruby_nos/signature_generator_spec.rb +28 -0
- data/spec/ruby_nos/udp_receptor_spec.rb +31 -0
- data/spec/ruby_nos/udp_sender_spec.rb +35 -0
- data/spec/spec_helper.rb +28 -0
- metadata +129 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "digest"
|
|
2
|
+
|
|
3
|
+
module RubyNos
|
|
4
|
+
class SignatureGenerator
|
|
5
|
+
|
|
6
|
+
attr_accessor :key
|
|
7
|
+
|
|
8
|
+
def key
|
|
9
|
+
@key ||= RubyNos.signature_key
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def generate_signature data
|
|
13
|
+
digest = OpenSSL::Digest.new('sha1')
|
|
14
|
+
OpenSSL::HMAC.hexdigest(digest, key, data)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def valid_signature? data, signature
|
|
18
|
+
generated_signature = generate_signature(data)
|
|
19
|
+
signature == generated_signature
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'ipaddr'
|
|
3
|
+
|
|
4
|
+
module RubyNos
|
|
5
|
+
class UDPReceptor
|
|
6
|
+
attr_accessor :port
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
configure
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def port
|
|
13
|
+
@port ||= RubyNos.port
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def multicast_address
|
|
17
|
+
@multicast_address ||= RubyNos.group_address
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def socket
|
|
21
|
+
@socket ||= UDPSocket.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def listen processor
|
|
25
|
+
Thread.new do
|
|
26
|
+
loop do
|
|
27
|
+
message = @socket.recvfrom(512).first
|
|
28
|
+
processor.process_message(message)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def configure
|
|
36
|
+
RubyNos.logger.send(:info, "Binding socket to #{bind_addr} IP")
|
|
37
|
+
membership = IPAddr.new(multicast_address).hton + IPAddr.new(bind_addr).hton
|
|
38
|
+
socket.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, membership)
|
|
39
|
+
socket.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
|
|
40
|
+
socket.bind(bind_addr, port)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def bind_addr
|
|
44
|
+
"0.0.0.0"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
module RubyNos
|
|
5
|
+
class UDPSender
|
|
6
|
+
include Initializable
|
|
7
|
+
|
|
8
|
+
def send args={}
|
|
9
|
+
socket = UDPSocket.open
|
|
10
|
+
socket.setsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL, 1)
|
|
11
|
+
RubyNos.logger.send(:info, "Message sent: #{args[:message]}")
|
|
12
|
+
socket.send(args[:message].to_json, 0, args[:host] || multicast_address, args[:port] || port)
|
|
13
|
+
socket.close
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def multicast_address
|
|
19
|
+
@multicast_address ||= RubyNos.group_address
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def port
|
|
23
|
+
@port ||= RubyNos.port
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/ruby_nos.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
gem_name = "ruby_nos"
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require "#{gem_name}/version"
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = gem_name
|
|
9
|
+
spec.version = RubyNos::VERSION
|
|
10
|
+
spec.authors = ["Workshare's dev team"]
|
|
11
|
+
spec.email = ['_Development@workshare.com']
|
|
12
|
+
spec.description = "A gem to provide microservices autodiscovery to Ruby microservices."
|
|
13
|
+
spec.summary = "A gem to provide microservices autodiscovery to Ruby microservices. This gem allows a microservice to publish its existence on a cloud, store other microservices information and public its API."
|
|
14
|
+
spec.homepage = "https://github.com/worshare/#{spec.name.gsub('_','-')}"
|
|
15
|
+
spec.license = "Copyright"
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
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
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
|
21
|
+
spec.add_development_dependency "rake", "~> 10.4"
|
|
22
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "RubyNos::Agent" do
|
|
4
|
+
subject{Agent.new(udp_tx: udp_sender, udp_rx: udp_receptor, cloud: cloud, processor: processor, rest_api: rest_api)}
|
|
5
|
+
let(:udp_receptor) {double("UDPReceptor", listen: nil)}
|
|
6
|
+
let(:udp_sender) {double("UDPSender", send: nil)}
|
|
7
|
+
let(:cloud) {double("cloud", uuid: "abcd", list: list)}
|
|
8
|
+
let(:list) {double("list", list_of_keys: [])}
|
|
9
|
+
let(:processor) {double("processor")}
|
|
10
|
+
let(:rest_api) {double("rest_api", endpoints: [], to_hash: {})}
|
|
11
|
+
|
|
12
|
+
describe "mantain cloud" do
|
|
13
|
+
context "without agents on the cloud" do
|
|
14
|
+
it "ask for other agents" do
|
|
15
|
+
expect(udp_sender).to receive(:send).twice
|
|
16
|
+
thread = subject.maintain_cloud
|
|
17
|
+
sleep 0.1
|
|
18
|
+
thread.kill
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "with some agent on the cloud" do
|
|
23
|
+
let(:list) {double("list", list_of_keys: [agent.uuid])}
|
|
24
|
+
let(:agent) {double("agent", uuid: "12345", timestamp: Time.now)}
|
|
25
|
+
|
|
26
|
+
before(:each) do
|
|
27
|
+
allow(list).to receive(:info_for).with(agent.uuid).and_return(agent)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "it exists a previous message of the agent" do
|
|
31
|
+
it "sends_a_ping_message to the agent" do
|
|
32
|
+
expect(udp_sender).to receive(:send).exactly(3).times
|
|
33
|
+
allow(subject).to receive(:last_message_exists?).and_return(true)
|
|
34
|
+
thread = subject.maintain_cloud
|
|
35
|
+
sleep 0.1
|
|
36
|
+
thread.kill
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "it does not exists a previous message of the agent" do
|
|
41
|
+
it "eliminates the agent from the list" do
|
|
42
|
+
expect(udp_sender).to receive(:send).twice
|
|
43
|
+
allow(subject).to receive(:last_message_exists?).and_return(false)
|
|
44
|
+
expect(list).to receive(:eliminate).with(agent.uuid)
|
|
45
|
+
thread = subject.maintain_cloud
|
|
46
|
+
sleep 0.1
|
|
47
|
+
thread.kill
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#join_cloud" do
|
|
54
|
+
let(:receptor_info) {{present: 1, endpoints: []}}
|
|
55
|
+
|
|
56
|
+
before(:each) do
|
|
57
|
+
allow(subject).to receive(:receptor_info).and_return(receptor_info)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "sends only a presence message if the agent does not have an API with endpoints" do
|
|
61
|
+
expect(udp_sender).to receive(:send).once
|
|
62
|
+
subject.join_cloud
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "sends a presence and a qne if the agent has an API with endpoints" do
|
|
66
|
+
allow(rest_api).to receive(:endpoints).and_return(["one_endpoint"])
|
|
67
|
+
expect(udp_sender).to receive(:send).twice
|
|
68
|
+
subject.join_cloud
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "#send_desconnection_message" do
|
|
73
|
+
it "sends a message with presence 0" do
|
|
74
|
+
expect(udp_sender).to receive(:send).once
|
|
75
|
+
subject.send_desconnection_message
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
describe "#listen" do
|
|
81
|
+
it "starts the udp receptor" do
|
|
82
|
+
expect(udp_receptor).to receive(:listen)
|
|
83
|
+
subject.listen
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
describe "#send_message" do
|
|
89
|
+
let(:message){double("Message", :serialize => "SerializedMessage")}
|
|
90
|
+
let(:rest_api) {RestApi.new}
|
|
91
|
+
let(:receptor_info) {{present: 1, endpoints: []}}
|
|
92
|
+
let(:well_formed_presence_message){Message.new({from: "AGT:#{subject.uuid.gsub("-", "")}", to: "CLD:#{subject.cloud.uuid.gsub("-", "")}", type: "PRS", timestamp: "sometime", data: receptor_info}).serialize}
|
|
93
|
+
let(:well_formed_qne_message){Message.new({from: "AGT:#{subject.uuid.gsub("-", "")}", to: "CLD:#{subject.cloud.uuid.gsub("-", "")}", type: "QNE", timestamp: "sometime", data: rest_api.to_hash}).serialize}
|
|
94
|
+
let(:host) {"0.0.0.0"}
|
|
95
|
+
let(:port) {"3784"}
|
|
96
|
+
|
|
97
|
+
before(:each) do
|
|
98
|
+
subject.cloud = cloud
|
|
99
|
+
subject.rest_api = rest_api
|
|
100
|
+
allow_any_instance_of(Message).to receive(:generate_miliseconds_timestamp).and_return("sometime")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "sends a message using the UDP Socket" do
|
|
104
|
+
expect(Message).to receive(:new).with({:from => "AGT:#{subject.uuid.gsub("-", "")}", :to => "CLD:#{cloud.uuid.gsub("-", "")}", :type => "DSC"}).and_return(message)
|
|
105
|
+
expect(udp_sender).to receive(:send).with({host: host, port: port, :message => "SerializedMessage"})
|
|
106
|
+
subject.send_message({:type => "DSC", :port => port, :host => host})
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "add the UDP socket info if it is a presence message" do
|
|
110
|
+
expect(subject).to receive(:receptor_info).and_return(receptor_info)
|
|
111
|
+
expect(udp_sender).to receive(:send).with({host: host, port: port, :message => well_formed_presence_message})
|
|
112
|
+
subject.send_message({:type => "PRS", :port => port, :host => host})
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "add the RestAPI info if it is a QNE message" do
|
|
116
|
+
expect(udp_sender).to receive(:send).with({host: host, port: port, :message => well_formed_qne_message})
|
|
117
|
+
subject.send_message({:type => "QNE", :port => port, :host => host})
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "#RubyNos::Cloud" do
|
|
4
|
+
subject{Cloud.new(uuid:cloud_uuid)}
|
|
5
|
+
let(:cloud_uuid) {"122445"}
|
|
6
|
+
let(:agent_uuid) {"12345"}
|
|
7
|
+
let(:list) {double("list")}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
subject.list = list
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "#update" do
|
|
15
|
+
|
|
16
|
+
describe "new agent" do
|
|
17
|
+
before do
|
|
18
|
+
allow(list).to receive(:is_on_the_list?).with(agent_uuid).and_return(false)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "receiving a Hash" do
|
|
22
|
+
let(:agent_info) {{agent_uuid: agent_uuid, info: info}}
|
|
23
|
+
let(:info) {{:endpoints => ["UDP,something,something"]}}
|
|
24
|
+
|
|
25
|
+
it "builds a RemoteAgent and stores it on the list" do
|
|
26
|
+
expect(list).to receive(:add).with(an_instance_of(RemoteAgent))
|
|
27
|
+
subject.update(agent_info)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "receiving a RemoteAgent" do
|
|
32
|
+
let(:agent) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 1, endpoints: [], rest_api: nil)}
|
|
33
|
+
|
|
34
|
+
it "stores agents information if it is new" do
|
|
35
|
+
expect(list).to receive(:add).with(agent)
|
|
36
|
+
subject.update(agent)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "old agent" do
|
|
43
|
+
let(:agent) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 1, endpoints: [], rest_api: nil)}
|
|
44
|
+
|
|
45
|
+
before(:each) do
|
|
46
|
+
allow(list).to receive(:is_on_the_list?).with(agent_uuid).and_return(true)
|
|
47
|
+
allow(list).to receive(:info_for).with(agent_uuid).and_return(agent)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "agent updated with correct information" do
|
|
51
|
+
let(:agent_updated) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 2, endpoints: ["something"], rest_api: nil)}
|
|
52
|
+
|
|
53
|
+
it "if the agent exists and the information is not the same it updates to this new information" do
|
|
54
|
+
expect(subject).to receive(:correct_timestamp?).and_return(true)
|
|
55
|
+
expect(agent).to receive(:same_endpoints?).with(agent_updated).and_return(false)
|
|
56
|
+
expect(list).to receive(:update).with(agent_uuid, agent_updated)
|
|
57
|
+
subject.update(agent_updated)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "agent updating with the same information" do
|
|
62
|
+
let(:agent) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 1, endpoints: ["something"], rest_api: nil)}
|
|
63
|
+
let(:agent_updated) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 2, endpoints: ["something"], rest_api: nil)}
|
|
64
|
+
|
|
65
|
+
it "if the agent exists and the information is not the same it updates to this new information" do
|
|
66
|
+
expect(subject).to receive(:correct_timestamp?).and_return(true)
|
|
67
|
+
expect(agent).to receive(:same_endpoints?).with(agent_updated).and_return(true)
|
|
68
|
+
expect(agent).to receive(:same_api?).with(agent_updated).and_return(true)
|
|
69
|
+
expect(agent).to receive(:same_timestamp?).with(agent_updated).and_return(true)
|
|
70
|
+
expect(list).to_not receive(:update).with(agent_uuid, agent_updated)
|
|
71
|
+
subject.update(agent_updated)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
context "agent updated with nil information" do
|
|
77
|
+
context "nil endpoints" do
|
|
78
|
+
let(:agent) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 1, endpoints: ["something"], rest_api: nil)}
|
|
79
|
+
let(:agent_updated) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 2, endpoints: [], rest_api: nil)}
|
|
80
|
+
|
|
81
|
+
it "only overwrite the entry with the new information" do
|
|
82
|
+
expect(subject).to receive(:correct_timestamp?).and_return(true)
|
|
83
|
+
expect(agent).to receive(:same_endpoints?).with(agent_updated).and_return(false)
|
|
84
|
+
expect(agent_updated).to receive(:endpoints=).with(agent.endpoints)
|
|
85
|
+
expect(list).to receive(:update).with(agent_uuid, agent_updated)
|
|
86
|
+
subject.update(agent_updated)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context "nil api" do
|
|
91
|
+
let(:agent) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 1, endpoints: ["something"], rest_api: double("rest_api"))}
|
|
92
|
+
let(:agent_updated) {instance_double(RemoteAgent, uuid: agent_uuid, timestamp: 2, endpoints: ["something"], rest_api: nil)}
|
|
93
|
+
|
|
94
|
+
it "only overwrite the entry with the new information" do
|
|
95
|
+
expect(subject).to receive(:correct_timestamp?).and_return(true)
|
|
96
|
+
expect(agent).to receive(:same_endpoints?).with(agent_updated).and_return(true)
|
|
97
|
+
expect(agent).to receive(:same_api?).and_return(false)
|
|
98
|
+
expect(agent_updated).to receive(:rest_api=).with(agent.rest_api)
|
|
99
|
+
expect(list).to receive(:update).with(agent_uuid, agent_updated)
|
|
100
|
+
subject.update(agent_updated)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "#RubyNos::Endpoint" do
|
|
4
|
+
subject{Endpoint.new}
|
|
5
|
+
|
|
6
|
+
describe "type=" do
|
|
7
|
+
it "can does not allow types that are not on the allowed types list" do
|
|
8
|
+
expect{subject.type = "SOMETHING"}.to raise_error(ArgumentError)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "allows to set a type that is on the list" do
|
|
12
|
+
subject.type = "PUBLIC"
|
|
13
|
+
expect(subject.type).to eq("PUBLIC")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#to_hash" do
|
|
18
|
+
it "returns the attributes of the endpoint in a hash" do
|
|
19
|
+
subject.path = "/example_path"
|
|
20
|
+
expect(subject.to_hash.keys).to eq([:pa, :po, :st, :ty, :xp, :ho])
|
|
21
|
+
expect(subject.to_hash[:pa]).to eq("/example_path")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "#aliasing" do
|
|
26
|
+
let(:endpoint_hash) {{pa: "/api/", po: 1234, st: 0, ty: "PUB", xp: 0, ho: "localhost"}}
|
|
27
|
+
|
|
28
|
+
it "allows to instantiate an endpoint object attributes with the correct values" do
|
|
29
|
+
endpoint = Endpoint.new(endpoint_hash)
|
|
30
|
+
expect(endpoint.port).to eq 1234
|
|
31
|
+
expect(endpoint.path).to eq "/api/"
|
|
32
|
+
expect(endpoint.sticky).to eq 0
|
|
33
|
+
expect(endpoint.type).to eq "PUB"
|
|
34
|
+
expect(endpoint.priority).to eq 0
|
|
35
|
+
expect(endpoint.host).to eq "localhost"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "#RubyNos::Formatter" do
|
|
4
|
+
subject{Formatter.new}
|
|
5
|
+
let(:uuid) {SecureRandom.uuid}
|
|
6
|
+
|
|
7
|
+
describe "convert_to_uuid" do
|
|
8
|
+
let(:string_uuid){uuid.gsub("-", "")}
|
|
9
|
+
it "converts an string into uuid format" do
|
|
10
|
+
expect(subject.convert_to_uuid(string_uuid)).to eq uuid
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "#uuid_format?" do
|
|
15
|
+
it "returns true if the parameter match the uuid format" do
|
|
16
|
+
expect(subject.uuid_format?(uuid)).to eq(true)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#uuid_to_string" do
|
|
21
|
+
it "converts an uuid to string" do
|
|
22
|
+
result = subject.uuid_to_string(uuid)
|
|
23
|
+
expect(result.include?("-")).to eq(false)
|
|
24
|
+
expect(uuid.split("").count - result.split("").count).to eq 4
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#parse_message" do
|
|
29
|
+
let(:message) {{:a => "something"}}
|
|
30
|
+
it "returns the message as a hash format if it was a hash " do
|
|
31
|
+
expect(subject.parse_message(message.to_json)).to eq(message)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe RubyNos::List do
|
|
4
|
+
subject{List.new}
|
|
5
|
+
let(:element) {double("element", uuid: "12345")}
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
subject.add(element)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "#add" do
|
|
12
|
+
it "adds an element to the list" do
|
|
13
|
+
expect(subject.list.count).to eq(1)
|
|
14
|
+
expect(subject.list.first).to eq({element.uuid => element})
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#update" do
|
|
19
|
+
let(:element_two) {double("another_element", uuid: "12345", some_other_thing: "something")}
|
|
20
|
+
|
|
21
|
+
it "updates an element on the list that has the same uuid" do
|
|
22
|
+
subject.update(element.uuid, element_two)
|
|
23
|
+
expect(subject.list.count).to eq 1
|
|
24
|
+
expect(subject.list.first[element_two.uuid].some_other_thing).to eq "something"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#eliminate" do
|
|
29
|
+
it "eliminates an element from the list" do
|
|
30
|
+
subject.eliminate(element.uuid)
|
|
31
|
+
expect(subject.list.count).to eq 0
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "#info_for" do
|
|
36
|
+
it "returns the information on the list for an element" do
|
|
37
|
+
info = subject.info_for(element.uuid)
|
|
38
|
+
expect(info.uuid).to eq("12345")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#list_of_keys" do
|
|
43
|
+
it "returns the list of keys in the list" do
|
|
44
|
+
expect(subject.list_of_keys).to eq(["12345"])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#is_on_the_list?" do
|
|
49
|
+
it "returns true if the element exists and folder if it does not exist" do
|
|
50
|
+
expect(subject.is_on_the_list?(element.uuid)).to eq(true)
|
|
51
|
+
expect(subject.is_on_the_list?("some_uuid")).to eq(false)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|