kamerling 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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