summaryrefslogtreecommitdiff
path: root/benchmarks/mix/tasks/pleroma/load_testing.ex
blob: 0a751adac02ab3a9088382ca6f8d7c899208ae50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
defmodule Mix.Tasks.Pleroma.LoadTesting do
  use Mix.Task
  use Pleroma.LoadTesting.Helper
  import Mix.Pleroma
  import Pleroma.LoadTesting.Generator
  import Pleroma.LoadTesting.Fetcher

  @shortdoc "Factory for generation data"
  @moduledoc """
  Generates data like:
  - local/remote users
  - local/remote activities with notifications
  - direct messages
  - long thread
  - non visible posts

  ## Generate data
      MIX_ENV=benchmark mix pleroma.load_testing --users 20000 --dms 20000 --thread_length 2000
      MIX_ENV=benchmark mix pleroma.load_testing -u 20000 -d 20000 -t 2000

  Options:
  - `--users NUMBER` - number of users to generate. Defaults to: 20000. Alias: `-u`
  - `--dms NUMBER` - number of direct messages to generate. Defaults to: 20000. Alias `-d`
  - `--thread_length` - number of messages in thread. Defaults to: 2000. ALias `-t`
  """

  @aliases [u: :users, d: :dms, t: :thread_length]
  @switches [
    users: :integer,
    dms: :integer,
    thread_length: :integer
  ]
  @users_default 20_000
  @dms_default 1_000
  @thread_length_default 2_000

  def run(args) do
    start_pleroma()
    Pleroma.Config.put([:instance, :skip_thread_containment], true)
    {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)

    users_max = Keyword.get(opts, :users, @users_default)
    dms_max = Keyword.get(opts, :dms, @dms_default)
    thread_length = Keyword.get(opts, :thread_length, @thread_length_default)

    clean_tables()

    opts =
      Keyword.put(opts, :users_max, users_max)
      |> Keyword.put(:dms_max, dms_max)
      |> Keyword.put(:thread_length, thread_length)

    generate_users(opts)

    # main user for queries
    IO.puts("Fetching local main user...")

    {time, user} =
      :timer.tc(fn ->
        Repo.one(
          from(u in User, where: u.local == true, order_by: fragment("RANDOM()"), limit: 1)
        )
      end)

    IO.puts("Fetching main user take #{to_sec(time)} sec.\n")

    IO.puts("Fetching local users...")

    {time, users} =
      :timer.tc(fn ->
        Repo.all(
          from(u in User,
            where: u.id != ^user.id,
            where: u.local == true,
            order_by: fragment("RANDOM()"),
            limit: 10
          )
        )
      end)

    IO.puts("Fetching local users take #{to_sec(time)} sec.\n")

    IO.puts("Fetching remote users...")

    {time, remote_users} =
      :timer.tc(fn ->
        Repo.all(
          from(u in User,
            where: u.id != ^user.id,
            where: u.local == false,
            order_by: fragment("RANDOM()"),
            limit: 10
          )
        )
      end)

    IO.puts("Fetching remote users take #{to_sec(time)} sec.\n")

    generate_activities(user, users)

    generate_remote_activities(user, remote_users)

    generate_like_activities(
      user, Pleroma.Repo.all(Pleroma.Activity.Queries.by_type("Create"))
    )

    generate_dms(user, users, opts)

    {:ok, activity} = generate_long_thread(user, users, opts)

    generate_non_visible_message(user, users)

    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)}"
    )

    fetch_user(user)
    query_timelines(user)
    query_notifications(user)
    query_dms(user)
    query_long_thread(user, activity)
    Pleroma.Config.put([:instance, :skip_thread_containment], false)
    query_timelines(user)
  end

  defp clean_tables do
    IO.puts("Deleting 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