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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -13
  3. data/Gemfile +0 -1
  4. data/Gemfile.lock +64 -64
  5. data/README.md +18 -1
  6. data/Rakefile +5 -3
  7. data/bin/kamerling +1 -1
  8. data/config/reek.yml +20 -3
  9. data/kamerling.gemspec +16 -13
  10. data/lib/kamerling.rb +2 -28
  11. data/lib/kamerling/addr.rb +17 -3
  12. data/lib/kamerling/client.rb +10 -11
  13. data/lib/kamerling/core_extensions/main.rb +14 -14
  14. data/lib/kamerling/dispatch.rb +13 -0
  15. data/lib/kamerling/handler.rb +16 -25
  16. data/lib/kamerling/http_api.rb +50 -34
  17. data/lib/kamerling/logging.rb +36 -16
  18. data/lib/kamerling/mapper.rb +33 -0
  19. data/lib/kamerling/message.rb +50 -37
  20. data/lib/kamerling/migrations/2_results_received_at.rb +7 -0
  21. data/lib/kamerling/migrations/3_dispatches.rb +17 -0
  22. data/lib/kamerling/migrations/4_registrations_registered_at.rb +7 -0
  23. data/lib/kamerling/migrations/5_clients_type.rb +7 -0
  24. data/lib/kamerling/net_dispatcher.rb +12 -7
  25. data/lib/kamerling/project.rb +7 -3
  26. data/lib/kamerling/receiver.rb +38 -10
  27. data/lib/kamerling/registrar.rb +45 -8
  28. data/lib/kamerling/registration.rb +9 -10
  29. data/lib/kamerling/repo.rb +33 -26
  30. data/lib/kamerling/repos.rb +52 -45
  31. data/lib/kamerling/result.rb +10 -11
  32. data/lib/kamerling/server/http.rb +28 -21
  33. data/lib/kamerling/server/sock.rb +32 -24
  34. data/lib/kamerling/server/tcp.rb +23 -15
  35. data/lib/kamerling/server/udp.rb +24 -16
  36. data/lib/kamerling/server_runner.rb +30 -41
  37. data/lib/kamerling/settings.rb +28 -0
  38. data/lib/kamerling/task.rb +7 -7
  39. data/lib/kamerling/task_dispatcher.rb +31 -22
  40. data/lib/kamerling/uuid.rb +13 -11
  41. data/lib/kamerling/uuid_entity.rb +23 -9
  42. data/lib/kamerling/value.rb +13 -0
  43. data/lib/kamerling/views/clients.slim +3 -1
  44. data/lib/kamerling/views/project.slim +8 -4
  45. data/lib/kamerling/views/projects.slim +7 -1
  46. data/spec/kamerling/addr_spec.rb +32 -22
  47. data/spec/kamerling/client_spec.rb +9 -5
  48. data/spec/kamerling/core_extensions/main_spec.rb +18 -13
  49. data/spec/kamerling/dispatch_spec.rb +16 -0
  50. data/spec/kamerling/handler_spec.rb +24 -34
  51. data/spec/kamerling/http_api_spec.rb +94 -73
  52. data/spec/kamerling/logging_spec.rb +93 -62
  53. data/spec/kamerling/mapper_spec.rb +151 -0
  54. data/spec/kamerling/message_spec.rb +73 -49
  55. data/spec/kamerling/net_dispatcher_spec.rb +22 -16
  56. data/spec/kamerling/receiver_spec.rb +29 -19
  57. data/spec/kamerling/registrar_spec.rb +43 -15
  58. data/spec/kamerling/registration_spec.rb +17 -0
  59. data/spec/kamerling/repo_spec.rb +63 -47
  60. data/spec/kamerling/repos_spec.rb +121 -109
  61. data/spec/kamerling/result_spec.rb +16 -0
  62. data/spec/kamerling/server/http_spec.rb +19 -14
  63. data/spec/kamerling/server/tcp_spec.rb +41 -35
  64. data/spec/kamerling/server/udp_spec.rb +40 -34
  65. data/spec/kamerling/server_runner_spec.rb +62 -53
  66. data/spec/kamerling/settings_spec.rb +36 -0
  67. data/spec/kamerling/task_dispatcher_spec.rb +38 -15
  68. data/spec/kamerling/task_spec.rb +9 -5
  69. data/spec/kamerling/uuid_entity_spec.rb +53 -25
  70. data/spec/kamerling/uuid_spec.rb +19 -16
  71. data/spec/kamerling/value_spec.rb +21 -0
  72. data/spec/spec_helper.rb +3 -6
  73. metadata +54 -8
  74. data/lib/kamerling/core_extensions.rb +0 -1
@@ -1,9 +1,13 @@
1
1
  require_relative '../spec_helper'
2
+ require_relative '../../lib/kamerling/addr'
3
+ require_relative '../../lib/kamerling/client'
2
4
 
3
- module Kamerling describe Client do
4
- describe '#busy' do
5
- it 'defaults to false' do
6
- Client.new(addr: fake(:addr)).busy.must_equal false
5
+ module Kamerling
6
+ describe Client do
7
+ describe '#busy' do
8
+ it 'defaults to false' do
9
+ refute Client.new.busy
10
+ end
7
11
  end
8
12
  end
9
- end end
13
+ end
@@ -1,18 +1,23 @@
1
1
  require_relative '../../spec_helper'
2
+ require_relative '../../../lib/kamerling/core_extensions/main'
2
3
 
3
- module Kamerling describe CoreExtensions::Main do
4
- describe '#req' do
5
- it 'raises a RuntimeError that a parameter is required' do
6
- -> { CoreExtensions::Main.req(:foo) }.must_raise(RuntimeError)
7
- .message.must_include 'param foo is required'
8
- end
9
- end
4
+ module Kamerling
5
+ describe CoreExtensions::Main do
6
+ describe '#warn_off' do
7
+ before { @verbose = $VERBOSE }
8
+ after { $VERBOSE = @verbose }
9
+
10
+ it 'when $VERBOSE is on it turns it off inside the block and back on' do
11
+ $VERBOSE = true
12
+ CoreExtensions::Main.warn_off { refute $VERBOSE }
13
+ assert $VERBOSE
14
+ end
10
15
 
11
- describe '#warn_off' do
12
- it 'turns $VERBOSE off inside the block' do
13
- assert $VERBOSE
14
- CoreExtensions::Main.warn_off { refute $VERBOSE }
15
- assert $VERBOSE
16
+ it 'when $VERBOSE is off it keeps it off' do
17
+ $VERBOSE = false
18
+ CoreExtensions::Main.warn_off { refute $VERBOSE }
19
+ refute $VERBOSE
20
+ end
16
21
  end
17
22
  end
18
- end end
23
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/kamerling/dispatch'
3
+
4
+ module Kamerling
5
+ describe Dispatch do
6
+ describe '#dispatched_at' do
7
+ it 'defaults to the current time' do
8
+ assert Dispatch.new.dispatched_at.between?(Time.now - 1, Time.now + 1)
9
+ end
10
+
11
+ it 'defaults to the time of Dispatch’s creation' do
12
+ Dispatch.new.dispatched_at.wont_equal Dispatch.new.dispatched_at
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,41 +1,31 @@
1
1
  require_relative '../spec_helper'
2
+ require_relative '../../lib/kamerling/addr'
3
+ require_relative '../../lib/kamerling/handler'
4
+ require_relative '../../lib/kamerling/message'
5
+ require_relative '../../lib/kamerling/receiver'
6
+ require_relative '../../lib/kamerling/registrar'
7
+ require_relative '../../lib/kamerling/uuid'
2
8
 
3
- module Kamerling describe Handler do
4
- describe '#handle' do
5
- fakes :addr, :receiver, :registrar
6
- let(:handler) { Handler.new receiver: receiver, registrar: registrar }
9
+ module Kamerling
10
+ describe Handler do
11
+ describe '#handle' do
12
+ fake :receiver, as: :class
13
+ fake :registrar, as: :class
7
14
 
8
- it 'handles RGST inputs' do
9
- input = 'RGST' + "\0" * 12 + '16B client UUID16B project UUID'
10
- client_uuid = UUID['16B client UUID']
11
- project_uuid = UUID['16B project UUID']
12
- handler.handle input, addr
13
- args = {
14
- addr: addr,
15
- client_uuid: client_uuid,
16
- project_uuid: project_uuid,
17
- }
18
- registrar.must_have_received :register, [args]
19
- end
15
+ let(:addr) { Addr.new }
16
+ let(:handler) { Handler.new(receiver: receiver, registrar: registrar) }
20
17
 
21
- it 'handles RSLT inputs' do
22
- input = 'RSLT' + "\0" * 12 +
23
- '16B client UUID16B project UUID16B task UUIDdata'
24
- client_uuid = UUID['16B client UUID']
25
- task_uuid = UUID['16B task UUID']
26
- handler.handle input, addr
27
- args = {
28
- addr: addr,
29
- client_uuid: client_uuid,
30
- data: 'data',
31
- task_uuid: task_uuid,
32
- }
33
- receiver.must_have_received :receive, [args]
34
- end
18
+ it 'handles RGST inputs' do
19
+ message = Message.parse('RGST')
20
+ handler.handle message, addr
21
+ registrar.must_have_received :register, [addr: addr, message: message]
22
+ end
35
23
 
36
- it 'raises on unknown inputs' do
37
- ex = -> { handler.handle 'MESS', addr }.must_raise Handler::UnknownInput
38
- ex.message.must_equal 'MESS'
24
+ it 'handles RSLT inputs' do
25
+ message = Message.parse('RSLT')
26
+ handler.handle message, addr
27
+ receiver.must_have_received :receive, [addr: addr, message: message]
28
+ end
39
29
  end
40
30
  end
41
- end end
31
+ end
@@ -1,93 +1,114 @@
1
1
  require 'nokogiri'
2
-
3
2
  require_relative '../spec_helper'
3
+ require_relative '../../lib/kamerling/client'
4
+ require_relative '../../lib/kamerling/http_api'
5
+ require_relative '../../lib/kamerling/project'
6
+ require_relative '../../lib/kamerling/repos'
7
+ require_relative '../../lib/kamerling/task'
8
+ require_relative '../../lib/kamerling/task_dispatcher'
9
+ require_relative '../../lib/kamerling/uuid'
4
10
 
5
- module Kamerling describe HTTPAPI do
6
- let(:app) { HTTPAPI.set repos: repos }
7
- let(:doc) { Nokogiri::HTML last_response.body }
8
- let(:ecc) { fake :project, uuid: UUID.new }
9
- let(:gimps) { fake :project, uuid: UUID.new }
10
- let(:repos) { fake :repos, as: :class, projects: [gimps, ecc] }
11
+ module Kamerling
12
+ describe HTTPAPI do
13
+ let(:app) { HTTPAPI.set(repos: repos, task_dispatcher: task_dispatcher) }
14
+ let(:doc) { Nokogiri::HTML(last_response.body) }
15
+ let(:ecc) { Project.new }
16
+ let(:gimps) { Project.new }
17
+ let(:repos) { fake(:repos, as: :class, projects: [gimps, ecc]) }
18
+ let(:task_dispatcher) { fake(:task_dispatcher) }
11
19
 
12
- describe 'GET /' do
13
- it 'contains links to clients and projects' do
14
- get '/'
15
- doc.at('#clients')['href'].must_equal '/clients'
16
- doc.at('#projects')['href'].must_equal '/projects'
20
+ describe 'GET /' do
21
+ it 'contains links to clients and projects' do
22
+ get '/'
23
+ doc.at('#clients')['href'].must_equal '/clients'
24
+ doc.at('#projects')['href'].must_equal '/projects'
25
+ end
17
26
  end
18
- end
19
27
 
20
- describe 'GET /clients' do
21
- it 'contains links to and UUIDs of clients' do
22
- fpga = fake :client, uuid: UUID.new
23
- stub(repos).clients { [fpga] }
24
- get '/clients'
25
- links = doc.css '#clients a[rel=client]'
26
- links.size.must_equal 1
27
- links.at("[data-uuid='#{fpga.uuid}']")['href']
28
- .must_equal "/clients/#{fpga.uuid}"
28
+ describe 'GET /clients' do
29
+ it 'contains information on clients' do
30
+ addr = Addr['127.0.0.1', 1981, :TCP]
31
+ fpga = Client.new(addr: addr, busy: true, type: :FPGA)
32
+ stub(repos).clients { [fpga] }
33
+ get '/clients'
34
+ links = doc.css('#clients a[data-class=client]')
35
+ links.first['data-addr'].must_equal 'tcp://127.0.0.1:1981'
36
+ links.first['data-busy'].must_equal 'true'
37
+ links.first['data-type'].must_equal 'FPGA'
38
+ links.first['data-uuid'].must_equal fpga.uuid
39
+ links.first['href'].must_equal "/clients/#{fpga.uuid}"
40
+ end
29
41
  end
30
- end
31
42
 
32
- describe 'GET /projects' do
33
- it 'contains links to and UUIDs of projects' do
34
- get '/projects'
35
- links = doc.css '#projects a[rel=project]'
36
- links.size.must_equal 2
37
- links.at("[data-uuid='#{gimps.uuid}']")['href']
38
- .must_equal "/projects/#{gimps.uuid}"
43
+ describe 'GET /projects' do
44
+ it 'contains links to and UUIDs of projects' do
45
+ get '/projects'
46
+ links = doc.css('#projects a[data-class=project]')
47
+ links.size.must_equal 2
48
+ links.at("[data-uuid='#{gimps.uuid}']")['href']
49
+ .must_equal "/projects/#{gimps.uuid}"
50
+ end
39
51
  end
40
- end
41
52
 
42
- describe 'GET /projects/{uuid}' do
43
- let(:cpu) { fake :client, busy: false, uuid: UUID.new }
44
- let(:gpu) { fake :client, busy: true, uuid: UUID.new }
45
- let(:three) { fake :task, done: false, uuid: UUID.new }
46
- let(:seven) { fake :task, done: true, uuid: UUID.new }
53
+ describe 'GET /projects/{uuid}' do
54
+ let(:cpu) { Client.new(busy: false, type: :CPU) }
55
+ let(:gpu) { Client.new(busy: true, type: :GPU) }
56
+ let(:three) { Task.new(done: false) }
57
+ let(:seven) { Task.new(done: true) }
47
58
 
48
- before do
49
- stub(repos).project(gimps.uuid) { gimps }
50
- stub(repos).clients_for(gimps) { [cpu, gpu] }
51
- stub(repos).tasks_for(gimps) { [three, seven] }
52
- end
59
+ before do
60
+ stub(repos).project(gimps.uuid) { gimps }
61
+ stub(repos).clients_for(gimps) { [cpu, gpu] }
62
+ stub(repos).tasks_for(gimps) { [three, seven] }
63
+ end
53
64
 
54
- it 'contains links to and info on the project’s clients' do
55
- get "/projects/#{gimps.uuid}"
56
- links = doc.css '#clients a[rel=client]'
57
- links.size.must_equal 2
58
- links.at("[data-uuid='#{cpu.uuid}']")['href']
59
- .must_equal "/clients/#{cpu.uuid}"
60
- links.at("[data-uuid='#{cpu.uuid}']")['data-busy'].must_equal 'false'
61
- links.at("[data-uuid='#{gpu.uuid}']")['data-busy'].must_equal 'true'
62
- end
65
+ it 'contains links to and info on the project’s clients' do
66
+ get "/projects/#{gimps.uuid}"
67
+ links = doc.css('#clients a[data-class=client]')
68
+ links.size.must_equal 2
69
+ links.at("[data-uuid='#{cpu.uuid}']")['href']
70
+ .must_equal "/clients/#{cpu.uuid}"
71
+ links.at("[data-uuid='#{cpu.uuid}']")['data-busy'].must_equal 'false'
72
+ links.at("[data-uuid='#{gpu.uuid}']")['data-busy'].must_equal 'true'
73
+ links.at("[data-uuid='#{cpu.uuid}']")['data-type'].must_equal 'CPU'
74
+ links.at("[data-uuid='#{gpu.uuid}']")['data-type'].must_equal 'GPU'
75
+ end
63
76
 
64
- it 'contains links to and info on the project’s tasks' do
65
- get "/projects/#{gimps.uuid}"
66
- links = doc.css '#tasks a[rel=task]'
67
- links.size.must_equal 2
68
- links.at("[data-uuid='#{three.uuid}']")['href']
69
- .must_equal "/tasks/#{three.uuid}"
70
- links.at("[data-uuid='#{three.uuid}']")['data-done'].must_equal 'false'
71
- links.at("[data-uuid='#{seven.uuid}']")['data-done'].must_equal 'true'
77
+ it 'contains links to and info on the project’s tasks' do
78
+ get "/projects/#{gimps.uuid}"
79
+ links = doc.css('#tasks a[data-class=task]')
80
+ links.size.must_equal 2
81
+ links.at("[data-uuid='#{three.uuid}']")['href']
82
+ .must_equal "/tasks/#{three.uuid}"
83
+ links.at("[data-uuid='#{three.uuid}']")['data-done'].must_equal 'false'
84
+ links.at("[data-uuid='#{seven.uuid}']")['data-done'].must_equal 'true'
85
+ end
72
86
  end
73
- end
74
87
 
75
- describe 'POST /projects' do
76
- it 'creates a new project with the given name and UUID' do
77
- post '/projects', name: 'ECC', uuid: uuid = UUID.new
78
- repos.must_have_received :<<, [Project.new(name: 'ECC', uuid: uuid)]
79
- end
88
+ describe 'POST /projects' do
89
+ it 'creates a new project with the given name and UUID' do
90
+ post '/projects', name: 'ECC', uuid: uuid = UUID.new
91
+ repos.must_have_received :<<, [Project.new(name: 'ECC', uuid: uuid)]
92
+ end
80
93
 
81
- it 'creates a new project with a random UUID if missing' do
82
- post '/projects', name: 'ECC'
83
- project = Project.new name: 'ECC', uuid: any(String)
84
- repos.must_have_received :<<, [project]
94
+ it 'redirects to /projects' do
95
+ post '/projects', name: 'ECC', uuid: UUID.new
96
+ follow_redirect!
97
+ URI(last_request.url).path.must_equal '/projects'
98
+ end
85
99
  end
86
100
 
87
- it 'redirects to /projects' do
88
- post '/projects', name: 'ECC'
89
- follow_redirect!
90
- URI(last_request.url).path.must_equal '/projects'
101
+ describe 'POST /projects/dispatch' do
102
+ it 'dispatches tasks to all free clients' do
103
+ post '/projects/dispatch'
104
+ task_dispatcher.must_have_received :dispatch_all, []
105
+ end
106
+
107
+ it 'redirects to /projects' do
108
+ post '/projects/dispatch'
109
+ follow_redirect!
110
+ URI(last_request.url).path.must_equal '/projects'
111
+ end
91
112
  end
92
113
  end
93
- end end
114
+ end
@@ -1,80 +1,111 @@
1
+ require 'logger'
2
+ require 'socket'
3
+ require 'stringio'
1
4
  require_relative '../spec_helper'
5
+ require_relative '../../lib/kamerling/addr'
6
+ require_relative '../../lib/kamerling/logging'
7
+ require_relative '../../lib/kamerling/message'
8
+ require_relative '../../lib/kamerling/net_dispatcher'
9
+ require_relative '../../lib/kamerling/server/tcp'
10
+ require_relative '../../lib/kamerling/server/udp'
2
11
 
3
- module Kamerling describe Logging do
4
- let(:logged) { stream.tap(&:rewind).read }
5
- let(:logger) { Logger.new stream }
6
- let(:stream) { StringIO.new }
7
- let(:tcp_server) { Server::TCP.new addr: Addr['localhost', 1981, :TCP] }
8
- let(:udp_server) { Server::UDP.new addr: Addr['localhost', 1979, :UDP] }
12
+ module Kamerling
13
+ describe Logging do
14
+ let(:logged) { stream.tap(&:rewind).read }
15
+ let(:logger) { Logger.new(stream) }
16
+ let(:stream) { StringIO.new }
17
+ let(:tcp_server) { Server::TCP.new(addr: Addr['localhost', 1981, :TCP]) }
18
+ let(:udp_server) { Server::UDP.new(addr: Addr['localhost', 1979, :UDP]) }
9
19
 
10
- before do
11
- Logging.log_to logger
12
- tcp_server.start
13
- udp_server.start
14
- end
15
-
16
- after do
17
- tcp_server.stop
18
- udp_server.stop
19
- end
20
-
21
- describe '.log_to' do
22
- it 'logs TCP server starts' do
23
- logged.must_include 'start localhost:1981 (TCP)'
20
+ before do
21
+ Logging.log_to logger
22
+ tcp_server.start
23
+ udp_server.start
24
24
  end
25
25
 
26
- it 'logs TCP server stops' do
26
+ after do
27
27
  tcp_server.stop
28
- logged.must_include 'stop localhost:1981 (TCP)'
28
+ udp_server.stop
29
29
  end
30
30
 
31
- it 'logs TCP server connects' do
32
- tcp_addr = TCPSocket.open(*tcp_server.addr) do |socket|
33
- Addr[*socket.local_address.ip_unpack, :TCP]
31
+ describe '.log_to' do
32
+ it 'logs TCP server starts' do
33
+ logged.must_include 'start tcp://localhost:1981'
34
34
  end
35
- run_all_threads
36
- logged.must_include "connect #{tcp_addr}"
37
- end
38
35
 
39
- it 'logs TCP server receives' do
40
- tcp_addr = TCPSocket.open(*tcp_server.addr) do |socket|
41
- socket << 'PING'
42
- Addr[*socket.local_address.ip_unpack, :TCP]
36
+ it 'logs TCP server stops' do
37
+ tcp_server.stop
38
+ logged.must_include 'stop tcp://localhost:1981'
43
39
  end
44
- run_all_threads
45
- logged.must_include "received #{tcp_addr} PING"
46
- end
47
40
 
48
- it 'logs UDP server starts' do
49
- logged.must_include 'start localhost:1979 (UDP)'
50
- end
41
+ it 'logs TCP server connects' do
42
+ tcp_addr = TCPSocket.open(*tcp_server.addr) do |socket|
43
+ Addr[*socket.local_address.ip_unpack, :TCP]
44
+ end
45
+ run_all_threads
46
+ logged.must_include "connect #{tcp_addr}"
47
+ end
51
48
 
52
- it 'logs UDP server stops' do
53
- udp_server.stop
54
- logged.must_include 'stop localhost:1979 (UDP)'
55
- end
49
+ it 'logs TCP server receives' do
50
+ tcp_addr = TCPSocket.open(*tcp_server.addr) do |socket|
51
+ socket << 'PING'
52
+ Addr[*socket.local_address.ip_unpack, :TCP]
53
+ end
54
+ run_all_threads
55
+ logged.must_include "received #{tcp_addr} 50 49 4e 47"
56
+ end
56
57
 
57
- it 'logs UDP server connects' do
58
- udp_client = UDPSocket.new
59
- udp_client.send 'PING', 0, *udp_server.addr
60
- udp_addr = Addr['127.0.0.1', udp_client.addr[1], :UDP]
61
- run_all_threads
62
- logged.must_include "connect #{udp_addr}"
63
- end
58
+ it 'logs TCP unknown message types' do
59
+ tcp_addr = TCPSocket.open(*tcp_server.addr) do |socket|
60
+ socket << 'foo'
61
+ Addr[*socket.local_address.ip_unpack, :TCP]
62
+ end
63
+ run_all_threads
64
+ logged.must_include "received #{tcp_addr} unknown message type"
65
+ end
64
66
 
65
- it 'logs TCP server receives' do
66
- udp_client = UDPSocket.new
67
- udp_client.send 'PING', 0, *udp_server.addr
68
- udp_addr = Addr['127.0.0.1', udp_client.addr[1], :UDP]
69
- run_all_threads
70
- logged.must_include "received #{udp_addr} PING"
71
- end
67
+ it 'logs UDP server starts' do
68
+ logged.must_include 'start udp://localhost:1979'
69
+ end
70
+
71
+ it 'logs UDP server stops' do
72
+ udp_server.stop
73
+ logged.must_include 'stop udp://localhost:1979'
74
+ end
75
+
76
+ it 'logs UDP server connects' do
77
+ udp_client = UDPSocket.new
78
+ udp_client.send 'PING', 0, *udp_server.addr
79
+ udp_addr = Addr['127.0.0.1', udp_client.addr[1], :UDP]
80
+ run_all_threads
81
+ logged.must_include "connect #{udp_addr}"
82
+ end
83
+
84
+ it 'logs UDP server receives' do
85
+ udp_client = UDPSocket.new
86
+ udp_client.send 'PING', 0, *udp_server.addr
87
+ udp_addr = Addr['127.0.0.1', udp_client.addr[1], :UDP]
88
+ run_all_threads
89
+ logged.must_include "received #{udp_addr} 50 49 4e 47"
90
+ end
72
91
 
73
- it 'logs packet dispatches' do
74
- server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
75
- addr = Addr[server.addr[3], server.addr[1], :UDP]
76
- NetDispatcher.dispatch addr, 'PING'
77
- logged.must_include "sent #{addr} PING"
92
+ it 'logs UDP unknown message types' do
93
+ udp_client = UDPSocket.new
94
+ addrs = Array.new(3) do
95
+ udp_client.send 'foo', 0, *udp_server.addr
96
+ Addr['127.0.0.1', udp_client.addr[1], :UDP]
97
+ end
98
+ run_all_threads
99
+ log_lines = addrs.map { |addr| "received #{addr} unknown message type" }
100
+ assert log_lines.any? { |line| logged.include?(line) }
101
+ end
102
+
103
+ it 'logs packet dispatches' do
104
+ server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
105
+ addr = Addr[server.addr[3], server.addr[1], :UDP]
106
+ NetDispatcher.dispatch addr, Message.parse('PING')
107
+ logged.must_include "sent #{addr} 50 49 4e 47"
108
+ end
78
109
  end
79
110
  end
80
- end end
111
+ end