From 5f0a3ac74d51333a778e6be26876fe26b0ff625b Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Mon, 18 May 2020 09:22:26 +0300 Subject: [PATCH] added tests --- docs/configuration/cheatsheet.md | 14 ++++++++ lib/pleroma/web/media_proxy/invalidation.ex | 8 ++++- .../web/media_proxy/invalidations/http.ex | 26 +++++++++++++- .../web/media_proxy/invalidations/script.ex | 30 ++++++++++++++-- .../media_proxy/invalidations/http_test.exs | 35 +++++++++++++++++++ .../media_proxy/invalidations/script_test.exs | 20 +++++++++++ 6 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 test/web/media_proxy/invalidations/http_test.exs create mode 100644 test/web/media_proxy/invalidations/script_test.exs diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index aaea3f46c..ddea6a4fb 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -262,6 +262,12 @@ Urls of attachments pass to script as arguments. * `script_path`: path to external script. +Example: +```elixir +config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, + script_path: "./installation/nginx-cache-purge.example" +``` + #### Pleroma.Web.MediaProxy.Invalidation.Http This strategy allow perform custom http request to purge cache. @@ -270,6 +276,14 @@ This strategy allow perform custom http request to purge cache. * `headers`: http headers. default is empty * `options`: request options. default is empty +Example: +```elixir +config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http, + method: :purge, + headers: [], + options: [] +``` + ## Link previews ### Pleroma.Web.Metadata (provider) diff --git a/lib/pleroma/web/media_proxy/invalidation.ex b/lib/pleroma/web/media_proxy/invalidation.ex index 371aa8ae0..c037ff13e 100644 --- a/lib/pleroma/web/media_proxy/invalidation.ex +++ b/lib/pleroma/web/media_proxy/invalidation.ex @@ -1,8 +1,15 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.MediaProxy.Invalidation do + @moduledoc false + @callback purge(list(String.t()), map()) :: {:ok, String.t()} | {:error, String.t()} alias Pleroma.Config + @spec purge(list(String.t())) :: {:ok, String.t()} | {:error, String.t()} def purge(urls) do [:media_proxy, :invalidation, :enabled] |> Config.get() @@ -13,7 +20,6 @@ defp do_purge(true, urls) do provider = Config.get([:media_proxy, :invalidation, :provider]) options = Config.get(provider) provider.purge(urls, options) - :ok end defp do_purge(_, _), do: :ok diff --git a/lib/pleroma/web/media_proxy/invalidations/http.ex b/lib/pleroma/web/media_proxy/invalidations/http.ex index 66fafa7ba..07248df6e 100644 --- a/lib/pleroma/web/media_proxy/invalidations/http.ex +++ b/lib/pleroma/web/media_proxy/invalidations/http.ex @@ -1,16 +1,40 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.MediaProxy.Invalidation.Http do + @moduledoc false @behaviour Pleroma.Web.MediaProxy.Invalidation + require Logger + @impl Pleroma.Web.MediaProxy.Invalidation def purge(urls, opts) do method = Map.get(opts, :method, :purge) headers = Map.get(opts, :headers, []) options = Map.get(opts, :options, []) + Logger.debug("Running cache purge: #{inspect(urls)}") + Enum.each(urls, fn url -> - Pleroma.HTTP.request(method, url, "", headers, options) + with {:error, error} <- do_purge(method, url, headers, options) do + Logger.error("Error while cache purge: url - #{url}, error: #{inspect(error)}") + end end) {:ok, "success"} end + + defp do_purge(method, url, headers, options) do + case Pleroma.HTTP.request(method, url, "", headers, options) do + {:ok, %{status: status} = env} when 400 <= status and status < 500 -> + {:error, env} + + {:error, error} = error -> + error + + _ -> + {:ok, "success"} + end + end end diff --git a/lib/pleroma/web/media_proxy/invalidations/script.ex b/lib/pleroma/web/media_proxy/invalidations/script.ex index 94c79511a..6be782132 100644 --- a/lib/pleroma/web/media_proxy/invalidations/script.ex +++ b/lib/pleroma/web/media_proxy/invalidations/script.ex @@ -1,6 +1,14 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.MediaProxy.Invalidation.Script do + @moduledoc false + @behaviour Pleroma.Web.MediaProxy.Invalidation + require Logger + @impl Pleroma.Web.MediaProxy.Invalidation def purge(urls, %{script_path: script_path} = _options) do args = @@ -9,7 +17,25 @@ def purge(urls, %{script_path: script_path} = _options) do |> Enum.uniq() |> Enum.join(" ") - System.cmd(Path.expand(script_path), [args]) - {:ok, "success"} + path = Path.expand(script_path) + + Logger.debug("Running cache purge: #{inspect(urls)}, #{path}") + + case do_purge(path, [args]) do + {result, exit_status} when exit_status > 0 -> + Logger.error("Error while cache purge: #{inspect(result)}") + {:error, inspect(result)} + + _ -> + {:ok, "success"} + end + end + + def purge(_, _), do: {:error, "not found script path"} + + defp do_purge(path, args) do + System.cmd(path, args) + rescue + error -> {inspect(error), 1} end end diff --git a/test/web/media_proxy/invalidations/http_test.exs b/test/web/media_proxy/invalidations/http_test.exs new file mode 100644 index 000000000..8a3b4141c --- /dev/null +++ b/test/web/media_proxy/invalidations/http_test.exs @@ -0,0 +1,35 @@ +defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do + use ExUnit.Case + alias Pleroma.Web.MediaProxy.Invalidation + + import ExUnit.CaptureLog + import Tesla.Mock + + test "logs hasn't error message when request is valid" do + mock(fn + %{method: :purge, url: "http://example.com/media/example.jpg"} -> + %Tesla.Env{status: 200} + end) + + refute capture_log(fn -> + assert Invalidation.Http.purge( + ["http://example.com/media/example.jpg"], + %{} + ) == {:ok, "success"} + end) =~ "Error while cache purge" + end + + test "it write error message in logs when request invalid" do + mock(fn + %{method: :purge, url: "http://example.com/media/example1.jpg"} -> + %Tesla.Env{status: 404} + end) + + assert capture_log(fn -> + assert Invalidation.Http.purge( + ["http://example.com/media/example1.jpg"], + %{} + ) == {:ok, "success"} + end) =~ "Error while cache purge: url - http://example.com/media/example1.jpg" + end +end diff --git a/test/web/media_proxy/invalidations/script_test.exs b/test/web/media_proxy/invalidations/script_test.exs new file mode 100644 index 000000000..1358963ab --- /dev/null +++ b/test/web/media_proxy/invalidations/script_test.exs @@ -0,0 +1,20 @@ +defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do + use ExUnit.Case + alias Pleroma.Web.MediaProxy.Invalidation + + import ExUnit.CaptureLog + + test "it logger error when script not found" do + assert capture_log(fn -> + assert Invalidation.Script.purge( + ["http://example.com/media/example.jpg"], + %{script_path: "./example"} + ) == {:error, "\"%ErlangError{original: :enoent}\""} + end) =~ "Error while cache purge: \"%ErlangError{original: :enoent}\"" + + assert Invalidation.Script.purge( + ["http://example.com/media/example.jpg"], + %{} + ) == {:error, "not found script path"} + end +end