one more temp commit
[akkoma] / lib / mix / tasks / pleroma / load_testing.ex
1 defmodule Mix.Tasks.Pleroma.LoadTesting do
2 use Mix.Task
3 use Pleroma.LoadTesting.Helper
4 import Mix.Pleroma
5 import Pleroma.LoadTesting.Generator
6 import Pleroma.LoadTesting.Fetcher
7
8 # tODO: remove autovacuum worker until generation is not ended
9 @shortdoc "Factory for generation data"
10 @moduledoc """
11 Generates data like:
12 - users
13 - activities with notifications
14
15 ## Generate data
16 MIX_ENV=test mix pleroma.load_testing --users 10000 --activities 20000
17 MIX_ENV=test mix pleroma.load_testing -u 10000 -a 20000
18
19 Options:
20 - `--users NUMBER` - number of users to generate (default: 10000)
21 - `--activities NUMBER` - number of activities to generate (default: 20000)
22 """
23
24 @aliases [u: :users, a: :activities]
25 @switches [
26 users: :integer,
27 activities: :integer,
28 dms: :integer,
29 thread_length: :integer,
30 non_visible_posts: :integer
31 ]
32 @users_default 20_000
33 @activities_default 50_000
34 @dms_default 50_000
35 @thread_length_default 2_000
36 @non_visible_posts_default 2_000
37
38 def run(args) do
39 start_pleroma()
40 {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
41
42 users_max = Keyword.get(opts, :users, @users_default)
43 activities_max = Keyword.get(opts, :activities, @activities_default)
44 dms_max = Keyword.get(opts, :dms, @dms_default)
45 long_thread_length = Keyword.get(opts, :thread_length, @thread_length_default)
46 non_visible_posts = Keyword.get(opts, :non_visible_posts, @non_visible_posts_default)
47
48 clean_tables()
49
50 opts =
51 Keyword.put(opts, :users_max, users_max)
52 |> Keyword.put(:activities_max, activities_max)
53 |> Keyword.put(:dms_max, dms_max)
54 |> Keyword.put(:long_thread_length, long_thread_length)
55 |> Keyword.put(:non_visible_posts_max, non_visible_posts)
56
57 generate_users(opts)
58
59 # main user for queries
60 IO.puts("Fetching main user...")
61
62 {time, user} =
63 :timer.tc(fn -> Repo.one(from(u in User, order_by: fragment("RANDOM()"), limit: 1)) end)
64
65 IO.puts("Fetching main user take #{to_sec(time)} sec.\n")
66
67 IO.puts("Fetching users...")
68
69 {time, users} =
70 :timer.tc(fn ->
71 Repo.all(
72 from(u in User,
73 where: u.id != ^user.id,
74 order_by: fragment("RANDOM()"),
75 limit: 10
76 )
77 )
78 end)
79
80 IO.puts("Fetching users take #{to_sec(time)} sec.\n")
81
82 generate_activities(users, opts)
83
84 generate_activities(users, Keyword.put(opts, :mention, user))
85
86 generate_dms(user, users, opts)
87
88 {:ok, activity} = generate_long_thread(user, users, opts)
89
90 generate_private_thread(users, opts)
91
92 # generate_replies(user, users, activities)
93
94 # activity = Enum.random(activities)
95 # generate_long_thread(user, users, activity)
96
97 IO.puts("Users in DB: #{Repo.aggregate(from(u in User), :count, :id)}")
98 IO.puts("Activities in DB: #{Repo.aggregate(from(a in Activity), :count, :id)}")
99 IO.puts("Objects in DB: #{Repo.aggregate(from(o in Object), :count, :id)}")
100 IO.puts("Notifications in DB: #{Repo.aggregate(from(n in Notification), :count, :id)}")
101
102 fetch_user(user)
103 query_timelines(user)
104 query_notifications(user)
105 query_dms(user)
106 query_long_thread(user, activity)
107 query_timelines(user)
108 end
109
110 defp clean_tables do
111 IO.puts("\n\nDeleting old data...\n")
112 Ecto.Adapters.SQL.query!(Repo, "TRUNCATE users CASCADE;")
113 Ecto.Adapters.SQL.query!(Repo, "TRUNCATE activities CASCADE;")
114 Ecto.Adapters.SQL.query!(Repo, "TRUNCATE objects CASCADE;")
115 end
116 end