diff --git a/bin/test_snikket_launch b/bin/test_snikket_launch new file mode 100755 index 0000000000000000000000000000000000000000..9f696c99918141c43ab11572f393160ad3455bad --- /dev/null +++ b/bin/test_snikket_launch @@ -0,0 +1,137 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "dhall" +require "net/http" +require "uri" +require "time" +require "em-http" +require "em-synchrony/em-http" +require "link-header-parser" + +require_relative "../lib/em" +require_relative "../lib/blather_notify" +require_relative "../lib/form_to_h" +require "ougai" + +$stdout.sync = true +LOG = Ougai::Logger.new($stdout) +LOG.level = ENV.fetch("LOG_LEVEL", "info") +LOG.formatter = Ougai::Formatters::Readable.new( + nil, + nil, + plain: !$stdout.isatty +) +Blather.logger = LOG + +CONFIG = Dhall.load(<<-DHALL).sync + (#{ARGV[0]}) : { + node: Text, + jid: Text, + password: Text, + sgx_jmp: Text, + interval: Int, + max_attempts: Int + } +DHALL + +DOMAIN = "jmp-test-#{Time.now.to_i}.snikket.chat" + +using FormToH + +class TestInstance + def launch + puts "Launching instance at #{DOMAIN}" + BlatherNotify.execute( + "snikket", + { domain: DOMAIN }.to_form(:submit) + ).then do |iq| + @id = iq.form.field("instance-id").value.to_s + @uri = iq.form.field("bootstrap-uri").value.to_s + end + end + + def extract_link(res) + LinkHeaderParser.parse( + Array(res.response_header["LINK"].sub(/>([^:])/, ">;\\1")), base: @uri + ).group_by_relation_type[:alternate].find { |header| + URI.parse(header.target_uri).scheme == "xmpp" + }.target_uri + end + + def ping_http(attempt: 0) + raise "Couldn't ping #{DOMAIN} over HTTP" if attempt > CONFIG[:max_attempts] + + EM::HttpRequest.new( + @uri, tls: { verify_peer: true } + ).ahead(redirects: 5).then { |res| extract_link(res) }.catch { |e| + puts "HTTP ping attempt #{attempt} failed: #{e}" + EM.promise_timer(CONFIG[:interval]).then { + ping_http(attempt: attempt + 1) + } + } + end + + def ping_xmpp(attempt: 0) + raise "Couldn't ping {#DOMAIN} over XMPP" if attempt > CONFIG[:max_attempts] + + BlatherNotify.write_with_promise( + Blather::Stanza::Iq::Ping.new(:get, DOMAIN) + ).catch { |e| + puts "XMPP ping attempt #{attempt} failed: #{e}" + EM.promise_timer(CONFIG[:interval]).then { + ping_xmpp(attempt: attempt + 1) + } + } + end + + def stop + puts "Stopping instance at #{DOMAIN}" + BlatherNotify.execute( + "stop snikket", + { instance_id: @id }.to_form(:submit) + ).then do |iq| + raise "Couldn't stop instance: #{iq.note}" if iq.note_type == :error + end + end + + def delete + puts "Deleting instance at #{DOMAIN}" + BlatherNotify.execute( + "delete snikket", + { instance_id: @id }.to_form(:submit) + ).then do |iq| + puts iq + raise "Couldn't stop instance: #{iq.note}" if iq.note_type == :error + end + end +end + +EM.run do + instance = TestInstance.new + + BlatherNotify.start( + CONFIG[:jid], + CONFIG[:password] + ).then { + instance.launch + }.then { + puts "Launch instance success" + instance.ping_http + }.then { + puts "HTTP ping success" + instance.ping_xmpp + }.then { + puts "XMPP ping success" + instance.stop + }.then { + puts "Stop instance success" + instance.delete + }.catch { |e| + p e + exit 1 + }.then { + puts "Delete instance success" + EM.stop + } +end