Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,088 changes: 1,022 additions & 66 deletions OPENAPI_DOC.yml

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions spec/api/edge_monitoring_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require "../helper"

module PlaceOS::Core::Api
describe EdgeMonitoring, tags: "api" do
client = AC::SpecHelper.client

namespace = EdgeMonitoring::NAMESPACE[0]
json_headers = HTTP::Headers{
"Content-Type" => "application/json",
}

describe "POST /cleanup" do
it "responds with success message" do
response = client.post("#{namespace}cleanup", headers: json_headers, body: {hours: 24}.to_json)
response.status_code.should eq 200

result = JSON.parse(response.body)
result["success"].as_bool.should be_true
result["message"].as_s.should contain("24 hours")
result["timestamp"].as_s.should_not be_empty
end

it "accepts custom hours parameter" do
response = client.post("#{namespace}cleanup?hours=48", headers: json_headers)
response.status_code.should eq 200

result = JSON.parse(response.body)
result["success"].as_bool.should be_true
result["message"].as_s.should contain("48 hours")
end
end

describe "GET /summary" do
it "returns error summary statistics" do
response = client.get("#{namespace}summary", headers: json_headers)
response.status_code.should eq 200

result = JSON.parse(response.body)
result["total_edges"].as_i.should be >= 0
result["connected_edges"].as_i.should be >= 0
result["edges_with_errors"].as_i.should be >= 0
result["total_errors_24h"].as_i.should be >= 0
result["total_modules"].as_i.should be >= 0
result["failed_modules"].as_i.should be >= 0
result["timestamp"].as_s.should_not be_empty
end
end
end
end
74 changes: 74 additions & 0 deletions spec/api/status_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,79 @@ module PlaceOS::Core::Api

pending "status/driver"
pending "status/load"

describe "edge endpoints" do
it "GET /edge/:edge_id/errors returns errors for specific edge" do
edge_id = "test-edge-1"

response = client.get("#{namespace}edge/#{edge_id}/errors", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON array
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
result.as_a.should be_a(Array(JSON::Any))
end

it "GET /edge/:edge_id/modules/status returns module status for specific edge" do
edge_id = "test-edge-1"

response = client.get("#{namespace}edge/#{edge_id}/modules/status", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON and has expected fields
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
result["edge_id"].as_s.should eq edge_id
end

it "GET /edges/health returns health status for all edges" do
response = client.get("#{namespace}edges/health", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON and has the expected structure
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
end

it "GET /edges/connections returns connection metrics for all edges" do
response = client.get("#{namespace}edges/connections", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
end

it "GET /edges/errors returns errors from all edges" do
response = client.get("#{namespace}edges/errors", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
end

it "GET /edges/modules/failures returns module failures from all edges" do
response = client.get("#{namespace}edges/modules/failures", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
end

it "GET /edges/statistics returns overall edge statistics" do
response = client.get("#{namespace}edges/statistics", headers: json_headers)
response.status_code.should eq 200

# Just verify it's valid JSON and has expected fields
result = JSON.parse(response.body)
result.should be_a(JSON::Any)
result["total_edges"].as_i.should be >= 0
result["connected_edges"].as_i.should be >= 0
result["disconnected_edges"].as_i.should be >= 0
end
end
end
end
64 changes: 64 additions & 0 deletions spec/placeos-edge/client_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,69 @@ module PlaceOS::Edge
raise "timed out"
end
end

it "sends error and health reports" do
client = Client.new
client_ws, server_ws = mock_sockets

error_reports = Channel(Protocol::Message::ErrorReport).new
health_reports = Channel(Protocol::Message::HealthReport).new

server_ws.on_message do |m|
message = Protocol::Text.from_json(m)
case message.body
when Protocol::Message::Register
# Respond to registration
server_ws.send(Protocol::Text.new(message.sequence_id, Protocol::Message::RegisterResponse.new(true)).to_json)
when Protocol::Message::ErrorReport
error_reports.send(message.body.as(Protocol::Message::ErrorReport))
server_ws.send(Protocol::Text.new(message.sequence_id, Protocol::Message::Success.new(true)).to_json)
when Protocol::Message::HealthReport
health_reports.send(message.body.as(Protocol::Message::HealthReport))
server_ws.send(Protocol::Text.new(message.sequence_id, Protocol::Message::Success.new(true)).to_json)
end
end

spawn { server_ws.run }

spawn {
client.connect(client_ws) do
# Track an error to trigger immediate reporting
client.track_error(
PlaceOS::Core::ErrorType::ModuleExecution,
"Test error message",
{"test" => "context"},
PlaceOS::Core::Severity::Critical
)
end
}

Fiber.yield
sleep 0.1 # Give time for immediate error report

# Should receive an immediate error report for critical error
select
when error_report = error_reports.receive
error_report.edge_id.should_not be_empty
error_report.errors.size.should eq(1)

# Parse the error JSON
error_json = error_report.errors.first
error = PlaceOS::Core::EdgeError.from_json(error_json)
error.error_type.should eq(PlaceOS::Core::ErrorType::ModuleExecution)
error.message.should eq("Test error message")
error.severity.should eq(PlaceOS::Core::Severity::Critical)
when timeout 2.seconds
raise "timed out waiting for error report"
end

# Should also receive periodic health reports (though we won't wait for the full interval)
# We can test the health report generation directly
health = client.get_edge_health
health.edge_id.should_not be_empty
health.connected.should be_true
health.module_count.should eq(0) # No modules loaded in test
health.error_count_24h.should eq(1) # One error tracked
end
end
end
Loading
Loading