pleroma/lib/load_testing/generator.ex

259 lines
6.4 KiB
Elixir
Raw Normal View History

2019-08-02 20:33:12 +02:00
defmodule Pleroma.LoadTesting.Generator do
use Pleroma.LoadTesting.Helper
2019-09-05 15:01:52 +02:00
alias Pleroma.Web.CommonAPI
2019-08-02 20:33:12 +02:00
def generate_users(opts) do
IO.puts("Starting generating #{opts[:users_max]} users...")
{time, _} = :timer.tc(fn -> do_generate_users(opts) end)
2019-09-05 15:01:52 +02:00
2019-08-02 20:33:12 +02:00
IO.puts("Inserting users take #{to_sec(time)} sec.\n")
end
defp do_generate_users(opts) do
max = Keyword.get(opts, :users_max)
2019-09-04 19:18:11 +02:00
Task.async_stream(
1..max,
&generate_user_data(&1),
max_concurrency: 10,
timeout: 30_000
)
|> Enum.to_list()
2019-08-02 20:33:12 +02:00
end
defp generate_user_data(i) do
user = %User{
name: "Test テスト User #{i}",
email: "user#{i}@example.com",
nickname: "nick#{i}",
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "Tester Number #{i}",
2019-09-06 15:37:18 +02:00
info: %{},
local: Enum.random([true, false])
2019-08-02 20:33:12 +02:00
}
user = %{
user
| ap_id: User.ap_id(user),
follower_address: User.ap_followers(user),
following_address: User.ap_following(user),
following: [User.ap_id(user)]
}
2019-09-05 15:01:52 +02:00
Repo.insert!(user)
2019-08-02 20:33:12 +02:00
end
2019-09-05 15:01:52 +02:00
def generate_activities(user, users) do
do_generate_activities(user, users)
2019-08-02 20:33:12 +02:00
end
2019-09-05 15:01:52 +02:00
defp do_generate_activities(user, users) do
IO.puts("Starting generating 20000 common activities...")
{time, _} =
:timer.tc(fn ->
Task.async_stream(
1..20_000,
fn _ ->
do_generate_activity([user | users])
end,
max_concurrency: 10,
timeout: 30_000
)
|> Stream.run()
end)
IO.puts("Inserting common activities take #{to_sec(time)} sec.\n")
IO.puts("Starting generating 20000 activities with mentions...")
{time, _} =
:timer.tc(fn ->
Task.async_stream(
1..20_000,
fn _ ->
do_generate_activity_with_mention(user, users)
end,
max_concurrency: 10,
timeout: 30_000
)
|> Stream.run()
end)
IO.puts("Inserting activities with menthions take #{to_sec(time)} sec.\n")
IO.puts("Starting generating 10000 activities with threads...")
{time, _} =
:timer.tc(fn ->
Task.async_stream(
1..10_000,
fn _ ->
do_generate_threads([user | users])
end,
max_concurrency: 10,
timeout: 30_000
)
|> Stream.run()
end)
IO.puts("Inserting activities with threads take #{to_sec(time)} sec.\n")
end
defp do_generate_activity(users) do
post = %{
"status" => "Some status without mention with random user"
}
CommonAPI.post(Enum.random(users), post)
end
defp do_generate_activity_with_mention(user, users) do
mentions_cnt = Enum.random([2, 3, 4, 5])
with_user = Enum.random([true, false])
users = Enum.shuffle(users)
mentions_users = Enum.take(users, mentions_cnt)
mentions_users = if with_user, do: [user | mentions_users], else: mentions_users
mentions_str =
Enum.map(mentions_users, fn user -> "@" <> user.nickname end) |> Enum.join(", ")
post = %{
"status" => mentions_str <> "some status with mentions random users"
}
CommonAPI.post(Enum.random(users), post)
2019-08-02 20:33:12 +02:00
end
2019-09-05 15:01:52 +02:00
defp do_generate_threads(users) do
thread_length = Enum.random([2, 3, 4, 5])
actor = Enum.random(users)
post = %{
"status" => "Start of the thread"
}
{:ok, activity} = CommonAPI.post(actor, post)
Enum.each(1..thread_length, fn _ ->
user = Enum.random(users)
post = %{
"status" => "@#{actor.nickname} reply to thread",
"in_reply_to_status_id" => activity.id
}
2019-08-02 20:33:12 +02:00
2019-09-05 15:01:52 +02:00
CommonAPI.post(user, post)
end)
2019-08-02 20:33:12 +02:00
end
2019-09-04 19:18:11 +02:00
def generate_dms(user, users, opts) do
IO.puts("Starting generating #{opts[:dms_max]} DMs")
{time, _} = :timer.tc(fn -> do_generate_dms(user, users, opts) end)
IO.puts("Inserting dms take #{to_sec(time)} sec.\n")
end
defp do_generate_dms(user, users, opts) do
Task.async_stream(
1..opts[:dms_max],
fn _ ->
do_generate_dm(user, users)
end,
max_concurrency: 10,
timeout: 30_000
)
|> Stream.run()
end
defp do_generate_dm(user, users) do
post = %{
"status" => "@#{user.nickname} some direct message",
"visibility" => "direct"
}
2019-09-05 15:01:52 +02:00
CommonAPI.post(Enum.random(users), post)
2019-09-04 19:18:11 +02:00
end
def generate_long_thread(user, users, opts) do
2019-09-05 15:01:52 +02:00
IO.puts("Starting generating long thread with #{opts[:thread_length]} replies")
2019-09-04 19:18:11 +02:00
{time, activity} = :timer.tc(fn -> do_generate_long_thread(user, users, opts) end)
IO.puts("Inserting long thread replies take #{to_sec(time)} sec.\n")
{:ok, activity}
end
defp do_generate_long_thread(user, users, opts) do
2019-09-05 15:01:52 +02:00
{:ok, %{id: id} = activity} = CommonAPI.post(user, %{"status" => "Start of long thread"})
2019-09-04 19:18:11 +02:00
Task.async_stream(
2019-09-05 15:01:52 +02:00
1..opts[:thread_length],
2019-09-04 19:18:11 +02:00
fn _ -> do_generate_thread(users, id) end,
max_concurrency: 10,
timeout: 30_000
)
|> Stream.run()
activity
end
defp do_generate_thread(users, activity_id) do
2019-09-05 15:01:52 +02:00
CommonAPI.post(Enum.random(users), %{
2019-09-04 19:18:11 +02:00
"status" => "reply to main post",
"in_reply_to_status_id" => activity_id
})
end
2019-09-05 15:01:52 +02:00
def generate_non_visible_message(user, users) do
IO.puts("Starting generating 1000 non visible posts")
2019-09-04 19:18:11 +02:00
2019-09-05 15:01:52 +02:00
{time, _} =
:timer.tc(fn ->
do_generate_non_visible_posts(user, users)
end)
2019-09-04 19:18:11 +02:00
2019-09-05 15:01:52 +02:00
IO.puts("Inserting non visible posts take #{to_sec(time)} sec.\n")
end
2019-09-04 19:18:11 +02:00
2019-09-05 15:01:52 +02:00
defp do_generate_non_visible_posts(user, users) do
[not_friend | users] = users
2019-09-04 19:18:11 +02:00
2019-09-05 15:01:52 +02:00
make_friends(user, users)
Task.async_stream(1..1000, fn _ -> do_generate_non_visible_post(not_friend, users) end,
2019-09-04 19:18:11 +02:00
max_concurrency: 10,
timeout: 30_000
)
2019-09-05 15:01:52 +02:00
|> Stream.run()
2019-09-04 19:18:11 +02:00
end
2019-09-05 15:01:52 +02:00
defp make_friends(_user, []), do: nil
2019-09-04 19:18:11 +02:00
2019-09-05 15:01:52 +02:00
defp make_friends(user, [friend | users]) do
{:ok, _} = User.follow(user, friend)
{:ok, _} = User.follow(friend, user)
make_friends(user, users)
end
defp do_generate_non_visible_post(not_friend, users) do
post = %{
"status" => "some non visible post",
"visibility" => "private"
}
{:ok, activity} = CommonAPI.post(not_friend, post)
thread_length = Enum.random([2, 3, 4, 5])
Enum.each(1..thread_length, fn _ ->
user = Enum.random(users)
post = %{
"status" => "@#{not_friend.nickname} reply to non visible post",
"in_reply_to_status_id" => activity.id,
"visibility" => "private"
}
CommonAPI.post(user, post)
end)
2019-09-04 19:18:11 +02:00
end
2019-08-02 20:33:12 +02:00
end