Example #1
0
    def test_dict_multi_key(self):
        mock = Mock()

        class DiffTuple(Diff):

            extract_imported = extract_existing = DictExtractor('k', 'k2')

            add = mock.add
            update = mock.update
            delete = mock.delete

        a = dict(k='a', k2=0, v=1)
        b = dict(k='b', k2=0, v=2)
        c = dict(k='c', k2=0, v=3)
        c_ = dict(k='c', k2=0, v=4)
        d = dict(k='d', k2=0, v=5)

        diff = DiffTuple([a, b, c], [b, c_, d])
        diff.apply()

        compare([
            call.delete(('a', 0), a, a),
            call.update(('c', 0), c, c, c_, c_),
            call.add(('d', 0), d, d),
        ], mock.mock_calls)
Example #2
0
 def test_delete_gauge(self):
     """Tests deltion of a gauge."""
     self.r.delete_gauge("test-gauge")
     self.redis.assert_has_calls([
         call.delete('g:test-gauge'),
         call.srem(self.r._gauge_slugs_key, "test-gauge"),
     ])
Example #3
0
    def test_named_tuple(self):
        mock = Mock()

        X = namedtuple('X', 'foo bar')
        Y = namedtuple('Y', 'foo bar')

        class DiffTuple(Diff):

            extract_imported = extract_existing = NamedTupleExtractor('foo')

            add = mock.add
            update = mock.update
            delete = mock.delete

        aX = X('a', 1)
        bX = X('b', 2)
        cX = X('c', 3)
        bY = Y('b', 2)
        cY = Y('c', 4)
        dY = Y('d', 5)

        daX = dict(foo='a', bar=1)
        dcX = dict(foo='c', bar=3)
        dcY = dict(foo='c', bar=4)
        ddY = dict(foo='d', bar=5)

        diff = DiffTuple([aX, bX, cX], [bY, cY, dY])
        diff.apply()

        compare([
            call.delete(('a',), aX, daX),
            call.update(('c',), cX, dcX, cY, dcY),
            call.add(('d', ), dY, ddY),
        ], mock.mock_calls)
Example #4
0
    def test_delete_metric(self):
        """Verify that ``R.delete_metric`` deletes all keys and removes keys
        from the set of metric slugs."""

        # Make sure KEYS returns some data
        self.redis.keys.return_value = ["m:slug:0", "m:slug:1"]
        self.r.delete_metric('slug')  # call delete_metric

        # Verify that the metric data is removed as are the keys from the set
        self.redis.assert_has_calls([
            call.keys("m:slug:*"),
            call.delete("m:slug:0", "m:slug:1"),
            call.srem(self.r._metric_slugs_key, "slug")
        ])
Example #5
0
    def test_post_actions(self):

        mock = Mock()

        class DiffTuple(Diff):
            def extract_existing(self, obj):
                return obj[0], obj

            extract_imported = extract_existing

            add = mock.add
            update = mock.update
            delete = mock.delete
            post_add = mock.post_add
            post_update = mock.post_update
            post_delete = mock.post_delete

        diff = DiffTuple(
            [('a1', 2), ('a2', 2),  ('c1', 6),  ('c2', 6)],
            [('c1', 7), ('c2', 7), ('d1', 8), ('d2', 8)]
        )

        compare([], mock.mock_calls)

        diff.apply()

        compare([
            call.delete('a1', ('a1', 2), ('a1', 2)),
            call.delete('a2', ('a2', 2), ('a2', 2)),
            call.post_delete(),
            call.update('c1', ('c1', 6), ('c1', 6), ('c1', 7), ('c1', 7)),
            call.update('c2', ('c2', 6), ('c2', 6), ('c2', 7), ('c2', 7)),
            call.post_update(),
            call.add('d1', ('d1', 8), ('d1', 8)),
            call.add('d2', ('d2', 8), ('d2', 8)),
            call.post_add(),
        ], mock.mock_calls)
Example #6
0
    def test_ftp_connection_remove_file_method_remove_file_and_clear_empty_directories(
            self):
        return_default = lambda value: value
        self.ftp_connection.ftp = MagicMock(name='ftp')
        self.ftp_connection.ftp.rmd = MagicMock(
            name='rmd',
            side_effect=[return_default,
                         Exception('no empty directory')])
        self.ftp_connection.remove_file('path/to/file/file.txt')

        self.ftp_connection.ftp.rmd.assert_has_calls(
            [call('ftp/path/path/to/file'),
             call('ftp/path/path/to')])
        self.ftp_connection.ftp.assert_has_calls(
            [call.delete('ftp/path/path/to/file/file.txt')])
    def test_do_not_delete_old_comments(self,
                                        mock_getenv,
                                        mock_client_session):
        mock_args, fake_client_session = self.create_mock_pr(
            mock_getenv,
            mock_client_session)

        mock_args.delete_previous_comments = False
        reporter = github_reporter.create_reporter(mock_args)

        problems = [Problem('another_file', x, 'Wat') for x in range(1, 13)]

        async_report = reporter.report('unit-test-linter', problems)
        loop = asyncio.get_event_loop()

        try:
            loop.run_until_complete(async_report)
        except HadLintErrorsException:
            pass

        overflow_message = textwrap.dedent('''\
            unit-test-linter says:

            Too many lint errors to report inline!  12 lines have a problem.
            Only reporting the first 10.''')
        overflow_call = call.post(
            'https://api.github.com/repos/foo/bar/issues/1234/comments',
            headers={
                'Authorization': 'token MY_TOKEN'
            },
            data=json.dumps({
                'body': overflow_message,
            }, sort_keys=True)
        )
        delete_previous_call = call.delete(
            'https://api.github.com/repos/foo/bar/pulls/comments/1',
            headers={
                'Authorization': 'token MY_TOKEN'
            }
        )

        self.assertIn(overflow_call, fake_client_session.calls)
        self.assertNotIn(delete_previous_call, fake_client_session.calls)
        self.assertEqual(4 + github_reporter.MAX_LINT_ERROR_REPORTS,
                         len(fake_client_session.calls))
Example #8
0
    def test_tuple(self):

        DiffTuple, mock = self.make_differ()

        diff = DiffTuple(
            [('a', 1, 2), ('b', 3, 4), ('c', 5, 6)],
            [('b', 3, 4), ('c', 5, 7), ('d', 7, 8)]
        )

        compare([], mock.mock_calls)

        diff.apply()

        compare([
            call.delete('a', ('a', 1, 2), ('a', 2)),
            call.update('c', ('c', 5, 6), ('c', 6), ('c', 5, 7), ('c', 7)),
            call.add('d', ('d', 7, 8), ('d', 8)),
        ], mock.mock_calls)
    def test_delete_success(self, search_response, defaults):
        """ Test delete success. """
        dn = 'uid=tux,ou=People,dc=python-ldap,dc=org'
        search_response.add(dn, defaults.modlist)

        c = tldap.backend.connection
        c.add(dn, defaults.modlist)
        with tldap.transaction.commit_on_success():
            c.delete(dn)

        expected_calls = [
            call.open(),
            call.bind(),
            call.add(dn, None, defaults.modlist),
            call.search(dn, '(objectclass=*)', 'BASE', attributes=ANY),
            call.delete(dn),
        ]
        defaults.mock_connection.assert_has_calls(expected_calls)
    def test_delete_rollback(self, search_response, defaults):
        """ Test delete rollback. """
        dn = 'uid=tux,ou=People,dc=python-ldap,dc=org'
        search_response.add(dn, defaults.modlist)

        c = tldap.backend.connection
        c.add(dn, defaults.modlist)
        with pytest.raises(tldap.exceptions.TestFailure):
            with tldap.transaction.commit_on_success():
                c.delete(dn)
                c.fail()  # raises TestFailure during commit causing rollback
                c.commit()

        expected_calls = [
            call.open(),
            call.bind(),
            call.add(dn, None, defaults.modlist),
            call.search(dn, '(objectclass=*)', 'BASE', attributes=ANY),
            call.delete(dn),
            call.add(dn, None, defaults.modlist),
        ]
        defaults.mock_connection.assert_has_calls(expected_calls)
    def test_roll_back_explicit(self, search_response, defaults):
        """ Test explicit roll back. """
        dn = 'uid=tux,ou=People,dc=python-ldap,dc=org'
        search_response.add(dn, defaults.modlist)

        c = tldap.backend.connection
        with tldap.transaction.commit_on_success():
            c.add(dn, defaults.modlist)
            c.modify(dn, {
                'sn': [(ldap3.MODIFY_REPLACE, [b"Gates"])]
            })
            c.rollback()

        expected_calls = [
            call.open(),
            call.bind(),
            call.add(dn, None, defaults.modlist),
            call.search(dn, '(objectclass=*)', 'BASE', attributes=ANY),
            call.modify(dn, {'sn': [('MODIFY_REPLACE', [b'Gates'])]}),
            call.modify(dn, {'sn': [('MODIFY_REPLACE', [b'Torvalds'])]}),
            call.delete(dn)
        ]
        defaults.mock_connection.assert_has_calls(expected_calls)
 def delete(self, url, *args, **kwargs):
     updated_kwargs = self._update_headers(kwargs)
     self.calls.append(call.delete(url, *args, **updated_kwargs))
     return _RequestContextManager(self._get_stored_value(url, 'delete'))
    def test_sync(self, load_mock, create_mock):
        provider = Ns1Provider('test', 'api-key')

        desired = Zone('unit.tests.', [])
        for r in self.expected:
            desired.add_record(r)

        plan = provider.plan(desired)
        # everything except the root NS
        expected_n = len(self.expected) - 1
        self.assertEquals(expected_n, len(plan.changes))

        # Fails, general error
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = ResourceException('boom')
        with self.assertRaises(ResourceException) as ctx:
            provider.apply(plan)
        self.assertEquals(load_mock.side_effect, ctx.exception)

        # Fails, bad auth
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = \
            ResourceException('server error: zone not found')
        create_mock.side_effect = AuthException('unauthorized')
        with self.assertRaises(AuthException) as ctx:
            provider.apply(plan)
        self.assertEquals(create_mock.side_effect, ctx.exception)

        # non-existant zone, create
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = \
            ResourceException('server error: zone not found')
        # ugh, need a mock zone with a mock prop since we're using getattr, we
        # can actually control side effects on `meth` with that.
        mock_zone = Mock()
        mock_zone.add_SRV = Mock()
        mock_zone.add_SRV.side_effect = [
            RateLimitException('boo', period=0),
            None,
        ]
        create_mock.side_effect = [mock_zone]
        got_n = provider.apply(plan)
        self.assertEquals(expected_n, got_n)

        # Update & delete
        load_mock.reset_mock()
        create_mock.reset_mock()
        nsone_zone = DummyZone(self.nsone_records + [{
            'type': 'A',
            'ttl': 42,
            'short_answers': ['9.9.9.9'],
            'domain': 'delete-me.unit.tests.',
        }])
        nsone_zone.data['records'][0]['short_answers'][0] = '2.2.2.2'
        nsone_zone.loadRecord = Mock()
        zone_search = Mock()
        zone_search.return_value = [
            {
                "domain": "geo.unit.tests",
                "zone": "unit.tests",
                "type": "A",
                "answers": [
                    {'answer': ['1.1.1.1'], 'meta': {}},
                    {'answer': ['1.2.3.4'],
                     'meta': {'ca_province': ['ON']}},
                    {'answer': ['2.3.4.5'], 'meta': {'us_state': ['NY']}},
                    {'answer': ['3.4.5.6'], 'meta': {'country': ['US']}},
                    {'answer': ['4.5.6.7'],
                     'meta': {'iso_region_code': ['NA-US-WA']}},
                ],
                'ttl': 34,
            },
        ]
        nsone_zone.search = zone_search
        load_mock.side_effect = [nsone_zone, nsone_zone]
        plan = provider.plan(desired)
        self.assertEquals(3, len(plan.changes))
        self.assertIsInstance(plan.changes[0], Update)
        self.assertIsInstance(plan.changes[2], Delete)
        # ugh, we need a mock record that can be returned from loadRecord for
        # the update and delete targets, we can add our side effects to that to
        # trigger rate limit handling
        mock_record = Mock()
        mock_record.update.side_effect = [
            RateLimitException('one', period=0),
            None,
            None,
        ]
        mock_record.delete.side_effect = [
            RateLimitException('two', period=0),
            None,
            None,
        ]
        nsone_zone.loadRecord.side_effect = [mock_record, mock_record,
                                             mock_record]
        got_n = provider.apply(plan)
        self.assertEquals(3, got_n)
        nsone_zone.loadRecord.assert_has_calls([
            call('unit.tests', u'A'),
            call('geo', u'A'),
            call('delete-me', u'A'),
        ])
        mock_record.assert_has_calls([
            call.update(answers=[{'answer': [u'1.2.3.4'], 'meta': {}}],
                        filters=[],
                        ttl=32),
            call.update(answers=[{u'answer': [u'1.2.3.4'], u'meta': {}}],
                        filters=[],
                        ttl=32),
            call.update(
                answers=[
                    {u'answer': [u'101.102.103.104'], u'meta': {}},
                    {u'answer': [u'101.102.103.105'], u'meta': {}},
                    {
                        u'answer': [u'201.202.203.204'],
                        u'meta': {
                            u'iso_region_code': [u'NA-US-NY']
                        },
                    },
                ],
                filters=[
                    {u'filter': u'shuffle', u'config': {}},
                    {u'filter': u'geotarget_country', u'config': {}},
                    {u'filter': u'select_first_n', u'config': {u'N': 1}},
                ],
                ttl=34),
            call.delete(),
            call.delete()
        ])
Example #14
0
    def test_sync(self, load_mock, create_mock):
        provider = Ns1Provider('test', 'api-key')

        desired = Zone('unit.tests.', [])
        for r in self.expected:
            desired.add_record(r)

        plan = provider.plan(desired)
        # everything except the root NS
        expected_n = len(self.expected) - 1
        self.assertEquals(expected_n, len(plan.changes))

        # Fails, general error
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = ResourceException('boom')
        with self.assertRaises(ResourceException) as ctx:
            provider.apply(plan)
        self.assertEquals(load_mock.side_effect, ctx.exception)

        # Fails, bad auth
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = \
            ResourceException('server error: zone not found')
        create_mock.side_effect = AuthException('unauthorized')
        with self.assertRaises(AuthException) as ctx:
            provider.apply(plan)
        self.assertEquals(create_mock.side_effect, ctx.exception)

        # non-existant zone, create
        load_mock.reset_mock()
        create_mock.reset_mock()
        load_mock.side_effect = \
            ResourceException('server error: zone not found')
        # ugh, need a mock zone with a mock prop since we're using getattr, we
        # can actually control side effects on `meth` with that.
        mock_zone = Mock()
        mock_zone.add_SRV = Mock()
        mock_zone.add_SRV.side_effect = [
            RateLimitException('boo', period=0),
            None,
        ]
        create_mock.side_effect = [mock_zone]
        got_n = provider.apply(plan)
        self.assertEquals(expected_n, got_n)

        # Update & delete
        load_mock.reset_mock()
        create_mock.reset_mock()
        nsone_zone = DummyZone(self.nsone_records +
                               [{
                                   'type': 'A',
                                   'ttl': 42,
                                   'short_answers': ['9.9.9.9'],
                                   'domain': 'delete-me.unit.tests.',
                               }])
        nsone_zone.data['records'][0]['short_answers'][0] = '2.2.2.2'
        nsone_zone.loadRecord = Mock()
        load_mock.side_effect = [nsone_zone, nsone_zone]
        plan = provider.plan(desired)
        self.assertEquals(2, len(plan.changes))
        self.assertIsInstance(plan.changes[0], Update)
        self.assertIsInstance(plan.changes[1], Delete)
        # ugh, we need a mock record that can be returned from loadRecord for
        # the update and delete targets, we can add our side effects to that to
        # trigger rate limit handling
        mock_record = Mock()
        mock_record.update.side_effect = [
            RateLimitException('one', period=0),
            None,
        ]
        mock_record.delete.side_effect = [
            RateLimitException('two', period=0),
            None,
        ]
        nsone_zone.loadRecord.side_effect = [mock_record, mock_record]
        got_n = provider.apply(plan)
        self.assertEquals(2, got_n)
        nsone_zone.loadRecord.assert_has_calls([
            call('unit.tests', u'A'),
            call('delete-me', u'A'),
        ])
        mock_record.assert_has_calls(
            [call.update(answers=[u'1.2.3.4'], ttl=32),
             call.delete()])