Example #1
0
def test_no_re_matches(minimal_database):
    pref_1 = SubscriptionDateTime(
        datetime=datetime.now() -
        timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1]).put()
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription).put()
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.get().datetime)
    meeting_spec.put()

    users = []
    num_users = 20
    for i in range(0, num_users):
        user = User(email='{}@yelp.com'.format(i),
                    metadata={'department': 'dept{}'.format(i)},
                    subscription_preferences=[user_pref])
        user.put()
        MeetingRequest(user=user.key, meeting_spec=meeting_spec.key).put()
        users.append(user)

    previous_meetings = {
        pair
        for pair in itertools.combinations([user.key.id()
                                            for user in users], 2)
    }
    previous_meetings = previous_meetings - {
        (users[0].key.id(), users[1].key.id())
    }
    matches, unmatched = generate_meetings(users, meeting_spec,
                                           previous_meetings)
    assert len(unmatched) == num_users - 2
    assert [(match[0].key.id(), match[1].key.id())
            for match in matches] == [(users[0].key.id(), users[1].key.id())]
Example #2
0
def test_generate_save_meetings(minimal_database, subscription):
    pref_1 = SubscriptionDateTime(
        datetime=datetime.now() -
        timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1]).put()
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription).put()
    user1 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept'
                 },
                 subscription_preferences=[user_pref]).put()
    user2 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept2'
                 },
                 subscription_preferences=[user_pref]).put()
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.get().datetime)
    meeting_spec.put()
    MeetingRequest(user=user1, meeting_spec=meeting_spec.key).put()
    MeetingRequest(user=user2, meeting_spec=meeting_spec.key).put()

    matches, unmatched = generate_meetings(
        [user1.get(), user2.get()], meeting_spec)
    save_meetings(matches, meeting_spec)

    assert unmatched == []

    participants = [
        participant.user for participant in MeetingParticipant.query().fetch()
    ]

    assert participants == [user1, user2]
Example #3
0
def test_generate_group_meetings():
    pref_1 = SubscriptionDateTime(
        datetime=datetime.now() -
        timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1]).put()
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription).put()
    user1 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept'
                 },
                 subscription_preferences=[user_pref]).put()
    user2 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept2'
                 },
                 subscription_preferences=[user_pref]).put()
    user3 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept3'
                 },
                 subscription_preferences=[user_pref]).put()
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.get().datetime).put()
    meeting = Meeting(meeting_spec=meeting_spec, cancelled=False).put()
    MeetingParticipant(meeting=meeting, user=user3).put()
    MeetingParticipant(meeting=meeting, user=user2).put()
    MeetingParticipant(meeting=meeting, user=user1).put()

    matched, unmatched = generate_group_meetings(
        [user1.get(), user2.get(), user3.get()], meeting_spec.get(), 3, 10, 5)
    assert {user.key for user in matched[0]} == {user1, user2, user3}
    assert unmatched == []
Example #4
0
def test_generate_meeting_specs(database):
    # delete current specs
    keys = [key for key in MeetingSpec.query().iter(keys_only=True)]
    ndb.delete_multi(keys)
    meeting_specs = MeetingSpec.query().fetch()
    assert len(meeting_specs) == 0

    # ensure we create new specs
    generate_meeting_specs()
    meeting_specs = MeetingSpec.query().fetch()
    assert len(meeting_specs) == 2
Example #5
0
def test_generate_group_meetings(session):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1])
    user_pref = UserSubscriptionPreferences(preference=pref_1, subscription=subscription)
    user1 = User(email='*****@*****.**', meta_data={'department': 'dept'}, subscription_preferences=[user_pref])
    user2 = User(email='*****@*****.**', meta_data={'department': 'dept2'}, subscription_preferences=[user_pref])
    user3 = User(email='*****@*****.**', meta_data={'department': 'dept3'}, subscription_preferences=[user_pref])
    meeting_spec = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.datetime)
    meeting = Meeting(meeting_spec=meeting_spec, cancelled=False)
    mp1 = MeetingParticipant(meeting=meeting, user=user3)
    mp2 = MeetingParticipant(meeting=meeting, user=user2)
    mp3 = MeetingParticipant(meeting=meeting, user=user1)

    session.add(pref_1)
    session.add(subscription)
    session.add(user_pref)
    session.add(user1)
    session.add(user2)
    session.add(user3)
    session.add(meeting_spec)
    session.add(meeting)
    session.add(mp1)
    session.add(mp2)
    session.add(mp3)
    session.commit()

    matched, unmatched = generate_group_meetings([user1, user2, user3], meeting_spec, 3, 10, 5)
    assert {user for user in matched[0]} == {user1, user2, user3}
    assert unmatched == []
Example #6
0
def test_get_previous_meetings(session):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() -
                                  timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1])
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription)
    user1 = User(email='*****@*****.**',
                 meta_data={'department': 'dept'},
                 subscription_preferences=[user_pref])
    user2 = User(email='*****@*****.**',
                 meta_data={'department': 'dept2'},
                 subscription_preferences=[user_pref])
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.datetime)
    meeting = Meeting(meeting_spec=meeting_spec, cancelled=False)
    mp1 = MeetingParticipant(meeting=meeting, user=user2)
    mp2 = MeetingParticipant(meeting=meeting, user=user1)

    session.add(pref_1)
    session.add(subscription)
    session.add(user_pref)
    session.add(user1)
    session.add(user2)
    session.add(meeting_spec)
    session.add(meeting)
    session.add(mp1)
    session.add(mp2)
    session.commit()

    assert get_previous_meetings(subscription) == set([(user1.id, user2.id)])
Example #7
0
def test_get_previous_meetings(minimal_database):
    pref_1 = SubscriptionDateTime(
        datetime=datetime.now() -
        timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1]).put()
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription).put()
    user1 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept'
                 },
                 subscription_preferences=[user_pref]).put()
    user2 = User(email='*****@*****.**',
                 metadata={
                     'department': 'dept2'
                 },
                 subscription_preferences=[user_pref]).put()
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.get().datetime).put()
    meeting = Meeting(meeting_spec=meeting_spec, cancelled=False).put()
    MeetingParticipant(meeting=meeting, user=user2).put()
    MeetingParticipant(meeting=meeting, user=user1).put()

    assert get_previous_meetings() == set([(user1.id(), user2.id())])
Example #8
0
def get_specs_from_subscription(subscription):
    specs = []
    for subscription_datetime in subscription.datetime:
        subscription_tz = timezone(subscription.timezone)
        week_start = datetime.now(subscription_tz) - timedelta(
            days=datetime.now(subscription_tz).weekday())
        week_start = week_start.replace(hour=0,
                                        minute=0,
                                        second=0,
                                        microsecond=0)

        subscription_dt = subscription_datetime.datetime.replace(
            tzinfo=utc).astimezone(subscription_tz)
        week_iter = week_start
        while week_iter.weekday() != subscription_dt.weekday():
            week_iter += timedelta(days=1)

        meeting_datetime = week_iter.replace(
            hour=subscription_dt.hour,
            minute=subscription_dt.minute).astimezone(utc)

        specs.append(
            MeetingSpec(meeting_subscription=subscription,
                        datetime=meeting_datetime))
    return week_start, specs
Example #9
0
def test_no_re_matches(session):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1])
    user_pref = UserSubscriptionPreferences(preference=pref_1, subscription=subscription)
    meeting_spec = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.datetime)
    session.add(pref_1)
    session.add(subscription)
    session.add(user_pref)
    session.add(meeting_spec)

    users = []
    num_users = 20
    for i in range(0, num_users):
        user = User(email='{}@yelp.com'.format(i), meta_data={
                    'department': 'dept{}'.format(i)}, subscription_preferences=[user_pref])
        session.add(user)
        mr = MeetingRequest(user=user, meeting_spec=meeting_spec)
        session.add(mr)
        users.append(user)
    session.commit()

    previous_meetings = {pair for pair in itertools.combinations([user.id for user in users], 2)}
    previous_meetings = previous_meetings - {(users[0].id, users[1].id)}
    matches, unmatched = generate_meetings(users, meeting_spec, previous_meetings)
    assert len(unmatched) == num_users - 2
    assert [(match[0].id, match[1].id) for match in matches] == [(users[0].id, users[1].id)]
Example #10
0
def test_generate_group_meeting(session):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1])
    user_pref = UserSubscriptionPreferences(preference=pref_1, subscription=subscription)
    meeting_spec = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.datetime)
    session.add(pref_1)
    session.add(subscription)
    session.add(user_pref)
    session.add(meeting_spec)

    users = []
    num_users = 21
    for i in range(0, num_users):
        user = User(email='{}@yelp.com'.format(i), meta_data={
                    'department': 'dept{}'.format(i)}, subscription_preferences=[user_pref])
        session.add(user)
        mr = MeetingRequest(user=user, meeting_spec=meeting_spec)
        session.add(mr)
        users.append(user)

    session.commit()
    matches, unmatched = generate_meetings(users, meeting_spec, prev_meeting_tuples=None, group_size=3)
    assert(len(matches) == 7)
    assert (len(unmatched) == 0)
    matches, unmatched = generate_meetings(users, meeting_spec, prev_meeting_tuples=None, group_size=5)
    assert(len(matches) == 4)
    assert (len(unmatched) == 1)
Example #11
0
def test_user_preference(minimal_database, subscription):
    preference = subscription.datetime[0]
    user_pref = UserSubscriptionPreferences(
        preference=preference,
        subscription=subscription.key,
    ).put()
    user = User(email='*****@*****.**',
                metadata={'department': 'dept'},
                subscription_preferences=[user_pref])
    user.put()
    meeting_spec = MeetingSpec(
        meeting_subscription=subscription.key,
        datetime=subscription.datetime[0].get().datetime)
    meeting_spec.put()

    assert user_pref == user_preference(user, meeting_spec)
Example #12
0
def get_previous_meetings(cooldown=MEETING_COOLDOWN_WEEKS):
    meetings = defaultdict(list)

    # get all meeting specs from x weeks ago til now
    time_threshold_for_meetings = datetime.now() - timedelta(weeks=cooldown)

    meeting_spec_keys = [
        spec.key for spec in MeetingSpec.query(
            MeetingSpec.datetime > time_threshold_for_meetings).fetch()
    ]

    logging.info('Previous Meeting History: ')
    logging.info([
        meeting.get().datetime.strftime("%Y-%m-%d %H:%M")
        for meeting in meeting_spec_keys
    ])

    if meeting_spec_keys == []:
        return set([])

    # get all meetings from meeting specs
    meeting_keys = [
        meeting.key for meeting in Meeting.query().filter(
            Meeting.meeting_spec.IN(meeting_spec_keys)).fetch()
    ]

    if meeting_keys == []:
        return set([])

    # get all participants from meetings
    participants = MeetingParticipant.query().filter(
        MeetingParticipant.meeting.IN(meeting_keys)).fetch()

    if participants == []:
        return set([])

    # group by meeting Id
    for participant in participants:
        meetings[participant.meeting.id()].append(participant.user)

    # ids are sorted, all matches should be in increasing order by id for the matching algorithm to work
    disallowed_meetings = set([
        tuple(sorted(meeting, key=lambda Key: Key.id()))
        for meeting in meetings.values()
    ])

    logging.info('Past Meetings')
    logging.info([
        tuple([meeting.get().get_username() for meeting in meeting])
        for meeting in disallowed_meetings
    ])

    disallowed_meetings = {
        tuple([meeting.id() for meeting in meeting])
        for meeting in disallowed_meetings
    }

    return disallowed_meetings
Example #13
0
def test_generate_group_meeting_invalid_number_of_users(minimal_database):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1]).put()
    user_pref = UserSubscriptionPreferences(preference=pref_1, subscription=subscription).put()
    meeting_spec = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.get().datetime)
    meeting_spec.put()

    users = []
    for i in range(0, 2):
        user = User(email='{}@yelp.com'.format(i), metadata={
            'department': 'dept{}'.format(i)}, subscription_preferences=[user_pref])
        user.put()
        MeetingRequest(user=user.key, meeting_spec=meeting_spec.key).put()
        users.append(user)

    matches, unmatched = generate_meetings(users, meeting_spec, prev_meeting_tuples=None, group_size=3)
    assert(len(matches) == 0)
    assert (len(unmatched) == 2)
Example #14
0
def store_specs_from_subscription(subscription_key, week_start, specs):
    """
    Idempotent function to store meeting specs for this week.
    """
    try:
        current_specs = MeetingSpec.query(
            MeetingSpec.meeting_subscription == subscription_key,
            MeetingSpec.datetime > week_start).fetch()
    except NeedIndexError:
        current_specs = []

    if current_specs:
        return

    ndb.put_multi(specs)
    return specs
Example #15
0
def test_user_preference(session, subscription):
    preference = subscription.datetime[0]
    user_pref = UserSubscriptionPreferences(
        preference=preference,
        subscription=subscription,
    )
    session.add(user_pref)
    user = User(email='*****@*****.**',
                meta_data={'department': 'dept'},
                subscription_preferences=[user_pref])
    session.add(user)
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=subscription.datetime[0].datetime)
    session.add(meeting_spec)
    session.commit()

    assert user_pref == user_preference(user, meeting_spec)
Example #16
0
def get_specs_from_subscription(subscription):
    specs = []
    for subscription_datetime in subscription.datetime:

        week_start = datetime.now() - timedelta(days=datetime.now().weekday())
        week_start = week_start.replace(hour=0,
                                        minute=0,
                                        second=0,
                                        microsecond=0)

        subscription_dt = subscription_datetime.get().datetime
        week_iter = week_start
        while week_iter.weekday() != subscription_dt.weekday():
            week_iter += timedelta(days=1)

        specs.append(
            MeetingSpec(meeting_subscription=subscription.key,
                        datetime=week_iter.replace(
                            hour=subscription_dt.hour,
                            minute=subscription_dt.minute)))
    return week_start, specs
Example #17
0
def test_generate_save_meetings(session, subscription):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() -
                                  timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    subscription = MeetingSubscription(title='all engineering weekly',
                                       datetime=[pref_1])
    user_pref = UserSubscriptionPreferences(preference=pref_1,
                                            subscription=subscription)
    user1 = User(email='*****@*****.**',
                 meta_data={'department': 'dept'},
                 subscription_preferences=[user_pref])
    user2 = User(email='*****@*****.**',
                 meta_data={'department': 'dept2'},
                 subscription_preferences=[user_pref])
    meeting_spec = MeetingSpec(meeting_subscription=subscription,
                               datetime=pref_1.datetime)
    mr1 = MeetingRequest(user=user1, meeting_spec=meeting_spec)
    mr2 = MeetingRequest(user=user2, meeting_spec=meeting_spec)

    session.add(pref_1)
    session.add(subscription)
    session.add(user_pref)
    session.add(user1)
    session.add(user2)
    session.add(meeting_spec)
    session.add(mr1)
    session.add(mr2)
    session.commit()

    matches, unmatched = generate_meetings([user1, user2], meeting_spec)
    save_meetings(matches, meeting_spec)

    assert unmatched == []

    participants = [
        participant.user for participant in MeetingParticipant.query.all()
    ]

    assert participants == [user1, user2]
Example #18
0
def test_previous_meeting_penalty(session):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1))
    pref_2 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 2))
    pref_3 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 3))
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1, pref_2, pref_3])
    user_pref1 = UserSubscriptionPreferences(preference=pref_1, subscription=subscription)
    user_pref2 = UserSubscriptionPreferences(preference=pref_2, subscription=subscription)
    user_pref3 = UserSubscriptionPreferences(preference=pref_3, subscription=subscription)
    meeting_spec1 = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.datetime)
    meeting_spec2 = MeetingSpec(meeting_subscription=subscription, datetime=pref_2.datetime)
    meeting_spec3 = MeetingSpec(meeting_subscription=subscription, datetime=pref_3.datetime)
    session.add(pref_1)
    session.add(pref_2)
    session.add(pref_3)
    session.add(subscription)
    session.add(user_pref1)
    session.add(user_pref2)
    session.add(user_pref3)
    session.add(meeting_spec1)
    session.add(meeting_spec2)
    session.add(meeting_spec3)

    users = []
    num_users = 20
    for i in range(0, num_users):
        user = User(email='{}@yelp.com'.format(i), meta_data={
                    'department': 'dept{}'.format(i)}, subscription_preferences=[user_pref1, user_pref2, user_pref3])
        session.add(user)
        mr1 = MeetingRequest(user=user, meeting_spec=meeting_spec1)
        mr2 = MeetingRequest(user=user, meeting_spec=meeting_spec2)
        mr3 = MeetingRequest(user=user, meeting_spec=meeting_spec3)
        session.add(mr1)
        session.add(mr2)
        session.add(mr3)
        users.append(user)

    meeting1 = Meeting(meeting_spec=meeting_spec1, cancelled=False)
    mp1 = MeetingParticipant(meeting=meeting1, user=users[1])
    mp2 = MeetingParticipant(meeting=meeting1, user=users[0])
    session.add(meeting1)
    session.add(mp1)
    session.add(mp2)

    meeting2 = Meeting(meeting_spec=meeting_spec2, cancelled=False)
    mp1 = MeetingParticipant(meeting=meeting2, user=users[1])
    mp2 = MeetingParticipant(meeting=meeting2, user=users[0])
    session.add(meeting2)
    session.add(mp1)
    session.add(mp2)

    meeting3 = Meeting(meeting_spec=meeting_spec3, cancelled=False)
    mp1 = MeetingParticipant(meeting=meeting3, user=users[1])
    mp2 = MeetingParticipant(meeting=meeting3, user=users[0])
    session.add(meeting3)
    session.add(mp1)
    session.add(mp2)

    session.commit()

    for run in range(10):
        matches, unmatched = generate_meetings(users, meeting_spec1, prev_meeting_tuples=None, group_size=3)
        assert(len(matches) == 6)
        assert (len(unmatched) == 2)
        for matched_group in matches:
            assert(not (users[0] in matched_group and users[1] in matched_group))
Example #19
0
def test_store_specs_from_subscription(database):
    week_start, specs = get_specs_from_subscription(database.sub)
    store_specs_from_subscription(database.sub.key, week_start, specs)
    assert len(MeetingSpec.query().fetch()) == 2
Example #20
0
def test_generate_meeting_specs_idempotent(database):
    # ensure we don't create more specs
    generate_meeting_specs()
    meeting_specs = MeetingSpec.query().fetch()
    assert len(meeting_specs) == 2
Example #21
0
def get_specs_for_current_week():
    week_start = datetime.now() - timedelta(days=datetime.now().weekday())
    week_start.replace(hour=0, minute=0, second=0, microsecond=0)
    return MeetingSpec.query(MeetingSpec.datetime > week_start).fetch()
Example #22
0
def test_previous_meeting_penalty(minimal_database):
    pref_1 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 1)).put()
    pref_2 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 2)).put()
    pref_3 = SubscriptionDateTime(datetime=datetime.now() - timedelta(weeks=MEETING_COOLDOWN_WEEKS - 3)).put()
    subscription = MeetingSubscription(title='all engineering weekly', datetime=[pref_1, pref_2, pref_3]).put()
    user_pref1 = UserSubscriptionPreferences(preference=pref_1, subscription=subscription).put()
    user_pref2 = UserSubscriptionPreferences(preference=pref_2, subscription=subscription).put()
    user_pref3 = UserSubscriptionPreferences(preference=pref_3, subscription=subscription).put()
    meeting_spec1 = MeetingSpec(meeting_subscription=subscription, datetime=pref_1.get().datetime)
    meeting_spec1.put()
    meeting_spec2 = MeetingSpec(meeting_subscription=subscription, datetime=pref_2.get().datetime)
    meeting_spec2.put()
    meeting_spec3 = MeetingSpec(meeting_subscription=subscription, datetime=pref_3.get().datetime)
    meeting_spec3.put()

    users = []
    num_users = 20
    for i in range(0, num_users):
        user = User(email='{}@yelp.com'.format(i), metadata={
                    'department': 'dept{}'.format(i)}, subscription_preferences=[user_pref1, user_pref2, user_pref3])
        user.put()
        MeetingRequest(user=user.key, meeting_spec=meeting_spec1.key).put()
        MeetingRequest(user=user.key, meeting_spec=meeting_spec2.key).put()
        MeetingRequest(user=user.key, meeting_spec=meeting_spec3.key).put()
        users.append(user)

    meeting1 = Meeting(meeting_spec=meeting_spec1.key, cancelled=False).put()
    MeetingParticipant(meeting=meeting1, user=users[1].key).put()
    MeetingParticipant(meeting=meeting1, user=users[0].key).put()
    meeting2 = Meeting(meeting_spec=meeting_spec2.key, cancelled=False).put()
    MeetingParticipant(meeting=meeting2, user=users[1].key).put()
    MeetingParticipant(meeting=meeting2, user=users[0].key).put()
    meeting3 = Meeting(meeting_spec=meeting_spec3.key, cancelled=False).put()
    MeetingParticipant(meeting=meeting3, user=users[1].key).put()
    MeetingParticipant(meeting=meeting3, user=users[0].key).put()

    for run in range(10):
        matches, unmatched = generate_meetings(users, meeting_spec1, prev_meeting_tuples=None, group_size=3)
        assert(len(matches) == 6)
        assert (len(unmatched) == 2)
        for matched_group in matches:
            assert(not (users[0] in matched_group and users[1] in matched_group))