Skip to content

Commit

Permalink
Add Service API compability tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vankiru committed Jan 27, 2025
1 parent dcbf7fd commit af9a758
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 39 deletions.
29 changes: 22 additions & 7 deletions lib/nats/io/msg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,29 @@ def respond(data = "")
def respond_with_error(error)
message = dup

message.header = {
"Nats-Service-Error" => error.message,
"Nats-Service-Error-Code" => 500
}

message.subject = reply
message.reply = nil
message.data = nil
message.reply = ""
message.data = ""

case error
when Exception
message.header = {
"Nats-Service-Error" => error.message,
"Nats-Service-Error-Code" => 500
}
when Hash
message.header = {
"Nats-Service-Error" => error[:description],
"Nats-Service-Error-Code" => error[:code]
}

message.data = error[:data]
else
message.header = {
"Nats-Service-Error" => error.to_s,
"Nats-Service-Error-Code" => 500
}
end

respond_msg(message)
end
Expand Down
6 changes: 4 additions & 2 deletions lib/nats/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ class Service
attr_reader :client, :name, :id, :version, :description, :metadata, :queue
attr_reader :monitoring, :status, :callbacks, :groups, :endpoints

alias_method :subject, :name

def initialize(client, options)
super()
validate(options)
Expand Down Expand Up @@ -74,6 +72,10 @@ def service
self
end

def subject
nil
end

private

def validate(options)
Expand Down
8 changes: 7 additions & 1 deletion lib/nats/service/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def initialize(name:, options:, parent:, &block)
@name = name

@service = parent.service
@subject = "#{parent.subject}.#{options[:subject] || name}"
@subject = build_subject(parent, options)
@queue = options[:queue] || parent.queue
@metadata = options[:metadata]

Expand Down Expand Up @@ -45,6 +45,12 @@ def validate(name, options)
)
end

def build_subject(parent, options)
subject = options[:subject] || name

parent.subject ? "#{parent.subject}.#{subject}" : subject
end

def create_handler(block)
service.client.subscribe(subject, queue: queue) do |msg|
started_at = Time.now
Expand Down
2 changes: 1 addition & 1 deletion lib/nats/service/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def initialize(name:, parent:, queue:)
@name = name

@service = parent.service
@subject = "#{parent.subject}.#{name}"
@subject = parent.subject ? "#{parent.subject}.#{name}" : name
@queue = queue || parent.queue
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/nats/service/stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def reset
@average_processing_time = 0

@num_errors = 0
@last_error = nil
@last_error = ""
end
end

Expand Down
81 changes: 81 additions & 0 deletions spec/compability/service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

module NATS
class Compability
class ServiceApi
class Service
attr_reader :service, :client

def initialize(client)
@client = client
end

def start
add_service
add_endpoints
end

def stop
@service.stop
end

private

def add_service
@service = client.add_service(
name: "demo",
version: "1.0.0",
description: "demo service",
metadata: {workload: "cpu"}
)

service.on_stats do |endpoint|
{endpoint: endpoint.name}
end
end

def add_endpoints
group1 = service.add_group("g1")
group2 = service.add_group("g2", queue: "group-queue")

add_endpoint(service, "demo-default-queue", subject: "demo.default", metadata: {key: "value"})
add_endpoint(service, "demo-custom-queue", subject: "demo.default", queue: "endpoint-group")

add_endpoint(group1, "g1-parent-queue", subject: "parent.queue")
add_endpoint(group1, "g1-custom-queue", subject: "custom.queue", queue: "endpoint-group")

add_endpoint(group2, "g2-parent-queue", subject: "parent.queue")
add_endpoint(group2, "g2-custom-queue", subject: "custom.queue", queue: "endpoint-group")

service.add_endpoint("faulty", subject: "faulty") do |msg|
raise "handler error"
end
end

def add_endpoint(parent, name, options)
parent.add_endpoint(name, options) do |msg|
msg.respond(msg.data)
end
end
end

def run
service = Service.new(client)

client.subscribe("tests.service.core.>") do |msg|
if msg.data.empty?
service.stop
else
service.start
end

msg.respond("")
end
end

def client
@client ||= NATS.connect
end
end
end
end
100 changes: 100 additions & 0 deletions spec/msg_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# frozen_string_literal: true

RSpec.describe NATS::Msg do
subject { described_class.new(options) }

let(:options) do
{
subject: "foo",
reply: "bar",
data: "foo.bar",
header: {},
nc: nil,
sub: nil
}
end

describe "#respond_with_error" do
let(:respond_with_error) { subject.respond_with_error(error) }

before do
allow(subject).to receive(:respond_msg)
end

let(:respond) do
{
subject: "bar",
header: {
"Nats-Service-Error" => "error",
"Nats-Service-Error-Code" => 500
},
reply: "",
data: ""
}
end

context "when argument is a string" do
let(:error) { "error" }

it "responds with service error message" do
respond_with_error

expect(subject).to have_received(:respond_msg).with have_attributes(respond)
end
end

context "when argument is a hash" do
let(:error) { {code: 503, description: "error", data: "data"} }

let(:respond) do
{
subject: "bar",
header: {
"Nats-Service-Error" => "error",
"Nats-Service-Error-Code" => 503
},
reply: "",
data: "data"
}
end

it "responds with service error message" do
respond_with_error

expect(subject).to have_received(:respond_msg).with have_attributes(respond)
end
end

context "when argument is an error" do
let(:error) { StandardError.new("error") }

it "responds with service error message" do
respond_with_error

expect(subject).to have_received(:respond_msg).with have_attributes(respond)
end
end

context "when argument is a random object" do
let(:error) { [1, 2, 3] }

let(:respond) do
{
subject: "bar",
header: {
"Nats-Service-Error" => "[1, 2, 3]",
"Nats-Service-Error-Code" => 500
},
reply: "",
data: ""
}
end

it "responds with argument " do
respond_with_error

expect(subject).to have_received(:respond_msg).with have_attributes(respond)
end
end
end
end
34 changes: 26 additions & 8 deletions spec/service/endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
let(:service) { client.add_service(name: "foo", queue: "queue") }

subject do
described_class.new(name: name, options: options, parent: service, &block)
described_class.new(name: name, options: options, parent: parent, &block)
end

let(:name) { "bar" }
let(:options) { {} }
let(:parent) { service }
let(:block) { ->(msg) { msg.respond("bar") } }

after { service.stop }
after do
service.stop
client.close
end

describe "#initialize" do
it "sets service" do
Expand All @@ -46,19 +50,33 @@
end
end

context "when parent is a service" do
it "builds sets subject to name" do
expect(subject.subject).to eq("bar")
end
end

context "when parent is a group" do
let(:parent) { service.add_group("baz") }

it "builds subject based on parent.subject" do
expect(subject.subject).to eq("baz.bar")
end
end

context "when options[:subject] is present" do
let(:options) { {subject: "baz"} }

it "builds subject based on options[:subject]" do
expect(subject.subject).to eq("foo.baz")
expect(subject.subject).to eq("baz")
end
end

context "when options[:subject] is blank" do
let(:options) { {subject: nil} }

it "builds subject based on endpoint name" do
expect(subject.subject).to eq("foo.bar")
expect(subject.subject).to eq("bar")
end
end

Expand Down Expand Up @@ -121,7 +139,7 @@
let(:request) do
subject
begin
client.request("foo.bar")
client.request("bar")
rescue
nil
end
Expand Down Expand Up @@ -195,7 +213,7 @@
subject.stop

expect(subs.values).to include(
having_attributes(subject: "foo.bar", drained: true)
having_attributes(subject: "bar", drained: true)
)
end

Expand All @@ -209,7 +227,7 @@
describe "#reset" do
before do
subject
3.times { client.request("foo.bar") }
3.times { client.request("bar") }
end

it "resets endpoint stats" do
Expand All @@ -220,7 +238,7 @@
processing_time: 0,
average_processing_time: 0,
num_errors: 0,
last_error: nil
last_error: ""
)
end
end
Expand Down
4 changes: 3 additions & 1 deletion spec/service/extension_examples.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# frozen_string_literal: true

RSpec.shared_examples "extension" do |params|
let(:subject_value) { "#{subject.subject}.baz" }
let(:subject_value) do
subject.is_a?(NATS::Service) ? "baz" : "#{subject.subject}.baz"
end

describe "#add_group" do
context "when queue is specified" do
Expand Down
Loading

0 comments on commit af9a758

Please sign in to comment.