|
4 | 4 | from unittest.mock import patch |
5 | 5 | from uuid import uuid4 |
6 | 6 |
|
| 7 | +import django |
7 | 8 | from django.contrib.admin.models import LogEntry |
8 | 9 | from django.contrib.auth import get_user_model |
9 | 10 | from django.core.exceptions import ValidationError |
@@ -479,15 +480,6 @@ def test_device_organization_fk_autocomplete_view(self): |
479 | 480 | hidden=[data['org2'].name, data['inactive'].name], |
480 | 481 | ) |
481 | 482 |
|
482 | | - def test_device_templates_m2m_queryset(self): |
483 | | - data = self._create_multitenancy_test_env() |
484 | | - t_shared = self._create_template(name='t-shared', organization=None) |
485 | | - self._test_multitenant_admin( |
486 | | - url=reverse(f'admin:{self.app_label}_device_add'), |
487 | | - visible=[str(data['t1']), str(t_shared)], |
488 | | - hidden=[str(data['t2']), str(data['t3_inactive'])], |
489 | | - ) |
490 | | - |
491 | 483 | def test_template_queryset(self): |
492 | 484 | data = self._create_multitenancy_test_env() |
493 | 485 | self._test_multitenant_admin( |
@@ -796,56 +788,6 @@ def test_template_not_contains_default_templates_js(self): |
796 | 788 | response = self.client.get(path) |
797 | 789 | self.assertNotContains(response, '// enable default templates') |
798 | 790 |
|
799 | | - def test_configuration_templates_removed(self): |
800 | | - def _update_template(templates): |
801 | | - params.update( |
802 | | - { |
803 | | - 'config-0-templates': ','.join( |
804 | | - [str(template.pk) for template in templates] |
805 | | - ) |
806 | | - } |
807 | | - ) |
808 | | - response = self.client.post(path, data=params, follow=True) |
809 | | - self.assertEqual(response.status_code, 200) |
810 | | - for template in templates: |
811 | | - self.assertContains( |
812 | | - response, f'class="sortedm2m" checked> {template.name}' |
813 | | - ) |
814 | | - return response |
815 | | - |
816 | | - template = self._create_template() |
817 | | - |
818 | | - # Add a new device |
819 | | - path = reverse(f'admin:{self.app_label}_device_add') |
820 | | - params = self._get_device_params(org=self._get_org()) |
821 | | - response = self.client.post(path, data=params, follow=True) |
822 | | - self.assertEqual(response.status_code, 200) |
823 | | - |
824 | | - config = Device.objects.get(name=params['name']).config |
825 | | - path = reverse(f'admin:{self.app_label}_device_change', args=[config.device_id]) |
826 | | - params.update( |
827 | | - { |
828 | | - 'config-0-id': str(config.pk), |
829 | | - 'config-0-device': str(config.device_id), |
830 | | - 'config-INITIAL_FORMS': 1, |
831 | | - '_continue': True, |
832 | | - } |
833 | | - ) |
834 | | - |
835 | | - # Add template to the device |
836 | | - _update_template(templates=[template]) |
837 | | - config.refresh_from_db() |
838 | | - self.assertEqual(config.templates.count(), 1) |
839 | | - self.assertEqual(config.status, 'modified') |
840 | | - config.set_status_applied() |
841 | | - self.assertEqual(config.status, 'applied') |
842 | | - |
843 | | - # Remove template from the device |
844 | | - _update_template(templates=[]) |
845 | | - config.refresh_from_db() |
846 | | - self.assertEqual(config.templates.count(), 0) |
847 | | - self.assertEqual(config.status, 'modified') |
848 | | - |
849 | 791 | def test_vpn_not_contains_default_templates_js(self): |
850 | 792 | vpn = self._create_vpn() |
851 | 793 | path = reverse(f'admin:{self.app_label}_vpn_change', args=[vpn.pk]) |
@@ -1626,89 +1568,6 @@ def test_add_vpn(self): |
1626 | 1568 | response, 'value="openwisp_controller.vpn_backends.OpenVpn" selected' |
1627 | 1569 | ) |
1628 | 1570 |
|
1629 | | - def test_vpn_clients_deleted(self): |
1630 | | - def _update_template(templates): |
1631 | | - params.update( |
1632 | | - { |
1633 | | - 'config-0-templates': ','.join( |
1634 | | - [str(template.pk) for template in templates] |
1635 | | - ) |
1636 | | - } |
1637 | | - ) |
1638 | | - response = self.client.post(path, data=params, follow=True) |
1639 | | - self.assertEqual(response.status_code, 200) |
1640 | | - for template in templates: |
1641 | | - self.assertContains( |
1642 | | - response, f'class="sortedm2m" checked> {template.name}' |
1643 | | - ) |
1644 | | - return response |
1645 | | - |
1646 | | - vpn = self._create_vpn() |
1647 | | - template = self._create_template() |
1648 | | - vpn_template = self._create_template( |
1649 | | - name='vpn-test', |
1650 | | - type='vpn', |
1651 | | - vpn=vpn, |
1652 | | - auto_cert=True, |
1653 | | - ) |
1654 | | - cert_query = Cert.objects.exclude(pk=vpn.cert_id) |
1655 | | - valid_cert_query = cert_query.filter(revoked=False) |
1656 | | - revoked_cert_query = cert_query.filter(revoked=True) |
1657 | | - |
1658 | | - # Add a new device |
1659 | | - path = reverse(f'admin:{self.app_label}_device_add') |
1660 | | - params = self._get_device_params(org=self._get_org()) |
1661 | | - response = self.client.post(path, data=params, follow=True) |
1662 | | - self.assertEqual(response.status_code, 200) |
1663 | | - |
1664 | | - config = Device.objects.get(name=params['name']).config |
1665 | | - self.assertEqual(config.vpnclient_set.count(), 0) |
1666 | | - self.assertEqual(config.templates.count(), 0) |
1667 | | - |
1668 | | - path = reverse(f'admin:{self.app_label}_device_change', args=[config.device_id]) |
1669 | | - params.update( |
1670 | | - { |
1671 | | - 'config-0-id': str(config.pk), |
1672 | | - 'config-0-device': str(config.device_id), |
1673 | | - 'config-INITIAL_FORMS': 1, |
1674 | | - '_continue': True, |
1675 | | - } |
1676 | | - ) |
1677 | | - |
1678 | | - with self.subTest('Adding only VpnClient template'): |
1679 | | - # Adding VpnClient template to the device |
1680 | | - _update_template(templates=[vpn_template]) |
1681 | | - |
1682 | | - self.assertEqual(config.templates.count(), 1) |
1683 | | - self.assertEqual(config.vpnclient_set.count(), 1) |
1684 | | - self.assertEqual(cert_query.count(), 1) |
1685 | | - self.assertEqual(valid_cert_query.count(), 1) |
1686 | | - |
1687 | | - # Remove VpnClient template from the device |
1688 | | - _update_template(templates=[]) |
1689 | | - |
1690 | | - self.assertEqual(config.templates.count(), 0) |
1691 | | - self.assertEqual(config.vpnclient_set.count(), 0) |
1692 | | - # Removing VPN template marks the related certificate as revoked |
1693 | | - self.assertEqual(revoked_cert_query.count(), 1) |
1694 | | - self.assertEqual(valid_cert_query.count(), 0) |
1695 | | - |
1696 | | - with self.subTest('Add VpnClient template along with another template'): |
1697 | | - # Adding templates to the device |
1698 | | - _update_template(templates=[template, vpn_template]) |
1699 | | - |
1700 | | - self.assertEqual(config.templates.count(), 2) |
1701 | | - self.assertEqual(config.vpnclient_set.count(), 1) |
1702 | | - self.assertEqual(valid_cert_query.count(), 1) |
1703 | | - |
1704 | | - # Remove VpnClient template from the device |
1705 | | - _update_template(templates=[template]) |
1706 | | - |
1707 | | - self.assertEqual(config.templates.count(), 1) |
1708 | | - self.assertEqual(config.vpnclient_set.count(), 0) |
1709 | | - self.assertEqual(valid_cert_query.count(), 0) |
1710 | | - self.assertEqual(revoked_cert_query.count(), 2) |
1711 | | - |
1712 | 1571 | def test_ip_not_in_add_device(self): |
1713 | 1572 | path = reverse(f'admin:{self.app_label}_device_add') |
1714 | 1573 | response = self.client.get(path) |
@@ -2160,6 +2019,41 @@ def test_vpn_template_switch(self): |
2160 | 2019 | ) |
2161 | 2020 | self.assertEqual(config.vpnclient_set.count(), 1) |
2162 | 2021 |
|
| 2022 | + # helper for asserting queries executed during template fetch for a device |
| 2023 | + def _verify_template_queries(self, config, count): |
| 2024 | + path = reverse(f'admin:{self.app_label}_device_change', args=[config.device.pk]) |
| 2025 | + for i in range(count): |
| 2026 | + self._create_template(name=f'template-{i}') |
| 2027 | + expected_count = 24 |
| 2028 | + if django.VERSION < (5, 2): |
| 2029 | + # In django version < 5.2, there is an extra SAVEPOINT query |
| 2030 | + # leading to extra RELEASE SAVEPOINT query, thus 2 extra queries |
| 2031 | + expected_count += 2 |
| 2032 | + with self.assertNumQueries(expected_count): |
| 2033 | + # contains 22 queries for fetching normal device data |
| 2034 | + response = self.client.get(path) |
| 2035 | + # contains 2 queries, 1 for fetching organization |
| 2036 | + # and 1 for fetching templates |
| 2037 | + response = self.client.get( |
| 2038 | + reverse( |
| 2039 | + 'admin:get_relevant_templates', args=[config.device.organization.pk] |
| 2040 | + ) |
| 2041 | + ) |
| 2042 | + self.assertEqual(response.status_code, 200) |
| 2043 | + |
| 2044 | + # ensuring queries are consistent for different number of templates |
| 2045 | + def test_templates_fetch_queries_1(self): |
| 2046 | + config = self._create_config(organization=self._get_org()) |
| 2047 | + self._verify_template_queries(config, 1) |
| 2048 | + |
| 2049 | + def test_templates_fetch_queries_5(self): |
| 2050 | + config = self._create_config(organization=self._get_org()) |
| 2051 | + self._verify_template_queries(config, 1) |
| 2052 | + |
| 2053 | + def test_templates_fetch_queries_10(self): |
| 2054 | + config = self._create_config(organization=self._get_org()) |
| 2055 | + self._verify_template_queries(config, 1) |
| 2056 | + |
2163 | 2057 |
|
2164 | 2058 | class TestTransactionAdmin( |
2165 | 2059 | CreateConfigTemplateMixin, |
|
0 commit comments