kamerling 0.0.2 → 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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -13
- data/Gemfile +0 -1
- data/Gemfile.lock +64 -64
- data/README.md +18 -1
- data/Rakefile +5 -3
- data/bin/kamerling +1 -1
- data/config/reek.yml +20 -3
- data/kamerling.gemspec +16 -13
- data/lib/kamerling.rb +2 -28
- data/lib/kamerling/addr.rb +17 -3
- data/lib/kamerling/client.rb +10 -11
- data/lib/kamerling/core_extensions/main.rb +14 -14
- data/lib/kamerling/dispatch.rb +13 -0
- data/lib/kamerling/handler.rb +16 -25
- data/lib/kamerling/http_api.rb +50 -34
- data/lib/kamerling/logging.rb +36 -16
- data/lib/kamerling/mapper.rb +33 -0
- data/lib/kamerling/message.rb +50 -37
- data/lib/kamerling/migrations/2_results_received_at.rb +7 -0
- data/lib/kamerling/migrations/3_dispatches.rb +17 -0
- data/lib/kamerling/migrations/4_registrations_registered_at.rb +7 -0
- data/lib/kamerling/migrations/5_clients_type.rb +7 -0
- data/lib/kamerling/net_dispatcher.rb +12 -7
- data/lib/kamerling/project.rb +7 -3
- data/lib/kamerling/receiver.rb +38 -10
- data/lib/kamerling/registrar.rb +45 -8
- data/lib/kamerling/registration.rb +9 -10
- data/lib/kamerling/repo.rb +33 -26
- data/lib/kamerling/repos.rb +52 -45
- data/lib/kamerling/result.rb +10 -11
- data/lib/kamerling/server/http.rb +28 -21
- data/lib/kamerling/server/sock.rb +32 -24
- data/lib/kamerling/server/tcp.rb +23 -15
- data/lib/kamerling/server/udp.rb +24 -16
- data/lib/kamerling/server_runner.rb +30 -41
- data/lib/kamerling/settings.rb +28 -0
- data/lib/kamerling/task.rb +7 -7
- data/lib/kamerling/task_dispatcher.rb +31 -22
- data/lib/kamerling/uuid.rb +13 -11
- data/lib/kamerling/uuid_entity.rb +23 -9
- data/lib/kamerling/value.rb +13 -0
- data/lib/kamerling/views/clients.slim +3 -1
- data/lib/kamerling/views/project.slim +8 -4
- data/lib/kamerling/views/projects.slim +7 -1
- data/spec/kamerling/addr_spec.rb +32 -22
- data/spec/kamerling/client_spec.rb +9 -5
- data/spec/kamerling/core_extensions/main_spec.rb +18 -13
- data/spec/kamerling/dispatch_spec.rb +16 -0
- data/spec/kamerling/handler_spec.rb +24 -34
- data/spec/kamerling/http_api_spec.rb +94 -73
- data/spec/kamerling/logging_spec.rb +93 -62
- data/spec/kamerling/mapper_spec.rb +151 -0
- data/spec/kamerling/message_spec.rb +73 -49
- data/spec/kamerling/net_dispatcher_spec.rb +22 -16
- data/spec/kamerling/receiver_spec.rb +29 -19
- data/spec/kamerling/registrar_spec.rb +43 -15
- data/spec/kamerling/registration_spec.rb +17 -0
- data/spec/kamerling/repo_spec.rb +63 -47
- data/spec/kamerling/repos_spec.rb +121 -109
- data/spec/kamerling/result_spec.rb +16 -0
- data/spec/kamerling/server/http_spec.rb +19 -14
- data/spec/kamerling/server/tcp_spec.rb +41 -35
- data/spec/kamerling/server/udp_spec.rb +40 -34
- data/spec/kamerling/server_runner_spec.rb +62 -53
- data/spec/kamerling/settings_spec.rb +36 -0
- data/spec/kamerling/task_dispatcher_spec.rb +38 -15
- data/spec/kamerling/task_spec.rb +9 -5
- data/spec/kamerling/uuid_entity_spec.rb +53 -25
- data/spec/kamerling/uuid_spec.rb +19 -16
- data/spec/kamerling/value_spec.rb +21 -0
- data/spec/spec_helper.rb +3 -6
- metadata +54 -8
- data/lib/kamerling/core_extensions.rb +0 -1
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/kamerling/registration'
|
3
|
+
|
4
|
+
module Kamerling
|
5
|
+
describe Registration do
|
6
|
+
describe '#registered_at' do
|
7
|
+
it 'defaults to the current time' do
|
8
|
+
registered_at = Registration.new.registered_at
|
9
|
+
assert registered_at.between?(Time.now - 1, Time.now + 1)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'defaults to the time of Registration’s creation' do
|
13
|
+
Registration.new.registered_at.wont_equal Registration.new.registered_at
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/kamerling/repo_spec.rb
CHANGED
@@ -1,60 +1,76 @@
|
|
1
|
+
require 'sequel'
|
1
2
|
require_relative '../spec_helper'
|
3
|
+
require_relative '../../lib/kamerling/mapper'
|
4
|
+
require_relative '../../lib/kamerling/project'
|
5
|
+
require_relative '../../lib/kamerling/repo'
|
6
|
+
require_relative '../../lib/kamerling/uuid'
|
7
|
+
require_relative '../../lib/kamerling/uuid_entity'
|
2
8
|
|
3
|
-
module Kamerling
|
4
|
-
|
9
|
+
module Kamerling
|
10
|
+
describe Repo do
|
11
|
+
Tune = Class.new(UUIDEntity) { attrs genre: Symbol }
|
5
12
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
describe '#<<' do
|
14
|
+
it 'passes the Hash version of an object to the source via a mapper' do
|
15
|
+
tune = Tune.new(genre: :chap_hop)
|
16
|
+
source = fake(Sequel::Dataset)
|
17
|
+
Repo.new(Tune, source) << tune
|
18
|
+
source.must_have_received :<<, [tune.to_h]
|
19
|
+
end
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
it 'updates the source’s version if it exists there' do
|
22
|
+
dataset = fake(Sequel::Dataset)
|
23
|
+
source = fake(Sequel::Dataset)
|
24
|
+
tune = Tune.new(genre: :chap_hop)
|
25
|
+
stub(source).<<(tune.to_h) { fail Sequel::UniqueConstraintViolation }
|
26
|
+
stub(source).where(uuid: tune.uuid) { dataset }
|
27
|
+
Repo.new(Tune, source) << tune
|
28
|
+
dataset.must_have_received :update, [tune.to_h]
|
29
|
+
end
|
22
30
|
end
|
23
|
-
end
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
describe '#[]' do
|
33
|
+
it 'hydrates the object found in the repo via a mapper' do
|
34
|
+
tune = Tune.new(genre: :chap_hop)
|
35
|
+
hash = { genre: :chap_hop, uuid: tune.uuid }
|
36
|
+
source = { { uuid: tune.uuid } => hash }
|
37
|
+
mapper = fake(:mapper, as: :class)
|
38
|
+
stub(mapper).from_h(Tune, hash) { tune }
|
39
|
+
retrieved = Repo.new(Tune, source, mapper: mapper)[tune.uuid]
|
40
|
+
retrieved.to_h.must_equal tune.to_h
|
41
|
+
end
|
32
42
|
|
33
|
-
|
34
|
-
|
43
|
+
it 'raises NotFound if the object is not found in the repo' do
|
44
|
+
-> { Repo.new(Tune, {})[UUID.new] }.must_raise Repo::NotFound
|
45
|
+
end
|
35
46
|
end
|
36
|
-
end
|
37
47
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
describe '#all' do
|
49
|
+
it 'returns all objects via a mapper' do
|
50
|
+
tune = Tune.new(genre: :chap_hop)
|
51
|
+
source = fake(Sequel::Dataset, all: [genre: :chap_hop, uuid: tune.uuid])
|
52
|
+
mapper = fake(:mapper, as: :class, from_h: tune)
|
53
|
+
Repo.new(Tune, source, mapper: mapper).all.must_equal [tune]
|
54
|
+
end
|
44
55
|
end
|
45
|
-
end
|
46
56
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
describe '#related_to' do
|
58
|
+
it 'returns objects related to the given object via a mapper' do
|
59
|
+
ragga = Tune.new(genre: :ragga)
|
60
|
+
reggae = Tune.new(genre: :reggae)
|
61
|
+
project = Project.new
|
62
|
+
results = [
|
63
|
+
{ genre: :ragga, uuid: ragga.uuid },
|
64
|
+
{ genre: :reggae, uuid: reggae.uuid },
|
65
|
+
]
|
66
|
+
source = fake(Sequel::Dataset)
|
67
|
+
stub(source).where(project_uuid: project.uuid) { results }
|
68
|
+
mapper = fake(:mapper, as: :class)
|
69
|
+
stub(mapper).from_h(Tune, genre: :ragga, uuid: ragga.uuid) { ragga }
|
70
|
+
stub(mapper).from_h(Tune, genre: :reggae, uuid: reggae.uuid) { reggae }
|
71
|
+
repo = Repo.new(Tune, source, mapper: mapper)
|
72
|
+
repo.related_to(project).must_equal [ragga, reggae]
|
73
|
+
end
|
58
74
|
end
|
59
75
|
end
|
60
|
-
end
|
76
|
+
end
|
@@ -1,136 +1,148 @@
|
|
1
|
+
require 'sequel'
|
1
2
|
require_relative '../spec_helper'
|
3
|
+
require_relative '../../lib/kamerling/addr'
|
4
|
+
require_relative '../../lib/kamerling/client'
|
5
|
+
require_relative '../../lib/kamerling/project'
|
6
|
+
require_relative '../../lib/kamerling/registration'
|
7
|
+
require_relative '../../lib/kamerling/repo'
|
8
|
+
require_relative '../../lib/kamerling/repos'
|
9
|
+
require_relative '../../lib/kamerling/result'
|
10
|
+
require_relative '../../lib/kamerling/task'
|
11
|
+
require_relative '../../lib/kamerling/uuid'
|
2
12
|
|
3
|
-
module Kamerling
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
13
|
+
module Kamerling
|
14
|
+
describe Repos do
|
15
|
+
describe '.<<' do
|
16
|
+
it 'shuffles the object into the right repo' do
|
17
|
+
Repos.repos = { Object => repo = fake(:repo) }
|
18
|
+
Repos.<< object = Object.new
|
19
|
+
repo.must_have_received :<<, [object]
|
20
|
+
end
|
10
21
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
it 'can be chained' do
|
23
|
+
str_repo, sym_repo = fake(:repo), fake(:repo)
|
24
|
+
Repos.repos = { String => str_repo, Symbol => sym_repo }
|
25
|
+
Repos << 'str' << :sym
|
26
|
+
str_repo.must_have_received :<<, ['str']
|
27
|
+
sym_repo.must_have_received :<<, [:sym]
|
28
|
+
end
|
17
29
|
end
|
18
|
-
end
|
19
30
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
31
|
+
describe '.[]' do
|
32
|
+
it 'allows querying for repository objects' do
|
33
|
+
client = Client.new
|
34
|
+
Repos.repos = { Client => {} }
|
35
|
+
Repos[Client][client.uuid].must_be_nil
|
36
|
+
Repos.repos = { Client => { client.uuid => client } }
|
37
|
+
Repos[Client][client.uuid].must_equal client
|
38
|
+
end
|
27
39
|
end
|
28
|
-
end
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
41
|
+
describe '.clients' do
|
42
|
+
it 'returns all clients' do
|
43
|
+
Repos.repos = { Client => fake(:repo, all: all_clients = fake) }
|
44
|
+
Repos.clients.must_equal all_clients
|
45
|
+
end
|
34
46
|
end
|
35
|
-
end
|
36
47
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
describe '.clients_for' do
|
49
|
+
it 'returns all clients for the given project' do
|
50
|
+
clients = [Client.new, Client.new]
|
51
|
+
project = Project.new
|
52
|
+
regs = clients.map { |client| Registration.new(client: client) }
|
53
|
+
reg_repo = fake(:repo)
|
54
|
+
stub(reg_repo).related_to(project) { regs }
|
55
|
+
Repos.repos = { Registration => reg_repo }
|
56
|
+
Repos.clients_for(project).must_equal clients
|
57
|
+
end
|
46
58
|
end
|
47
|
-
end
|
48
59
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
describe '.db=' do
|
61
|
+
it 'auto-migrates the passed db' do
|
62
|
+
db = Sequel.sqlite
|
63
|
+
warn_off { db.tables.wont_include :schema_info }
|
64
|
+
Repos.db = db
|
65
|
+
warn_off { db.tables.must_include :schema_info }
|
66
|
+
end
|
55
67
|
end
|
56
|
-
end
|
57
68
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
describe '.free_clients_for' do
|
70
|
+
it 'returns free clients for the given project' do
|
71
|
+
busy_client = Client.new(busy: true)
|
72
|
+
free_client = Client.new(busy: false)
|
73
|
+
busy_reg = Registration.new(client: busy_client)
|
74
|
+
free_reg = Registration.new(client: free_client)
|
75
|
+
project = Project.new
|
76
|
+
repo = fake(:repo)
|
77
|
+
stub(repo).related_to(project) { [busy_reg, free_reg] }
|
78
|
+
Repos.repos = { Registration => repo }
|
79
|
+
Repos.free_clients_for(project).must_equal [free_client]
|
80
|
+
end
|
69
81
|
end
|
70
|
-
end
|
71
82
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
83
|
+
describe '.next_task_for' do
|
84
|
+
it 'returns the next task for the given project' do
|
85
|
+
project = Project.new
|
86
|
+
done_task = Task.new(done: true)
|
87
|
+
new_task = Task.new(done: false)
|
88
|
+
repo = fake(:repo)
|
89
|
+
stub(repo).related_to(project) { [done_task, new_task] }
|
90
|
+
Repos.repos = { Task => repo }
|
91
|
+
Repos.next_task_for(project).must_equal new_task
|
92
|
+
end
|
81
93
|
end
|
82
|
-
end
|
83
94
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
95
|
+
describe '.project' do
|
96
|
+
it 'returns the project with the given UUID' do
|
97
|
+
gimps = Project.new
|
98
|
+
Repos.repos = { Project => { gimps.uuid => gimps } }
|
99
|
+
Repos.project(gimps.uuid).must_equal gimps
|
100
|
+
end
|
89
101
|
end
|
90
|
-
end
|
91
102
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
103
|
+
describe '.projects' do
|
104
|
+
it 'returns all projects' do
|
105
|
+
Repos.repos = { Project => fake(:repo, all: all_projects = fake) }
|
106
|
+
Repos.projects.must_equal all_projects
|
107
|
+
end
|
96
108
|
end
|
97
|
-
end
|
98
109
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
110
|
+
describe '.tasks_for' do
|
111
|
+
it 'returns all tasks for the given project' do
|
112
|
+
project = Project.new
|
113
|
+
tasks = [Task.new, Task.new]
|
114
|
+
task_repo = fake(:repo)
|
115
|
+
stub(task_repo).related_to(project) { tasks }
|
116
|
+
Repos.repos = { Task => task_repo }
|
117
|
+
Repos.tasks_for(project).must_equal tasks
|
118
|
+
end
|
107
119
|
end
|
108
|
-
end
|
109
120
|
|
110
|
-
|
111
|
-
|
121
|
+
describe 'when working on actual database' do
|
122
|
+
before { Repos.db = Sequel.sqlite }
|
112
123
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
it 'makes sure objects can be stored and retrieved' do
|
125
|
+
addr = Addr['127.0.0.1', 1981, :TCP]
|
126
|
+
client = Client.new(addr: addr)
|
127
|
+
project = Project.new(name: 'project name', uuid: UUID.new)
|
128
|
+
task = Task.new(data: 'data', project: project, uuid: UUID.new)
|
129
|
+
reg = Registration.new(addr: addr, client: client, project: project)
|
130
|
+
res = Result.new(addr: addr, client: client, data: 'da', task: task)
|
131
|
+
Repos << client << project << task << reg << res
|
132
|
+
Repos[Client][client.uuid].must_equal client
|
133
|
+
Repos[Project][project.uuid].must_equal project
|
134
|
+
Repos[Registration][reg.uuid].must_equal reg
|
135
|
+
Repos[Result][res.uuid].must_equal res
|
136
|
+
Repos[Task][task.uuid].must_equal task
|
137
|
+
end
|
127
138
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
139
|
+
it 'makes sure objects can be updated' do
|
140
|
+
client = Client.new(addr: Addr['127.0.0.1', 1979, :TCP])
|
141
|
+
Repos << client
|
142
|
+
client.busy = true
|
143
|
+
Repos << client
|
144
|
+
assert Repos[Client][client.uuid].busy
|
145
|
+
end
|
134
146
|
end
|
135
147
|
end
|
136
|
-
end
|
148
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/kamerling/result'
|
3
|
+
|
4
|
+
module Kamerling
|
5
|
+
describe Result do
|
6
|
+
describe '#received_at' do
|
7
|
+
it 'defaults to the current time' do
|
8
|
+
assert Result.new.received_at.between?(Time.now - 1, Time.now + 1)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'defaults to the time of Result’s creation' do
|
12
|
+
Result.new.received_at.wont_equal Result.new.received_at
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,22 +1,27 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
1
3
|
require_relative '../../spec_helper'
|
4
|
+
require_relative '../../../lib/kamerling/server/http'
|
2
5
|
|
3
|
-
module Kamerling
|
4
|
-
|
6
|
+
module Kamerling
|
7
|
+
describe Server::HTTP do
|
8
|
+
let(:addr) { Addr['localhost', 2009, :TCP] }
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
describe '#addr' do
|
11
|
+
it 'returns the server’s host + port as a TCP addr' do
|
12
|
+
Server::HTTP.new(addr: addr).addr.must_equal addr
|
13
|
+
end
|
9
14
|
end
|
10
|
-
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
describe '#start, #stop' do
|
17
|
+
it 'starts/stops a HTTP server on the given host and port' do
|
18
|
+
capture_io do
|
19
|
+
server = Server::HTTP.new(addr: addr).start
|
20
|
+
uri = URI.parse('http://localhost:2009')
|
21
|
+
Net::HTTP.get_response(uri).must_be_kind_of Net::HTTPSuccess
|
22
|
+
server.stop
|
23
|
+
end
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
22
|
-
end
|
27
|
+
end
|