diff --git a/spec/factories.rb b/spec/factories.rb index cd5a4bc30..0c246e7c1 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -249,6 +249,15 @@ FactoryGirl.define do association(:post, factory: :status_message) end + factory :signed_comment, parent: :comment do + association(:parent, factory: :status_message) + + after(:build) do |comment| + order = SignatureOrder.first || FactoryGirl.create(:signature_order) + comment.signature = FactoryGirl.build(:comment_signature, comment: comment, signature_order: order) + end + end + factory(:notification, class: Notifications::AlsoCommented) do association :recipient, :factory => :user association :target, :factory => :comment diff --git a/spec/integration/export/memory_usage_spec.rb b/spec/integration/export/memory_usage_spec.rb new file mode 100644 index 000000000..9036796ee --- /dev/null +++ b/spec/integration/export/memory_usage_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# Memory usage methods are from: https://gist.github.com/pvdb/6240788 + +# returns detailed information about the process memory usage (as recorded in the "/proc/$$/statm" proc fs file) +def Process.statm + Hash[%i[size resident shared trs lrs drs dt].zip(open("/proc/#{Process.pid}/statm").read.split)] +end + +# the real memory (resident set) size of the process (in 1_024 byte units, assuming a 4kB memory page size) +def Process.rss + Process.statm[:resident].to_i * 4 +end + +describe Diaspora::Exporter do + context "on big profiles", :performance do + before :all do + if Post.count < 1000 + # Force fixture rebuild + FileUtils.rm_f(Rails.root.join("tmp", "fixture_builder.yml")) + end + + FixtureBuilder.configure do |fbuilder| + # rebuild fixtures automatically when these files change: + fbuilder.files_to_check += Dir[ + "app/models/*.rb", "lib/**/*.rb", "spec/factories/*.rb", "spec/support/fixture_builder.rb" + ] - ["lib/diaspora/exporter.rb"] + + # now declare objects + fbuilder.factory do + create_basic_users + + 1000.times { + FactoryGirl.create(:signed_comment, post: bob.person.posts.first) + FactoryGirl.create(:status_message, author: bob.person) + FactoryGirl.create(:comment, author: bob.person) + FactoryGirl.create(:contact, user: bob) + FactoryGirl.create(:participation, author: bob.person) + } + end + end + end + + it "doesn't exceed sensible memory usage limit" do + json = Diaspora::Exporter.new(bob).execute + expect(json).not_to be_empty + expect(Process.rss).to be < 500 * 1024 + puts "Process resident set size: #{Process.rss}" + end + end +end diff --git a/spec/support/fixture_builder.rb b/spec/support/fixture_builder.rb index b88c24953..242ebb03b 100644 --- a/spec/support/fixture_builder.rb +++ b/spec/support/fixture_builder.rb @@ -1,47 +1,49 @@ # frozen_string_literal: true -FixtureBuilder.configure do |fbuilder| +def create_basic_users + # Users + alice = FactoryGirl.create(:user_with_aspect, username: "alice", strip_exif: false) + alices_aspect = alice.aspects.where(name: "generic").first + eve = FactoryGirl.create(:user_with_aspect, username: "eve") + eves_aspect = eve.aspects.where(name: "generic").first + + bob = FactoryGirl.create(:user_with_aspect, username: "bob") + bobs_aspect = bob.aspects.where(name: "generic").first + FactoryGirl.create(:aspect, name: "empty", user: bob) + + connect_users(bob, bobs_aspect, alice, alices_aspect) + connect_users(bob, bobs_aspect, eve, eves_aspect) + + # Set up friends - 2 local, 1 remote + local_luke = FactoryGirl.create(:user_with_aspect, username: "luke") + lukes_aspect = local_luke.aspects.where(name: "generic").first + + local_leia = FactoryGirl.create(:user_with_aspect, username: "leia") + leias_aspect = local_leia.aspects.where(name: "generic").first + + remote_raphael = FactoryGirl.create(:person, diaspora_handle: "raphael@remote.net") + + connect_users_with_aspects(local_luke, local_leia) + + local_leia.contacts.create(person: remote_raphael, aspects: [leias_aspect]) + local_luke.contacts.create(person: remote_raphael, aspects: [lukes_aspect]) + + # Set up a follower + peter = FactoryGirl.create(:user_with_aspect, username: "peter") + peters_aspect = peter.aspects.where(name: "generic").first + + peter.contacts.create!(person: alice.person, aspects: [peters_aspect], sharing: false, receiving: true) +end + +FixtureBuilder.configure do |fbuilder| # rebuild fixtures automatically when these files change: - fbuilder.files_to_check += Dir["app/models/*.rb", "lib/**/*.rb", "spec/factories/*.rb", "spec/support/fixture_builder.rb"] + fbuilder.files_to_check += Dir[ + "app/models/*.rb", "lib/**/*.rb", "spec/factories/*.rb", "spec/support/fixture_builder.rb" + ] - ["lib/diaspora/exporter.rb"] # now declare objects fbuilder.factory do - # Users - alice = FactoryGirl.create(:user_with_aspect, :username => "alice", :strip_exif => false) - alices_aspect = alice.aspects.where(:name => "generic").first - - eve = FactoryGirl.create(:user_with_aspect, :username => "eve") - eves_aspect = eve.aspects.where(:name => "generic").first - - bob = FactoryGirl.create(:user_with_aspect, :username => "bob") - bobs_aspect = bob.aspects.where(:name => "generic").first - FactoryGirl.create(:aspect, :name => "empty", :user => bob) - - connect_users(bob, bobs_aspect, alice, alices_aspect) - connect_users(bob, bobs_aspect, eve, eves_aspect) - - # Set up friends - 2 local, 1 remote - local_luke = FactoryGirl.create(:user_with_aspect, :username => "luke") - lukes_aspect = local_luke.aspects.where(:name => "generic").first - - local_leia = FactoryGirl.create(:user_with_aspect, :username => "leia") - leias_aspect = local_leia.aspects.where(:name => "generic").first - - remote_raphael = FactoryGirl.create(:person, :diaspora_handle => "raphael@remote.net") - - connect_users_with_aspects(local_luke, local_leia) - - local_leia.contacts.create(:person => remote_raphael, :aspects => [leias_aspect]) - local_luke.contacts.create(:person => remote_raphael, :aspects => [lukes_aspect]) - - # Set up a follower - peter = FactoryGirl.create(:user_with_aspect, :username => "peter") - peters_aspect = peter.aspects.where(:name => "generic").first - - peter.contacts.create!(:person => alice.person, - :aspects => [peters_aspect], - :sharing => false, - :receiving => true) - end + create_basic_users + end end