anyt 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75c73a6373cc4d26033b8fd5caf3d8b5601d06644227f7ee279818b8fc5e4afd
4
- data.tar.gz: d187153da7f0e4b3d7aae6d5a67594a66817beac1364e7741b0b2fb98b2ef7b3
3
+ metadata.gz: 0c9c827378c7eb12bd020314e569289176896a6c2ea3c08ea649e9ec8674590f
4
+ data.tar.gz: 62da136e9594732d956f1113797209dd7853f929cbd2301b17c79d97836b2934
5
5
  SHA512:
6
- metadata.gz: 1b06df7c02346d0c6986f42e5e71b33875c99ee0924c41a31ea4de574b3b65eaf15069f410962aaf6d62a1af511efd9505f49ade5cbf9815f2bdec00e5a7ff51
7
- data.tar.gz: 4955e07d7fac679f27f55604faea71d513bc66cfaf85abcd2e6f46db375a706a6d9d281ad36529f7d124a2e7242a777d4c83d11ec6020bfe9160f0bfbb076bfe
6
+ metadata.gz: c5c1cef4a681e2814941391092dde7e72709072ec0a5c5f3db63c57ce961255fafdee3524458ba286abe3c85b31a456e0d834e3b921efc6b4480fa963b966741
7
+ data.tar.gz: 4dd4cc71eab70762f8bd1f3d1c16b710d41cf660d58b333012309419d6c8433393612600a70c456fc87f2239d9c3ee5c645aaa3ed72391c6bcc6d3881c290ba7
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  [![Cult Of Martians](http://cultofmartians.com/assets/badges/badge.svg)](https://cultofmartians.com/tasks/anycable-conformance-tool.html#task)
2
2
  [![Gem Version](https://badge.fury.io/rb/anyt.svg)](https://rubygems.org/gems/anyt)
3
3
  ![Test](https://github.com/anycable/anyt/workflows/Test/badge.svg)
4
- [![Gitter](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/anycable/anycablebility)
5
4
 
6
5
  # AnyCable Conformance Testing Tool
7
6
 
data/lib/anyt/cli.rb CHANGED
@@ -32,7 +32,7 @@ module Anyt
32
32
  end
33
33
 
34
34
  # Load all test scenarios
35
- Tests.load_tests
35
+ Tests.load_tests unless @skip_tests
36
36
 
37
37
  Rails.application.initialize!
38
38
 
@@ -50,8 +50,14 @@ module Anyt
50
50
  # Start webosocket server under test
51
51
  Command.run
52
52
 
53
- # Run tests
54
- result = Tests.run ? 0 : 1
53
+ unless @skip_tests
54
+ # Run tests
55
+ result = Tests.run ? 0 : 1
56
+ end
57
+
58
+ wait_till_terminated if @only_rails
59
+ rescue Interrupt => e
60
+ $stdout.puts "#{e.message}. Good-bye!"
55
61
  ensure
56
62
  RPC.stop unless @skip_rpc
57
63
  Command.stop
@@ -91,16 +97,21 @@ module Anyt
91
97
 
92
98
  cli.on("--only-rpc", TrueClass, "Run only RPC server") do |flag|
93
99
  @only_rpc = flag
100
+ @skip_tests = true
101
+ end
102
+
103
+ cli.on("--only-rails", TrueClass, "Run only Rails server") do
104
+ @skip_rpc = true
105
+ @only_rails = true
106
+ @skip_tests = true
107
+
108
+ configure_rails_command!
94
109
  end
95
110
 
96
111
  cli.on("--self-check", "Run tests again Action Cable itself") do
97
112
  @skip_rpc = true
98
- dummy_path = ::File.expand_path(
99
- "config.ru",
100
- ::File.join(::File.dirname(__FILE__), "dummy")
101
- )
102
- Anyt.config.command = "bundle exec puma #{dummy_path}"
103
- Anyt.config.use_action_cable = true
113
+
114
+ configure_rails_command!
104
115
  end
105
116
 
106
117
  cli.on("--only test1,test2,test3", Array, "Run only specified tests") do |only_tests|
@@ -149,6 +160,36 @@ module Anyt
149
160
  puts "Use `anyt --help` to list all available options."
150
161
  exit 1
151
162
  end
163
+
164
+ def configure_rails_command!
165
+ dummy_path = ::File.expand_path(
166
+ "config.ru",
167
+ ::File.join(::File.dirname(__FILE__), "dummy")
168
+ )
169
+ Anyt.config.command = "bundle exec puma #{dummy_path}"
170
+ Anyt.config.use_action_cable = true
171
+ end
172
+
173
+ def wait_till_terminated
174
+ self_read = setup_signals
175
+
176
+ while readable_io = IO.select([self_read]) # rubocop:disable Lint/AssignmentInCondition
177
+ signal = readable_io.first[0].gets.strip
178
+ raise Interrupt, "SIG#{signal} received"
179
+ end
180
+ end
181
+
182
+ def setup_signals
183
+ self_read, self_write = IO.pipe
184
+
185
+ %w[INT TERM].each do |signal|
186
+ trap signal do
187
+ self_write.puts signal
188
+ end
189
+ end
190
+
191
+ self_read
192
+ end
152
193
  end
153
194
  end
154
195
  end
data/lib/anyt/command.rb CHANGED
@@ -11,6 +11,8 @@ module Anyt
11
11
  def run
12
12
  return if running?
13
13
 
14
+ return unless Anyt.config.command
15
+
14
16
  AnyCable.logger.debug "Running command: #{Anyt.config.command}"
15
17
 
16
18
  @process = ChildProcess.build(*Anyt.config.command.split(/\s+/))
data/lib/anyt/config.rb CHANGED
@@ -15,6 +15,9 @@ module Anyt
15
15
  wait_command: 2,
16
16
  timeout_multiplier: 1
17
17
 
18
+ coerce_types only_tests: {type: :string, array: true}
19
+ coerce_types except_tests: {type: :string, array: true}
20
+
18
21
  def tests_path
19
22
  return unless tests_relative_path
20
23
 
@@ -42,6 +42,29 @@ module ApplicationCable
42
42
  end
43
43
  end
44
44
 
45
+ # BenchmarkChannel is useful when running Rails app only or RPC only
46
+ class BenchmarkChannel < ApplicationCable::Channel
47
+ def subscribed
48
+ stream_from "all#{stream_id}"
49
+ end
50
+
51
+ def echo(data)
52
+ transmit data
53
+ end
54
+
55
+ def broadcast(data)
56
+ ActionCable.server.broadcast "all#{stream_id}", data
57
+ data["action"] = "broadcastResult"
58
+ transmit data
59
+ end
60
+
61
+ private
62
+
63
+ def stream_id
64
+ params[:id] || ""
65
+ end
66
+ end
67
+
45
68
  ActionCable.server.config.cable = {"adapter" => "redis"}
46
69
  ActionCable.server.config.connection_class = -> { ApplicationCable::Connection }
47
70
  ActionCable.server.config.disable_request_forgery_protection = true
@@ -12,9 +12,9 @@ module Anyt
12
12
  base.after { @clients&.each { |client| client.close(allow_messages: true) } }
13
13
  end
14
14
 
15
- def build_client(*args)
15
+ def build_client(**args)
16
16
  @clients ||= []
17
- Anyt::Client.new(*args).tap do |client|
17
+ Anyt::Client.new(**args).tap do |client|
18
18
  @clients << client
19
19
  end
20
20
  end
data/lib/anyt/rpc.rb CHANGED
@@ -19,10 +19,9 @@ module Anyt # :nodoc:
19
19
 
20
20
  AnyCable.server_callbacks.each(&:call)
21
21
 
22
- @server = AnyCable::Server.new(
22
+ @server = AnyCable::GRPC::Server.new(
23
23
  host: AnyCable.config.rpc_host,
24
- **AnyCable.config.to_grpc_params,
25
- interceptors: AnyCable.middleware.to_a
24
+ **AnyCable.config.to_grpc_params
26
25
  )
27
26
 
28
27
  AnyCable.middleware.freeze
@@ -7,16 +7,27 @@ feature "Channel state" do
7
7
  def subscribed
8
8
  self.user = {name: params["name"]}
9
9
  self.count = 1
10
+
11
+ stream_from "state_counts"
10
12
  end
11
13
 
12
14
  def tick
13
15
  self.count += 2
14
- transmit(count: count, name: user[:name])
16
+ transmit({count: count, name: user[:name]})
17
+ end
18
+
19
+ def unsubscribed
20
+ return unless params["notify_disconnect"]
21
+
22
+ ActionCable.server.broadcast("state_counts", {data: "user left: #{user[:name]}"})
15
23
  end
16
24
  end
17
25
 
18
26
  let(:identifier) { {channel: channel, name: "chipolino"}.to_json }
19
27
 
28
+ let(:client2) { build_client(ignore: %w[ping welcome]) }
29
+ let(:identifier2) { {channel: channel, name: "chipollone", notify_disconnect: true}.to_json }
30
+
20
31
  before do
21
32
  subscribe_request = {command: "subscribe", identifier: identifier}
22
33
 
@@ -44,4 +55,27 @@ feature "Channel state" do
44
55
 
45
56
  assert_equal msg, client.receive
46
57
  end
58
+
59
+ scenario %(
60
+ Channel state is available in #unsubscribe callbacks
61
+ ) do
62
+ subscribe_request = {command: "subscribe", identifier: identifier2}
63
+
64
+ client2.send(subscribe_request)
65
+
66
+ ack = {
67
+ "identifier" => identifier2, "type" => "confirm_subscription"
68
+ }
69
+
70
+ assert_equal ack, client2.receive
71
+
72
+ client2.close
73
+
74
+ msg = {
75
+ "identifier" => identifier,
76
+ "message" => {"data" => "user left: chipollone"}
77
+ }
78
+
79
+ assert_equal msg, client.receive
80
+ end
47
81
  end
@@ -7,7 +7,7 @@ feature "Request" do
7
7
  end
8
8
 
9
9
  def unsubscribed
10
- ActionCable.server.broadcast("request_a", data: "user left")
10
+ ActionCable.server.broadcast("request_a", {data: "user left"})
11
11
  end
12
12
  end
13
13
 
@@ -17,7 +17,7 @@ feature "Request" do
17
17
  end
18
18
 
19
19
  def unsubscribed
20
- ActionCable.server.broadcast("request_b", data: "user left")
20
+ ActionCable.server.broadcast("request_b", {data: "user left"})
21
21
  end
22
22
  end
23
23
 
@@ -27,7 +27,7 @@ feature "Request" do
27
27
  end
28
28
 
29
29
  def unsubscribed
30
- ActionCable.server.broadcast("request_c", data: "user left#{params[:id].presence}")
30
+ ActionCable.server.broadcast("request_c", {data: "user left#{params[:id].presence}"})
31
31
  end
32
32
  end
33
33
 
@@ -24,7 +24,7 @@ feature "Broadcast data to stream" do
24
24
  ) do
25
25
  ActionCable.server.broadcast(
26
26
  "a",
27
- data: {user_id: 1, status: "left", meta: {connection_time: "10s"}}
27
+ {data: {user_id: 1, status: "left", meta: {connection_time: "10s"}}}
28
28
  )
29
29
 
30
30
  msg = {
@@ -26,7 +26,7 @@ feature "Streams with many clients" do
26
26
  scenario %(
27
27
  Multiple clients receive messages from stream
28
28
  ) do
29
- ActionCable.server.broadcast("a", data: "X")
29
+ ActionCable.server.broadcast("a", {data: "X"})
30
30
 
31
31
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
32
32
 
@@ -37,7 +37,7 @@ feature "Streams with many clients" do
37
37
  scenario %(
38
38
  Client receive messages when another client removes subscription
39
39
  ) do
40
- ActionCable.server.broadcast("a", data: "X")
40
+ ActionCable.server.broadcast("a", {data: "X"})
41
41
 
42
42
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
43
43
 
@@ -51,7 +51,7 @@ feature "Streams with many clients" do
51
51
  # ActionCable doesn't provide an unsubscription ack :(
52
52
  sleep 1
53
53
 
54
- ActionCable.server.broadcast("a", data: "Y")
54
+ ActionCable.server.broadcast("a", {data: "Y"})
55
55
 
56
56
  msg2 = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "Y"}}
57
57
 
@@ -23,13 +23,13 @@ feature "Multiple streams" do
23
23
  scenario %(
24
24
  Client receives messages from both streams
25
25
  ) do
26
- ActionCable.server.broadcast("a", data: "X")
26
+ ActionCable.server.broadcast("a", {data: "X"})
27
27
 
28
28
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
29
29
 
30
30
  assert_equal msg, client.receive
31
31
 
32
- ActionCable.server.broadcast("b", data: "Y")
32
+ ActionCable.server.broadcast("b", {data: "Y"})
33
33
 
34
34
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "Y"}}
35
35
 
@@ -39,7 +39,7 @@ feature "Multiple streams" do
39
39
  scenario %(
40
40
  Client does not receive messages from any stream after removing subscription
41
41
  ) do
42
- ActionCable.server.broadcast("a", data: "X")
42
+ ActionCable.server.broadcast("a", {data: "X"})
43
43
 
44
44
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
45
45
 
@@ -52,8 +52,8 @@ feature "Multiple streams" do
52
52
  # ActionCable doesn't provide an unsubscription ack :(
53
53
  sleep 1
54
54
 
55
- ActionCable.server.broadcast("a", data: "Y")
56
- ActionCable.server.broadcast("b", data: "Z")
55
+ ActionCable.server.broadcast("a", {data: "Y"})
56
+ ActionCable.server.broadcast("b", {data: "Z"})
57
57
 
58
58
  assert_raises(Anyt::Client::TimeoutError) { client.receive(timeout: 0.5) }
59
59
  end
@@ -22,13 +22,13 @@ feature "Single stream" do
22
22
  scenario %(
23
23
  Client receives messages from the stream
24
24
  ) do
25
- ActionCable.server.broadcast("a", data: "X")
25
+ ActionCable.server.broadcast("a", {data: "X"})
26
26
 
27
27
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
28
28
 
29
29
  assert_equal msg, client.receive
30
30
 
31
- ActionCable.server.broadcast("a", data: "Y")
31
+ ActionCable.server.broadcast("a", {data: "Y"})
32
32
 
33
33
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "Y"}}
34
34
 
@@ -38,7 +38,7 @@ feature "Single stream" do
38
38
  scenario %(
39
39
  Client does not receive messages from the stream after removing subscription
40
40
  ) do
41
- ActionCable.server.broadcast("a", data: "X")
41
+ ActionCable.server.broadcast("a", {data: "X"})
42
42
 
43
43
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
44
44
 
@@ -51,7 +51,7 @@ feature "Single stream" do
51
51
  # ActionCable doesn't provide an unsubscription ack :(
52
52
  sleep 1
53
53
 
54
- ActionCable.server.broadcast("a", data: "Y")
54
+ ActionCable.server.broadcast("a", {data: "Y"})
55
55
 
56
56
  assert_raises(Anyt::Client::TimeoutError) { client.receive(timeout: 0.5) }
57
57
  end
@@ -70,7 +70,7 @@ feature "Single stream" do
70
70
 
71
71
  assert_equal ack, client.receive
72
72
 
73
- ActionCable.server.broadcast("a", data: "XX")
73
+ ActionCable.server.broadcast("a", {data: "XX"})
74
74
 
75
75
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "XX"}}
76
76
  msg2 = {"identifier" => {channel: channel, some_param: "test"}.to_json, "message" => {"data" => "XX"}}
@@ -8,7 +8,7 @@ feature "Stop streams" do
8
8
  end
9
9
 
10
10
  def ping(data)
11
- ActionCable.server.broadcast data["name"], reply: "pong"
11
+ ActionCable.server.broadcast data["name"], {reply: "pong"}
12
12
  end
13
13
 
14
14
  def unfollow(data)
@@ -33,7 +33,7 @@ feature "Stop streams" do
33
33
  ) do
34
34
  skip if Anyt.config.use_action_cable && (::ActionCable::VERSION::MAJOR < 6 || ::ActionCable::VERSION::MINOR < 1)
35
35
 
36
- ActionCable.server.broadcast("a", data: "X")
36
+ ActionCable.server.broadcast("a", {data: "X"})
37
37
 
38
38
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "X"}}
39
39
 
@@ -47,9 +47,9 @@ feature "Stop streams" do
47
47
  client.send(perform_request)
48
48
  sleep 0.2 # give some time to commit unsubscribe
49
49
 
50
- ActionCable.server.broadcast("a", data: "Y")
50
+ ActionCable.server.broadcast("a", {data: "Y"})
51
51
  sleep 0.2 # "a" should be broadcasted first
52
- ActionCable.server.broadcast("b", data: "Z")
52
+ ActionCable.server.broadcast("b", {data: "Z"})
53
53
 
54
54
  msg = {"identifier" => {channel: channel}.to_json, "message" => {"data" => "Z"}}
55
55
  assert_equal msg, client.receive
@@ -10,7 +10,7 @@ feature "Subscription perform methods" do
10
10
  end
11
11
 
12
12
  def echo(data)
13
- transmit(response: data["text"])
13
+ transmit({response: data["text"]})
14
14
  end
15
15
  end
16
16
 
data/lib/anyt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyt
4
- VERSION = "1.0.1"
4
+ VERSION = "1.1.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anyt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2022-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -58,28 +58,48 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '5.0'
61
+ version: '6.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '5.0'
68
+ version: '6.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: anyway_config
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: anycable-rails
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - ">"
74
88
  - !ruby/object:Gem::Version
75
- version: 1.0.0
89
+ version: 1.0.99
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '2.0'
76
93
  type: :runtime
77
94
  prerelease: false
78
95
  version_requirements: !ruby/object:Gem::Requirement
79
96
  requirements:
80
- - - ">="
97
+ - - ">"
81
98
  - !ruby/object:Gem::Version
82
- version: 1.0.0
99
+ version: 1.0.99
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: redis
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -243,7 +263,7 @@ homepage: http://github.com/anycable/anyt
243
263
  licenses:
244
264
  - MIT
245
265
  metadata: {}
246
- post_install_message:
266
+ post_install_message:
247
267
  rdoc_options: []
248
268
  require_paths:
249
269
  - lib
@@ -258,8 +278,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
278
  - !ruby/object:Gem::Version
259
279
  version: '0'
260
280
  requirements: []
261
- rubygems_version: 3.0.6
262
- signing_key:
281
+ rubygems_version: 3.2.22
282
+ signing_key:
263
283
  specification_version: 4
264
284
  summary: Anycable conformance testing tool
265
285
  test_files: []