aboutsummaryrefslogtreecommitdiff
path: root/benchmarks/mix/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks/mix/tasks')
-rw-r--r--benchmarks/mix/tasks/pleroma/benchmarks/tags.ex114
-rw-r--r--benchmarks/mix/tasks/pleroma/benchmarks/timelines.ex70
-rw-r--r--benchmarks/mix/tasks/pleroma/load_testing.ex67
3 files changed, 251 insertions, 0 deletions
diff --git a/benchmarks/mix/tasks/pleroma/benchmarks/tags.ex b/benchmarks/mix/tasks/pleroma/benchmarks/tags.ex
new file mode 100644
index 0000000..a32de2d
--- /dev/null
+++ b/benchmarks/mix/tasks/pleroma/benchmarks/tags.ex
@@ -0,0 +1,114 @@
+defmodule Mix.Tasks.Pleroma.Benchmarks.Tags do
+ use Mix.Task
+
+ import Pleroma.LoadTesting.Helper, only: [clean_tables: 0]
+ import Ecto.Query
+
+ alias Pleroma.Repo
+
+ def run(_args) do
+ Mix.Pleroma.start_pleroma()
+ activities_count = Repo.aggregate(from(a in Pleroma.Activity), :count, :id)
+
+ if activities_count == 0 do
+ IO.puts("Did not find any activities, cleaning and generating")
+ clean_tables()
+ Pleroma.LoadTesting.Users.generate_users(10)
+ Pleroma.LoadTesting.Activities.generate_tagged_activities()
+ else
+ IO.puts("Found #{activities_count} activities, won't generate new ones")
+ end
+
+ tags = Enum.map(0..20, fn i -> {"For #tag_#{i}", "tag_#{i}"} end)
+
+ Enum.each(tags, fn {_, tag} ->
+ query =
+ from(o in Pleroma.Object,
+ where: fragment("(?)->'tag' \\? (?)", o.data, ^tag)
+ )
+
+ count = Repo.aggregate(query, :count, :id)
+ IO.puts("Database contains #{count} posts tagged with #{tag}")
+ end)
+
+ user = Repo.all(Pleroma.User) |> List.first()
+
+ Benchee.run(
+ %{
+ "Hashtag fetching, any" => fn tags ->
+ hashtag_fetching(
+ %{
+ "any" => tags
+ },
+ user,
+ false
+ )
+ end,
+ # Will always return zero results because no overlapping hashtags are generated.
+ "Hashtag fetching, all" => fn tags ->
+ hashtag_fetching(
+ %{
+ "all" => tags
+ },
+ user,
+ false
+ )
+ end
+ },
+ inputs:
+ tags
+ |> Enum.map(fn {_, v} -> v end)
+ |> Enum.chunk_every(2)
+ |> Enum.map(fn tags -> {"For #{inspect(tags)}", tags} end),
+ time: 5
+ )
+
+ Benchee.run(
+ %{
+ "Hashtag fetching" => fn tag ->
+ hashtag_fetching(
+ %{
+ "tag" => tag
+ },
+ user,
+ false
+ )
+ end
+ },
+ inputs: tags,
+ time: 5
+ )
+ end
+
+ defp hashtag_fetching(params, user, local_only) do
+ tags =
+ [params["tag"], params["any"]]
+ |> List.flatten()
+ |> Enum.uniq()
+ |> Enum.filter(& &1)
+ |> Enum.map(&String.downcase(&1))
+
+ tag_all =
+ params
+ |> Map.get("all", [])
+ |> Enum.map(&String.downcase(&1))
+
+ tag_reject =
+ params
+ |> Map.get("none", [])
+ |> Enum.map(&String.downcase(&1))
+
+ _activities =
+ %{
+ type: "Create",
+ local_only: local_only,
+ blocking_user: user,
+ muting_user: user,
+ user: user,
+ tag: tags,
+ tag_all: tag_all,
+ tag_reject: tag_reject,
+ }
+ |> Pleroma.Web.ActivityPub.ActivityPub.fetch_public_activities()
+ end
+end
diff --git a/benchmarks/mix/tasks/pleroma/benchmarks/timelines.ex b/benchmarks/mix/tasks/pleroma/benchmarks/timelines.ex
new file mode 100644
index 0000000..3770ca1
--- /dev/null
+++ b/benchmarks/mix/tasks/pleroma/benchmarks/timelines.ex
@@ -0,0 +1,70 @@
+defmodule Mix.Tasks.Pleroma.Benchmarks.Timelines do
+ use Mix.Task
+
+ import Pleroma.LoadTesting.Helper, only: [clean_tables: 0]
+
+ alias Pleroma.Web.CommonAPI
+ alias Plug.Conn
+
+ def run(_args) do
+ Mix.Pleroma.start_pleroma()
+
+ # Cleaning tables
+ clean_tables()
+
+ [{:ok, user} | users] = Pleroma.LoadTesting.Users.generate_users(1000)
+
+ # Let the user make 100 posts
+
+ 1..100
+ |> Enum.each(fn i -> CommonAPI.post(user, %{status: to_string(i)}) end)
+
+ # Let 10 random users post
+ posts =
+ users
+ |> Enum.take_random(10)
+ |> Enum.map(fn {:ok, random_user} ->
+ {:ok, activity} = CommonAPI.post(random_user, %{status: "."})
+ activity
+ end)
+
+ # let our user repeat them
+ posts
+ |> Enum.each(fn activity ->
+ CommonAPI.repeat(activity.id, user)
+ end)
+
+ Benchee.run(
+ %{
+ "user timeline, no followers" => fn reading_user ->
+ conn =
+ Phoenix.ConnTest.build_conn()
+ |> Conn.assign(:user, reading_user)
+ |> Conn.assign(:skip_link_headers, true)
+
+ Pleroma.Web.MastodonAPI.AccountController.statuses(conn, %{id: user.id})
+ end
+ },
+ inputs: %{"user" => user, "no user" => nil},
+ time: 60
+ )
+
+ users
+ |> Enum.each(fn {:ok, follower} -> Pleroma.User.follow(follower, user) end)
+
+ Benchee.run(
+ %{
+ "user timeline, all following" => fn reading_user ->
+ conn =
+ Phoenix.ConnTest.build_conn()
+ |> Conn.assign(:user, reading_user)
+ |> Conn.assign(:skip_link_headers, true)
+
+ Pleroma.Web.MastodonAPI.AccountController.statuses(conn, %{id: user.id})
+ end
+ },
+ inputs: %{"user" => user, "no user" => nil},
+ time: 60
+ )
+ end
+end
diff --git a/benchmarks/mix/tasks/pleroma/load_testing.ex b/benchmarks/mix/tasks/pleroma/load_testing.ex
new file mode 100644
index 0000000..3888832
--- /dev/null
+++ b/benchmarks/mix/tasks/pleroma/load_testing.ex
@@ -0,0 +1,67 @@
+defmodule Mix.Tasks.Pleroma.LoadTesting do
+ use Mix.Task
+ import Ecto.Query
+ import Pleroma.LoadTesting.Helper, only: [clean_tables: 0]
+
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ @shortdoc "Factory for generation data"
+ @moduledoc """
+ Generates data like:
+ - local/remote users
+ - local/remote activities with differrent visibility:
+ - simple activiities
+ - with emoji
+ - with mentions
+ - hellthreads
+ - with attachments
+ - with tags
+ - likes
+ - reblogs
+ - simple threads
+ - long threads
+
+ ## Generate data
+ MIX_ENV=benchmark mix pleroma.load_testing --users 20000 --friends 1000 --iterations 170 --friends_used 20 --non_friends_used 20
+ MIX_ENV=benchmark mix pleroma.load_testing -u 20000 -f 1000 -i 170 -fu 20 -nfu 20
+
+ Options:
+ - `--users NUMBER` - number of users to generate. Defaults to: 20000. Alias: `-u`
+ - `--friends NUMBER` - number of friends for main user. Defaults to: 1000. Alias: `-f`
+ - `--iterations NUMBER` - number of iterations to generate activities. For each iteration in database is inserted about 120+ activities with different visibility, actors and types.Defaults to: 170. Alias: `-i`
+ - `--friends_used NUMBER` - number of main user friends used in activity generation. Defaults to: 20. Alias: `-fu`
+ - `--non_friends_used NUMBER` - number of non friends used in activity generation. Defaults to: 20. Alias: `-nfu`
+ """
+
+ @aliases [u: :users, f: :friends, i: :iterations, fu: :friends_used, nfu: :non_friends_used]
+ @switches [
+ users: :integer,
+ friends: :integer,
+ iterations: :integer,
+ friends_used: :integer,
+ non_friends_used: :integer
+ ]
+
+ def run(args) do
+ Logger.configure(level: :error)
+ Mix.Pleroma.start_pleroma()
+ clean_tables()
+ {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
+
+ user = Pleroma.LoadTesting.Users.generate(opts)
+ Pleroma.LoadTesting.Activities.generate(user, opts)
+
+ IO.puts("Users in DB: #{Repo.aggregate(from(u in User), :count, :id)}")
+
+ IO.puts("Activities in DB: #{Repo.aggregate(from(a in Pleroma.Activity), :count, :id)}")
+
+ IO.puts("Objects in DB: #{Repo.aggregate(from(o in Pleroma.Object), :count, :id)}")
+
+ IO.puts(
+ "Notifications in DB: #{Repo.aggregate(from(n in Pleroma.Notification), :count, :id)}"
+ )
+
+ Pleroma.LoadTesting.Fetcher.run_benchmarks(user)
+ end
+end