discourse/script/profile_db_generator.rb
Alan Guo Xiang Tan 0da79561c3
DEV: Improve/Fix script/bench.rb (#19646)
1. Fix bug where we were not waiting for all unicorn workers to start up
before running benchmarks.

2. Fix a bug where headers were not used when benchmarking. Admin
benchmarks were basically running as anon user.

3. Disable rate limits when in profile env. We're pretty much going to
hit the rate limit every time as a normal user.

4. Benchmark against topic with a fixed posts count of 100. Previously profiling script was just randomly creating posts
and we would benchmark against a topic with a fixed posts count of 30.
Sometimes, the script fails because no topics with a posts count of 30
exists.

5. Benchmarks are not run against a normal user on top of anon and
admin.

6. Add script option to select tests that should be run.
2022-12-30 07:25:11 +08:00

141 lines
3.1 KiB
Ruby

# frozen_string_literal: true
# can be used to generate a mock db for profiling purposes
# we want our script to generate a consistent output, to do so
# we monkey patch array sample so it always uses the same rng
class Array
RNG = Random.new(1098109928029800)
def sample
self[RNG.rand(size)]
end
end
# based on https://gist.github.com/zaius/2643079
def unbundled_require(gem)
if defined?(::Bundler)
spec_path = Dir.glob("#{Gem.dir}/specifications/#{gem}-*.gemspec").last
if spec_path.nil?
raise LoadError
end
spec = Gem::Specification.load spec_path
spec.activate
end
begin
require gem
end
end
def sentence
@gabbler ||= Gabbler.new.tap do |gabbler|
story = File.read(File.dirname(__FILE__) + "/alice.txt")
gabbler.learn(story)
end
sentence = +""
until sentence.length > 800 do
sentence << @gabbler.sentence
sentence << "\n"
end
sentence
end
def create_user(seq, admin: false, username: nil)
User.new.tap do |user|
user.email = "user@localhost#{seq}.fake"
user.username = username || "user#{seq}"
user.password = "password12345abc"
user.save!
if admin
user.grant_admin!
user.change_trust_level!(TrustLevel[4])
end
user.activate
end
end
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
Jobs.run_immediately!
unless Rails.env == "profile"
puts "This script should only be used in the profile environment"
exit
end
# by default, Discourse has a "system" and `discobot` account
if User.count > 2
puts "Only run this script against an empty DB"
exit
end
require 'optparse'
begin
unbundled_require 'gabbler'
rescue LoadError
puts "installing gabbler gem"
puts `gem install gabbler`
unbundled_require 'gabbler'
end
number_of_users = 100
puts "Creating #{number_of_users} users"
number_of_users.times.map do |i|
putc "."
create_user(i)
end
puts
puts "Creating 1 admin user"
admin_user = create_user(number_of_users + 1, admin: true, username: "admin1")
users = User.human_users.all
puts
puts "Creating 10 categories"
categories = 10.times.map do |i|
putc "."
Category.create(name: "category#{i}", text_color: "ffffff", color: "000000", user: admin_user)
end
puts
puts "Creating 100 topics"
topic_ids = 100.times.map do
post = PostCreator.create(admin_user, raw: sentence, title: sentence[0..50].strip, category: categories.sample.id, skip_validations: true)
putc "."
post.topic_id
end
puts
puts "Creating 2000 replies"
2000.times do
putc "."
PostCreator.create(users.sample, raw: sentence, topic_id: topic_ids.sample, skip_validations: true)
end
puts
puts "creating perf test topic"
first_post = PostCreator.create(
users.sample,
raw: sentence,
title: "I am a topic used for perf tests",
category: categories.sample.id,
skip_validations: true
)
puts
puts "Creating 100 replies for perf test topic"
100.times do
putc "."
PostCreator.create(users.sample, raw: sentence, topic_id: first_post.topic_id, skip_validations: true)
end
# no sidekiq so update some stuff
Category.update_stats
Jobs::PeriodicalUpdates.new.execute(nil)