Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@adkron
Created November 23, 2010 01:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adkron/711070 to your computer and use it in GitHub Desktop.
Save adkron/711070 to your computer and use it in GitHub Desktop.
require 'spec_helper'
require 'benchmark'
describe 'performance tracking for accessing sitewide information' do
include Mongo
describe 'sitewide privacy settings maintained in an user info attribute collection' do
before(:all) do
db = Connection.new.db('user-acl-specs')
@users = db.collection('users')
@count_of_test_users = 10000
@created_users = @users.find().next_document
@users.create_index([["attributes.visible_sitewide", Mongo::ASCENDING], ["attributes.field_value", Mongo::ASCENDING]])
# puts @users.find({"$or" => [
# {"attributes" => {"$elemMatch" => {"field_value" => "nick1", "visible_sitewide" => true}}},
# {"nickname" => "nick1"}
# ]}).explain()
# build_test_users(db)
end
# it "do nothing" do
# end
it "search where user info and acl are stored in a collection in the user model" do
@nicknames = ["nick1", "nick2", "nick3", "nick4", "nick5", "nick6", "nick7", "nick8", "nick9", "nick10"]
Benchmark.bmbm do |label|
label.report('finding a user where the search term is the exact email') do
(1..10).each do
@nicknames.each do |a_nickname|
search_string = "#{a_nickname}@email.com"
# search_string = #{@available_attributes[index][:nickname]}@email.com
@users.find('attributes' => {'$elemMatch' => {'field_name' => 'email', 'field_value' => "#{search_string}", 'visible_sitewide' => true}}).next_document
end
end
end
label.report('finding a user where the search term is partial email') do
(1..10).each do
@nicknames.each do |a_nickname|
@users.find('attributes' => {'$elemMatch' => {'field_name' => 'email', 'field_value' => /#{a_nickname}/i, 'visible_sitewide' => true}}).next_document
end
end
end
label.report('using a search term that searches across email, first name, last name & nickname visible sitewide') do
(1..10).each do
@nicknames.each do |a_nickname|
@users.find({"$or" => [
{"attributes" => {"$elemMatch" => {"field_name" => "email", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"attributes" => {"$elemMatch" => {"field_name" => "first_name", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"attributes" => {"$elemMatch" => {"field_name" => "last_name", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"nickname" => /#{a_nickname}/i}
]}).next_document
end
end
end
label.report('using a search term that searches all fields visible sitewide') do
10.times do
@nicknames.each do |a_nickname|
@users.find({"$or" => [
{"attributes" => {"$elemMatch" => {"field_value" => a_nickname, "visible_sitewide" => true}}},
{"nickname" => a_nickname}, {'attributes.connections_visible_to' =>- 0}
]}).next_document
end
end
end
label.report('using a search term that searches across email, first name, last name & nickname visible sitewide and user specific access') do
# (1..10).each do
@nicknames.each do |a_nickname|
@users.find({"$or" => [
{"attributes" => {"$elemMatch" => {"field_name" => "email", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"attributes" => {"$elemMatch" => {"field_name" => "first_name", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"attributes" => {"$elemMatch" => {"field_name" => "last_name", "field_value" => /#{a_nickname}/i, "visible_sitewide" => true}}},
{"attributes" => {"$elemMatch" => {"field_name" => "email", "field_value" => /#{a_nickname}/i, "connections_visible_to" => {"$in" => [random_user_id]}}}},
{"attributes" => {"$elemMatch" => {"field_name" => "first_name", "field_value" => /#{a_nickname}/i, "connections_visible_to" => {"$in" => [random_user_id]}}}},
{"attributes" => {"$elemMatch" => {"field_name" => "last_name", "field_value" => /#{a_nickname}/i, "connections_visible_to" => {"$in" => [random_user_id]}}}},
{"nickname" => /#{a_nickname}/i}
]}).next_document
end
# end
end
label.report('using a search term that searches across all fields visible sitewide and user specific access') do
(1..10).each do
@nicknames.each do |a_nickname|
@users.find({"$or" => [
{"attributes" => {"$elemMatch" => {"field_value" => /#{a_nickname}/i, "connections_visible_to" => {"$in" => [random_user_id]}}}},
{"nickname" => /#{a_nickname}/i}
]}).next_document
end
end
end
label.report('load a user with all its field') do
(1..5).each do |index|
@users.find_one(:nickname => "nick#{index}")
end
end
end
end
# after(:all) do
# @users.drop
# end
end
def build_test_users(db)
@users.drop
@users.create_index([["attributes.field_name", Mongo::ASCENDING]])
@users.create_index([["attributes.visible_sitewide", Mongo::ASCENDING], []])
@users.create_index([["attributes.connections_visible_to", Mongo::ASCENDING]])
@connection_groups = db.collection('connection_groups')
@connection_groups.drop
@count_of_test_users = 10000
@available_attributes = []
(1..@count_of_test_users).each do |i|
attributes_for_user = {
:nickname => "nick#{i}"
}
@users.save attributes_for_user
@available_attributes << attributes_for_user
end
@created_users = []
@users.find().each do |row|
@created_users << row
end
update_fields_for_all_users
end
def update_fields_for_all_users
@created_users.each do |a_user|
# This approach has the connection groups in a separate collection which will be used to identify which fields a member gets access to when he/she is added to an existing connection group.
connections = create_connections(a_user)
@users.update({:nickname => a_user['nickname']},
{"$set" => {:attributes =>[
{:field_name => "first_name", :field_value => a_user['nickname'], :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "middle_initial", :field_value => middle_initial, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "last_name", :field_value => last_name, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "dob_day", :field_value => dob_day, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "dob_month", :field_value => dob_month, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "dob_year", :field_value => dob_year, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "gender", :field_value => gender, :visible_sitewide => random_boolean_value, :connections_visible_to => random_user_ids(50)},
{:field_name => "email", :field_value => email_value(a_user['nickname']), :visible_sitewide => true, :connections_visible_to => random_user_ids(50)}
]}}
)
end
end
def create_connections(a_user)
user_connections = []
user_connections << create_connection_group(a_user['_id'], "Doctors", 10)
user_connections << create_connection_group(a_user['_id'], "Family", 20)
user_connections << create_connection_group(a_user['_id'], "Friends", 30)
end
def create_connection_group(group_owner_id, group_name, group_member_count=1)
{
:group_owner_id => group_owner_id,
:group_name => group_name,
:group_members => random_user_ids(group_member_count),
:visible_fields => ["first_name", "last_name", "email"]
}
end
def random_user_ids(count)
(1..count).collect do
@created_users.rand['_id']
end
end
def dob_day
Random.new.rand(1..31)
end
def dob_month
Random.new.rand(1..12)
end
def dob_year
Random.new.rand(1950..2000)
end
def zip_code
Random.new.rand(10000..90000)
end
def last_name
random_string(Random.new.rand(1..25))
end
def middle_initial
random_string(1)
end
def email_value(nickname)
"#{nickname}@email.com"
end
def gender
random_boolean_value ? 'female' : 'male'
end
def random_boolean_value
Random.new.rand(1..2) == 1 ? true : false
end
def random_string(length=20)
(0...length).map { ('a'..'z').to_a[rand(26)] }.join
end
def random_user_id
@users.find_one(:nickname => "nick#{random_user_offset}")['_id']
end
def random_user_offset
Random.new.rand(1..@count_of_test_users)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment