implement :update_pod callback

This commit is contained in:
Benjamin Neff 2016-01-28 05:00:20 +01:00
parent 4408efdff3
commit 1790efad08
4 changed files with 112 additions and 9 deletions

View file

@ -19,6 +19,15 @@ class Pod < ActiveRecord::Base
ConnectionTester::NodeInfoFailure => :version_failed
}
# this are only the most common errors, the rest will be +unknown_error+
CURL_ERROR_MAP = {
couldnt_resolve_host: :dns_failed,
couldnt_connect: :net_failed,
operation_timedout: :net_failed,
ssl_cipher: :ssl_failed,
ssl_cacert: :ssl_failed
}.freeze
DEFAULT_PORTS = [URI::HTTP::DEFAULT_PORT, URI::HTTPS::DEFAULT_PORT]
has_many :people
@ -76,17 +85,20 @@ class Pod < ActiveRecord::Base
uri.tap {|uri| uri.path = path }.to_s
end
def update_offline_since
if offline?
touch(:offline_since) unless was_offline?
else
self.offline_since = nil
end
end
private
def update_from_result(result)
self.status = status_from_result(result)
if offline?
touch(:offline_since) unless was_offline?
logger.warn "OFFLINE #{result.failure_message}"
else
self.offline_since = nil
end
update_offline_since
logger.warn "OFFLINE #{result.failure_message}" if offline?
attributes_from_result(result)
touch(:checked_at)

View file

@ -119,8 +119,21 @@ DiasporaFederation.configure do |config|
Person.find_by(diaspora_handle: diaspora_id).send(:url_to, path)
end
on :update_pod do
# TODO
on :update_pod do |url, status|
pod = Pod.find_or_create_by(url: url)
if status.is_a? Symbol
pod.status = Pod::CURL_ERROR_MAP.fetch(status, :unknown_error)
pod.error = "FederationError: #{status}"
elsif status >= 200 && status < 300
pod.status = :no_errors unless Pod.statuses[pod.status] == Pod.statuses[:version_failed]
else
pod.status = :http_failed
pod.error = "FederationError: HTTP status code was: #{status}"
end
pod.update_offline_since
pod.save
end
end
end

View file

@ -389,4 +389,47 @@ describe "diaspora federation callbacks" do
).to eq("https://#{pod.host}/path/on/pod")
end
end
describe ":update_pod" do
let(:pod) { FactoryGirl.create(:pod) }
let(:pod_url) { pod.url_to("/") }
it "sets the correct error for curl-errors" do
pod = FactoryGirl.create(:pod)
DiasporaFederation.callbacks.trigger(:update_pod, pod.url_to("/"), :ssl_cacert)
updated_pod = Pod.find_or_create_by(url: pod.url_to("/"))
expect(Pod.statuses[updated_pod.status]).to eq(Pod.statuses[:ssl_failed])
expect(updated_pod.error).to eq("FederationError: ssl_cacert")
end
it "sets :no_errors to a pod that was down but up now and return code 202" do
pod = FactoryGirl.create(:pod, status: :unknown_error)
DiasporaFederation.callbacks.trigger(:update_pod, pod.url_to("/"), 202)
updated_pod = Pod.find_or_create_by(url: pod.url_to("/"))
expect(Pod.statuses[updated_pod.status]).to eq(Pod.statuses[:no_errors])
end
it "does not change a pod that has status :version_failed and was successful" do
pod = FactoryGirl.create(:pod, status: :version_failed)
DiasporaFederation.callbacks.trigger(:update_pod, pod.url_to("/"), 202)
updated_pod = Pod.find_or_create_by(url: pod.url_to("/"))
expect(Pod.statuses[updated_pod.status]).to eq(Pod.statuses[:version_failed])
end
it "sets :http_failed if it has an unsuccessful http status code" do
pod = FactoryGirl.create(:pod)
DiasporaFederation.callbacks.trigger(:update_pod, pod.url_to("/"), 404)
updated_pod = Pod.find_or_create_by(url: pod.url_to("/"))
expect(Pod.statuses[updated_pod.status]).to eq(Pod.statuses[:http_failed])
expect(updated_pod.error).to eq("FederationError: HTTP status code was: 404")
end
end
end

View file

@ -136,4 +136,39 @@ describe Pod, type: :model do
expect(pod.url_to("/receive/public")).to eq("https://#{pod.host}/receive/public")
end
end
describe "#update_offline_since" do
let(:pod) { FactoryGirl.create(:pod) }
it "handles a successful status" do
pod.status = :no_errors
pod.update_offline_since
expect(pod.offline?).to be_falsey
expect(pod.offline_since).to be_nil
end
it "handles a failed status" do
pod.status = :unknown_error
pod.update_offline_since
expect(pod.offline?).to be_truthy
expect(pod.offline_since).to be_within(1.second).of Time.zone.now
end
it "preserves the original offline timestamp" do
pod.status = :unknown_error
pod.update_offline_since
pod.save
now = Time.zone.now
expect(pod.offline_since).to be_within(1.second).of now
Timecop.travel(Time.zone.today + 30.days) do
pod.update_offline_since
expect(pod.offline_since).to be_within(1.second).of now
expect(Time.zone.now).to be_within(1.day).of(now + 30.days)
end
end
end
end