Aggiunge registry nodi stream e provisioning Hetzner/lab per lo scale-out.
Prepara l'architettura multi-nodo (MediaMTX+ffmpeg) con assignment URL per sessione, admin di provision/drain e provider Cloud/DNS astratti verso mltv-stream.net. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Streams::NodeProvisioner do
|
||||
def with_env(vars)
|
||||
previous = vars.keys.index_with { |k| ENV[k] }
|
||||
vars.each { |k, v| ENV[k] = v }
|
||||
yield
|
||||
ensure
|
||||
previous.each { |k, v| v.nil? ? ENV.delete(k) : ENV[k] = v }
|
||||
end
|
||||
|
||||
let(:redis) { Redis.new(url: ENV.fetch("REDIS_URL", "redis://redis:6379/0")) }
|
||||
|
||||
before do
|
||||
redis.del(Streams::DnsProviders::Lab::REDIS_KEY)
|
||||
end
|
||||
|
||||
it "provisions and decommissions a simulated lab node" do
|
||||
with_env(
|
||||
"STREAM_CLOUD_PROVIDER" => "local_lab",
|
||||
"STREAM_DNS_PROVIDER" => "lab",
|
||||
"STREAM_LAB_DNS_SUFFIX" => "lab.mltv-stream.net",
|
||||
"MEDIAMTX_API_URL" => "http://mtx-home:9997",
|
||||
"MEDIAMTX_RTMP_URL" => "rtmp://ingest-home.example:1935",
|
||||
"HLS_PUBLIC_URL" => "https://ingest-home.example/hls",
|
||||
"STREAM_LAB_MAX_PUBLISHERS" => "2"
|
||||
) do
|
||||
provisioner = described_class.new
|
||||
node = provisioner.provision_lab!
|
||||
|
||||
expect(node.slug).to eq("ingest-lab-01")
|
||||
expect(node.role).to eq("lab")
|
||||
expect(node.status).to eq("ready")
|
||||
expect(node.hostname).to eq("ingest-lab-01.lab.mltv-stream.net")
|
||||
expect(node.api_base_url).to eq("http://mtx-home:9997")
|
||||
expect(Streams::DnsProviders::Lab.new.resolve(node.hostname)).to eq("127.0.0.1")
|
||||
|
||||
provisioner.decommission!(node)
|
||||
expect(StreamNode.find_by(slug: "ingest-lab-01")).to be_nil
|
||||
expect(Streams::DnsProviders::Lab.new.resolve("ingest-lab-01.lab.mltv-stream.net")).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it "refuses to decommission a busy node" do
|
||||
with_env(
|
||||
"STREAM_CLOUD_PROVIDER" => "local_lab",
|
||||
"STREAM_DNS_PROVIDER" => "lab",
|
||||
"MEDIAMTX_API_URL" => "http://mtx-home:9997",
|
||||
"MEDIAMTX_RTMP_URL" => "rtmp://ingest-home.example:1935",
|
||||
"HLS_PUBLIC_URL" => "https://ingest-home.example/hls"
|
||||
) do
|
||||
node = described_class.new.provision_lab!
|
||||
user = User.create!(email: "lab@example.com", name: "L", password: "Password123", role: "coach")
|
||||
club = Club.create!(name: "LabClub", sport: "volleyball")
|
||||
team = club.teams.create!(name: "T", sport: "volleyball", slug: "lab-t")
|
||||
match = team.matches.create!(opponent_name: "X", scheduled_at: 1.hour.from_now)
|
||||
StreamSession.create!(match: match, user: user, platform: "matchlivetv", status: "live", stream_node: node)
|
||||
|
||||
expect { described_class.new.decommission!(node) }.to raise_error(Streams::NodeProvisioner::BusyError)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user