Skip to content

Commit 76960cb

Browse files
authored
[DPE-2804] Conditional backup tests (#269)
* Conditional backup tests * Bump libs
1 parent 1e73df9 commit 76960cb

File tree

5 files changed

+47
-10
lines changed

5 files changed

+47
-10
lines changed

.github/workflows/ci.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,14 @@ jobs:
123123
echo Skipping unstable tests
124124
echo "mark_expression=and not unstable" >> "$GITHUB_OUTPUT"
125125
fi
126+
- name: Select test secret usage
127+
id: select-test-secrets
128+
if: ${{ github.event.pull_request.head.repo.full_name != 'canonical/postgresql-operator' }}
129+
run: |
130+
echo Skipping tests using secrets
131+
echo "mark_secrets=and not uses_secrets" >> "$GITHUB_OUTPUT"
126132
- name: Run integration tests
127-
run: tox run -e ${{ matrix.tox-environment }} -- -m 'not ${{ matrix.exclude-mark }} ${{ steps.select-test-stability.outputs.mark_expression }}' --keep-models
133+
run: tox run -e ${{ matrix.tox-environment }} -- -m 'not ${{ matrix.exclude-mark }} ${{ steps.select-test-secrets.outputs.mark_secrets }} ${{ steps.select-test-stability.outputs.mark_expression }}' --keep-models
128134
env:
129135
SECRETS_FROM_GITHUB: |
130136
{

lib/charms/data_platform_libs/v0/data_interfaces.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
320320

321321
# Increment this PATCH version before using `charmcraft publish-lib` or reset
322322
# to 0 if you are raising the major API version
323-
LIBPATCH = 22
323+
LIBPATCH = 23
324324

325325
PYDEPS = ["ops>=2.0.0"]
326326

@@ -807,6 +807,9 @@ def _fetch_relation_data_without_secrets(
807807
This is used typically when the Provides side wants to read the Requires side's data,
808808
or when the Requires side may want to read its own data.
809809
"""
810+
if app not in relation.data or not relation.data[app]:
811+
return {}
812+
810813
if fields:
811814
return {k: relation.data[app][k] for k in fields if k in relation.data[app]}
812815
else:
@@ -830,6 +833,9 @@ def _fetch_relation_data_with_secrets(
830833
normal_fields = []
831834

832835
if not fields:
836+
if app not in relation.data or not relation.data[app]:
837+
return {}
838+
833839
all_fields = list(relation.data[app].keys())
834840
normal_fields = [field for field in all_fields if not self._is_secret_field(field)]
835841

@@ -853,8 +859,11 @@ def _fetch_relation_data_with_secrets(
853859

854860
def _update_relation_data_without_secrets(
855861
self, app: Application, relation: Relation, data: Dict[str, str]
856-
):
862+
) -> None:
857863
"""Updating databag contents when no secrets are involved."""
864+
if app not in relation.data or relation.data[app] is None:
865+
return
866+
858867
if any(self._is_secret_field(key) for key in data.keys()):
859868
raise SecretsIllegalUpdateError("Can't update secret {key}.")
860869

@@ -865,8 +874,19 @@ def _delete_relation_data_without_secrets(
865874
self, app: Application, relation: Relation, fields: List[str]
866875
) -> None:
867876
"""Remove databag fields 'fields' from Relation."""
877+
if app not in relation.data or not relation.data[app]:
878+
return
879+
868880
for field in fields:
869-
relation.data[app].pop(field)
881+
try:
882+
relation.data[app].pop(field)
883+
except KeyError:
884+
logger.debug(
885+
"Non-existing field was attempted to be removed from the databag %s, %s",
886+
str(relation.id),
887+
str(field),
888+
)
889+
pass
870890

871891
# Public interface methods
872892
# Handling Relation Fields seamlessly, regardless if in databag or a Juju Secret
@@ -880,9 +900,6 @@ def get_relation(self, relation_name, relation_id) -> Relation:
880900
"Relation %s %s couldn't be retrieved", relation_name, relation_id
881901
)
882902

883-
if not relation.app:
884-
raise DataInterfacesError("Relation's application missing")
885-
886903
return relation
887904

888905
def fetch_relation_data(
@@ -1089,7 +1106,10 @@ def _delete_relation_secret(
10891106
# Remove secret from the relation if it's fully gone
10901107
if not new_content:
10911108
field = self._generate_secret_field_name(group)
1092-
relation.data[self.local_app].pop(field)
1109+
try:
1110+
relation.data[self.local_app].pop(field)
1111+
except KeyError:
1112+
pass
10931113

10941114
# Return the content that was removed
10951115
return True

lib/charms/postgresql_k8s/v0/postgresql.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
# Increment this PATCH version before using `charmcraft publish-lib` or reset
3434
# to 0 if you are raising the major API version
35-
LIBPATCH = 18
35+
LIBPATCH = 19
3636

3737
INVALID_EXTRA_USER_ROLE_BLOCKING_MESSAGE = "invalid role(s) for extra user roles"
3838

@@ -514,7 +514,7 @@ def build_postgresql_parameters(
514514
)
515515
if profile == "production":
516516
# Use 25% of the available memory for shared_buffers.
517-
# and the remaind as cache memory.
517+
# and the remaining as cache memory.
518518
shared_buffers = int(available_memory * 0.25)
519519
effective_cache_size = int(available_memory - shared_buffers)
520520
parameters.setdefault("shared_buffers", f"{int(shared_buffers/10**6)}MB")

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ target-version = ["py38"]
9999

100100
# Linting tools configuration
101101
[tool.ruff]
102+
# preview and explicit preview are enabled for CPY001
103+
preview = true
104+
explicit-preview-rules = true
102105
target-version = "py38"
103106
src = ["src", "."]
104107
line-length = 99

tests/integration/test_backups.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ async def cloud_configs(ops_test: OpsTest, github_secrets) -> None:
7979
bucket_object.delete()
8080

8181

82+
async def test_none() -> None:
83+
"""Empty test so that the suite will not fail if all tests are skippedi."""
84+
pass
85+
86+
87+
@pytest.mark.uses_secrets
8288
@pytest.mark.abort_on_fail
8389
async def test_backup(ops_test: OpsTest, cloud_configs: Tuple[Dict, Dict]) -> None:
8490
"""Build and deploy two units of PostgreSQL and then test the backup and restore actions."""
@@ -216,6 +222,7 @@ async def test_backup(ops_test: OpsTest, cloud_configs: Tuple[Dict, Dict]) -> No
216222
await ops_test.model.remove_application(TLS_CERTIFICATES_APP_NAME, block_until_done=True)
217223

218224

225+
@pytest.mark.uses_secrets
219226
async def test_restore_on_new_cluster(ops_test: OpsTest) -> None:
220227
"""Test that is possible to restore a backup to another PostgreSQL cluster."""
221228
charm = await ops_test.build_charm(".")
@@ -293,6 +300,7 @@ async def test_restore_on_new_cluster(ops_test: OpsTest) -> None:
293300
connection.close()
294301

295302

303+
@pytest.mark.uses_secrets
296304
async def test_invalid_config_and_recovery_after_fixing_it(
297305
ops_test: OpsTest, cloud_configs: Tuple[Dict, Dict]
298306
) -> None:

0 commit comments

Comments
 (0)