chapps.tests.test_policy.test_policy module

Tests for CHAPPS policy module

class chapps.tests.test_policy.test_policy.Test_EmailPolicy[source]

Bases: object

Tests of the base policy class

test_rediskey()[source]

GIVEN a prefix and some arguments WHEN we ask EmailPolicy for a redis key THEN it should glue everything together with colons

test_fmtkey()[source]

GIVEN some arguments WHEN we ask EmailPolicy to format a key THEN it should use the prefix ‘grl’, and glue all together with colons

test_approval_not_implemented(allowable_ppr)[source]

GIVEN an instance of EmailPolicy or a subclass WHEN the superclass/abstract version of approve_policy_request is called THEN a NotImplementedError should be raised

test_connect_to_redis()[source]

GIVEN a new EmailPolicy WHEN asked for a Redis handle THEN return a Redis handle

test_connect_to_sentinel(chapps_sentinel_env, chapps_sentinel_config_file)[source]

GIVEN Sentinel servers are listed in the config file WHEN asked for a Redis handle THEN use Sentinel server and dataset information to get a read-write Redis handle

class chapps.tests.test_policy.test_policy.Test_PostfixActions[source]

Bases: object

Tests for abstract Postfix action superclass

test_okay(postfix_actions)[source]

Returns OK

test_okay_accepts_useless_message(postfix_actions)[source]

Returns OK even if a message is supplied

test_dunno(postfix_actions)[source]

Returns DUNNO

test_dunno_accepts_useless_message(postfix_actions)[source]

Returns DUNNO even if a message is supplied

test_action_for_raises_not_implemented_error(postfix_actions)[source]

The method action_for() is abstract and not implemented by PostfixActions

class chapps.tests.test_policy.test_policy.Test_PostfixOQPActions[source]

Bases: object

Testing outbound quota actions for Postfix

test_pass_yields_okay(oqp_actions)[source]

Pass returns OK

test_fail_yields_rejection(oqp_actions)[source]

Fail returns a string starting with ‘554 Rejected’ or ‘REJECT’

class chapps.tests.test_policy.test_policy.Test_PostfixGRLActions[source]

Bases: object

Testing greylisting actions for Postfix

test_pass_yields_dunno(grl_actions)[source]

Pass returns DUNNO

test_fail_yields_rejection(grl_actions)[source]

Fail returns a string starting with DEFER_IF_PERMIT

class chapps.tests.test_policy.test_policy.Test_GreylistingPolicy_Base[source]

Bases: object

Tests of the greylisting policy module

test_fmtkey()[source]

GIVEN some arguments WHEN we ask EmailPolicy to format a key THEN it should use the prefix ‘grl’, and glue all together with colons

test_tuple_key(caplog, allowable_inbound_ppr)[source]

GIVEN a PostfixPolicyRequest object populated with valid data WHEN we as for a tuple key THEN a string in the form of grl:<ip>:<sender>:<recipient> should be returned

test_client_key(caplog, allowable_inbound_ppr)[source]

GIVEN a PostfixPolicyRequest object populated with valid data WHEN we ask for a client key THEN a string in the form of grl:<ip> should be returned

test_config_overrides_properly_forwarded(caplog, testing_policy_grl)[source]
test_approve_policy_request(caplog, monkeypatch, allowable_inbound_ppr)[source]

GIVEN a positive policy evaluation WHEN approve_policy_request is called THEN it should return True

test_policy_request_instance_cache(caplog, monkeypatch, allowable_inbound_ppr)[source]

GIVEN a positive policy evaluation WHEN approve_policy_request is called THEN it should return True

class chapps.tests.test_policy.test_policy.Test_GreylistingPolicyEvaluation[source]

Bases: object

test_first_encounter_false(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl, populated_database_fixture)[source]

GIVEN a new tuple WHEN executed THEN return False

test_pass_if_option_false(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl, populated_database_fixture)[source]

GIVEN that the option is set to False WHEN examining a policy request THEN issue a passing response since we are not enforcing this policy

test_pass_if_whitelisted(caplog, monkeypatch, helo_ppr_factory, testing_policy_grl, populated_database_fixture)[source]
GIVEN

that the PPR’s client (HELO) is whitelisted

WHEN

evaluating an approval request

THEN

issue a passing response

test_first_encounter_updates_tuple(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl)[source]

GIVEN a new tuple WHEN executed THEN update the tuple

test_recognized_tuple_passes(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl)[source]

GIVEN a recognized tuple - a timestamp WHEN the tuple was seen more than min_delay seconds ago THEN return True

test_recognized_tuple_updates_client_tally(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl)[source]

GIVEN a recognized tuple - a timestamp WHEN the tuple was seen more than min_delay seconds ago THEN return True

test_sufficient_client_tally_permits_sending_for_unrecognized_tuple(caplog, monkeypatch, allowable_inbound_ppr, mock_client_tally, testing_policy_grl, populate_redis_grl, populated_database_fixture)[source]

GIVEN a new tuple from a client with a large enough tally WHEN executed THEN return True

test_client_tally_updated_when_unrecognized_tuple_passes(caplog, monkeypatch, allowable_inbound_ppr, mock_client_tally, testing_policy_grl, populate_redis_grl)[source]

GIVEN a new tuple from a client with a large enough tally WHEN executed THEN update the tally

test_retry_too_soon_fails(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl)[source]

GIVEN a recognized tuple WHEN the tuple was seen too recently (less than min_delay seconds) THEN return False

test_retry_too_soon_updates_tuple(caplog, monkeypatch, allowable_inbound_ppr, testing_policy_grl)[source]

GIVEN a recognized tuple WHEN the tuple was seen too recently (less than min_delay seconds) THEN return False

class chapps.tests.test_policy.test_policy.Test_GreylistingPolicy_update_control_data[source]

Bases: object

Testing control update routes _update_tuple and _update_client_tally

test_update_tuple(caplog, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN a ppr WHEN _update_tuple executed THEN set a key with a particular structure to a current timestamp

test_update_client_tally(caplog, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN a ppr WHEN _update_client_tally is executed THEN add the tuple (map) instance -> timestamp to the client key

test_skip_client_tally_update_if_allow_after_is_zero(caplog, monkeypatch, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN that allow_after is set to zero (we are not keeping a success tally) WHEN _update_client_tally is executed THEN immediately return

class chapps.tests.test_policy.test_policy.Test_GreylistingPolicy_get_control_data[source]

Bases: object

This method interfaces with Redis

test_no_keys_yet_exist(caplog, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN a new tuple WHEN control data is requested THEN the returned tuple should have None as its first element

test_tuple_is_recognized(caplog, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN a recognized tuple WHEN control data is requested THEN the tuple should have a timestamp (float) as its 2nd argument

test_allow_after_is_zero(caplog, monkeypatch, clear_redis_grl, allowable_inbound_ppr)[source]

GIVEN a recognized tuple, and allow_after set to 0 WHEN control data is requested THEN the third member of the tuple should always be None

test_new_tuple_client_tally_present(caplog, monkeypatch, mock_client_tally, populate_redis_grl, allowable_inbound_ppr, unique_instance)[source]

GIVEN an unrecognized tuple, but existing client tally WHEN executed THEN the count should be returned as the third member of the tuple

test_tuple_recognized_and_tally_exists(caplog, mock_client_tally, allowable_inbound_ppr, populate_redis_grl, unique_instance)[source]
GIVEN

a recognized tuple, and an existing tally

WHEN

executed

THEN

return the option flag, a timestamp, and the client’s tally in that order

class chapps.tests.test_policy.test_policy.Test_OutboundQuotaPolicy[source]

Bases: object

Tests of the outbound quota policy module

test_oqp_fmtkey()[source]

GIVEN: email (user), and parameter name WHEN: oqp is asked for a Redis key THEN: oqp._fmtkey(user, param) should return a string like ‘oqp:<user>:<param>’

test_approve_policy_request(caplog, allowable_ppr, well_spaced_attempts, populate_redis)[source]

Verify that underquota users’ emails are approved.

test_approve_last_remaining_quota(caplog, allowable_ppr, well_spaced_attempts, populate_redis)[source]

Verify that the last bit of a quota can be used.

test_approve_last_with_multiple_recipients(caplog, groupsend_ppr, well_spaced_attempts, populate_redis)[source]

Verify that multiple recipients adding up to the last available messages will be approved.

test_approve_underquota_within_margin(caplog, multisend_ppr_factory, well_spaced_attempts, populate_redis)[source]

Verify that when a multi-recipient email takes an underquota account overquota, it will be approved if the amount overquota is within the established margin.

test_deny_policy_request(overquota_ppr, well_spaced_attempts, populate_redis)[source]

Verify that overquota users are rejected.

test_deny_when_too_many_recipients(multisend_ppr_factory, well_spaced_attempts, populate_redis)[source]
GIVEN

a multi-recipient PPR

WHEN

the recipient list would go over the quota

THEN

the attempt is denied.

This has the side-effect of meaning that rejected multi-recipient attempts add their recipient count to the attempt history, meaning that the account will be fully over-quota once this occurs.

test_deny_overquota_within_margin(caplog, groupsend_ppr, well_spaced_attempts, populate_redis)[source]

Verify that an account which is just over-quota will not have a new email which is within the margin approved. This is to ensure that the quota is real, and not just enlarged by the margin.

test_deny_rapid_attempts(allowable_ppr, rapid_attempts, populate_redis)[source]

Verify that attempts which come too fast will be rejected.

test_return_cached_instance_approval(allowable_ppr, well_spaced_double_attempts, populate_redis, caplog)[source]

GIVEN we have already seen a particular instance before, WHEN we are asked to approve or deny it THEN we will return the cached value of the instance (which really only matters on approval)

test_approve_policy_request_for_uncached(uncached_allowable_ppr, well_spaced_attempts, populated_database_fixture, testing_policy)[source]

Verify that existing-but-uncached users’ emails are approved. (Uncached implies they have sent no emails w/i the rolling interval.)

test_deny_policy_request_for_undefined(undefined_ppr, populated_database_fixture, testing_policy)[source]

Verify that undefined users are rejected.

test_current_quota(sda_allowable_ppr, populate_redis, well_spaced_attempts, populated_database_fixture, testing_policy)[source]
class chapps.tests.test_policy.test_policy.Test_SenderDomainAuthPolicy[source]

Bases: object

test_sda_fmtkey()[source]
test_get_sender_domain(auto_ppr, expected_result)[source]
test_sender_domain_key(allowable_ppr)[source]
test_authorized_user(sda_allowable_ppr, testing_policy_sda)[source]
test_whole_email_auth(sda_auth_email_ppr, testing_policy_sda)[source]
test_whole_email_unauth(sda_unauth_email_ppr, testing_policy_sda)[source]
test_cached_authed_user(monkeypatch, sda_allowable_ppr, testing_policy_sda)[source]
test_cached_whole_email(monkeypatch, sda_auth_email_ppr, testing_policy_sda)[source]
test_unauthorized_user(sda_unauth_ppr, testing_policy_sda, clear_redis_sda)[source]
test_cached_unauth_user(monkeypatch, sda_unauth_ppr, testing_policy_sda)[source]
class chapps.tests.test_policy.test_policy.Test_InboundPolicy[source]

Bases: object

test_whitelist(testing_policy_inbound, helo_ppr_factory)[source]
GIVEN

a helo whitelist and an inbound policy

WHEN

the PPR reflects a connection from the whitelisted server

THEN

the policy’s _whitelisted() method should return True

test_not_whitelisted(testing_policy_inbound, helo_ppr_factory)[source]
GIVEN

a helo whitelist and an inbound policy

WHEN

the PPR reflects a connection from an unlisted server

THEN

the policy’s _whitelisted() method should return False