2019-08-02 20:33:12 +02:00
|
|
|
defmodule Mix.Tasks.Pleroma.LoadTesting do
|
|
|
|
use Mix.Task
|
|
|
|
use Pleroma.LoadTesting.Helper
|
|
|
|
import Mix.Pleroma
|
|
|
|
import Pleroma.LoadTesting.Generator
|
|
|
|
import Pleroma.LoadTesting.Fetcher
|
|
|
|
|
|
|
|
# tODO: remove autovacuum worker until generation is not ended
|
|
|
|
@shortdoc "Factory for generation data"
|
|
|
|
@moduledoc """
|
|
|
|
Generates data like:
|
|
|
|
- users
|
|
|
|
- activities with notifications
|
|
|
|
|
|
|
|
## Generate data
|
2019-09-05 15:01:52 +02:00
|
|
|
MIX_ENV=benchmark mix pleroma.load_testing --users 10000
|
|
|
|
MIX_ENV=benchmark mix pleroma.load_testing -u 10000
|
2019-08-02 20:33:12 +02:00
|
|
|
|
|
|
|
Options:
|
|
|
|
- `--users NUMBER` - number of users to generate (default: 10000)
|
|
|
|
"""
|
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
@aliases [u: :users, d: :dms, t: :thread_length]
|
2019-09-04 19:18:11 +02:00
|
|
|
@switches [
|
|
|
|
users: :integer,
|
|
|
|
dms: :integer,
|
2019-09-05 15:01:52 +02:00
|
|
|
thread_length: :integer
|
2019-09-04 19:18:11 +02:00
|
|
|
]
|
2019-08-02 20:33:12 +02:00
|
|
|
@users_default 20_000
|
2019-09-05 15:01:52 +02:00
|
|
|
@dms_default 20_000
|
2019-09-04 19:18:11 +02:00
|
|
|
@thread_length_default 2_000
|
2019-08-02 20:33:12 +02:00
|
|
|
|
|
|
|
def run(args) do
|
|
|
|
start_pleroma()
|
2019-09-04 19:18:11 +02:00
|
|
|
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-04 19:18:11 +02:00
|
|
|
users_max = Keyword.get(opts, :users, @users_default)
|
|
|
|
dms_max = Keyword.get(opts, :dms, @dms_default)
|
2019-09-05 15:01:52 +02:00
|
|
|
thread_length = Keyword.get(opts, :thread_length, @thread_length_default)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-04 19:18:11 +02:00
|
|
|
clean_tables()
|
2019-08-02 20:33:12 +02:00
|
|
|
|
|
|
|
opts =
|
2019-09-04 19:18:11 +02:00
|
|
|
Keyword.put(opts, :users_max, users_max)
|
|
|
|
|> Keyword.put(:dms_max, dms_max)
|
2019-09-05 15:01:52 +02:00
|
|
|
|> Keyword.put(:thread_length, thread_length)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
|
|
|
generate_users(opts)
|
|
|
|
|
|
|
|
# main user for queries
|
|
|
|
IO.puts("Fetching main user...")
|
|
|
|
|
|
|
|
{time, user} =
|
2019-09-05 15:01:52 +02:00
|
|
|
:timer.tc(fn ->
|
|
|
|
Repo.one(from(u in User, order_by: fragment("RANDOM()"), limit: 1))
|
|
|
|
end)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
|
|
|
IO.puts("Fetching main user take #{to_sec(time)} sec.\n")
|
|
|
|
|
|
|
|
IO.puts("Fetching users...")
|
|
|
|
|
|
|
|
{time, users} =
|
|
|
|
:timer.tc(fn ->
|
|
|
|
Repo.all(
|
|
|
|
from(u in User,
|
|
|
|
where: u.id != ^user.id,
|
|
|
|
order_by: fragment("RANDOM()"),
|
|
|
|
limit: 10
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end)
|
|
|
|
|
|
|
|
IO.puts("Fetching users take #{to_sec(time)} sec.\n")
|
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
generate_activities(user, users)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-04 19:18:11 +02:00
|
|
|
generate_dms(user, users, opts)
|
|
|
|
|
|
|
|
{:ok, activity} = generate_long_thread(user, users, opts)
|
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
generate_non_visible_message(user, users)
|
2019-09-04 19:18:11 +02:00
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
IO.puts("Users in DB: #{Repo.aggregate(from(u in User), :count, :id)}")
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
IO.puts("Activities in DB: #{Repo.aggregate(from(a in Pleroma.Activity), :count, :id)}")
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-05 15:01:52 +02:00
|
|
|
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)}"
|
|
|
|
)
|
2019-08-02 20:33:12 +02:00
|
|
|
|
2019-09-04 19:18:11 +02:00
|
|
|
fetch_user(user)
|
2019-08-02 20:33:12 +02:00
|
|
|
query_timelines(user)
|
|
|
|
query_notifications(user)
|
2019-09-04 19:18:11 +02:00
|
|
|
query_dms(user)
|
|
|
|
query_long_thread(user, activity)
|
|
|
|
query_timelines(user)
|
2019-08-02 20:33:12 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
defp clean_tables do
|
|
|
|
IO.puts("\n\nDeleting old data...\n")
|
|
|
|
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE users CASCADE;")
|
|
|
|
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE activities CASCADE;")
|
|
|
|
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE objects CASCADE;")
|
|
|
|
end
|
|
|
|
end
|