Created
November 23, 2010 01:18
-
-
Save adkron/711070 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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