Skip to content

Commit b049e93

Browse files
committed
fix(core): fix bug where remote_cache caused project ids to leak (#1618)
* fix(core): fix bug where remote_cache caused project ids to leak between projects * add test for instance attributes
1 parent 99a5d65 commit b049e93

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

renku/core/management/repository.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ class RepositoryApiMixin(GitCore):
113113
"requirements\\.txt",
114114
]
115115

116-
_commit_activity_cache = {}
116+
_commit_activity_cache = attr.ib(factory=dict)
117117

118-
_activity_index = None
118+
_activity_index = attr.ib(default=None)
119119

120-
_remote_cache = {}
120+
_remote_cache = attr.ib(factory=dict)
121121

122122
def __attrs_post_init__(self):
123123
"""Initialize computed attributes."""

tests/core/commands/test_client.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
# limitations under the License.
1818
"""Test Python SDK client."""
1919

20+
import inspect
21+
2022
import pytest
2123

2224

@@ -41,3 +43,53 @@ def test_local_client(tmpdir):
4143
def test_ignored_paths(paths, ignored, client):
4244
"""Test resolution of ignored paths."""
4345
assert client.find_ignored_paths(*paths) == ignored
46+
47+
48+
def test_safe_class_attributes(tmpdir):
49+
"""Test that there are no unsafe class attributes on the client.
50+
51+
This prevents us from adding class attributes that might leak in a threaded environment.
52+
If you do add a class attribute and want to add it to the list of safe_attributes,
53+
make sure that it's not something that can leak between calls, e.g. in the service.
54+
"""
55+
from renku.core.management.client import LocalClient
56+
57+
# NOTE: attributes that are allowed on LocalClient
58+
safe_attributes = [
59+
"ACTIVITY_INDEX",
60+
"CACHE",
61+
"CONFIG_NAME",
62+
"DATASETS",
63+
"DATA_DIR_CONFIG_KEY",
64+
"LOCK_SUFFIX",
65+
"METADATA",
66+
"POINTERS",
67+
"RENKU_LFS_IGNORE_PATH",
68+
"RENKU_PROTECTED_PATHS",
69+
"WORKFLOW",
70+
"_CMD_STORAGE_CHECKOUT",
71+
"_CMD_STORAGE_CLEAN",
72+
"_CMD_STORAGE_INSTALL",
73+
"_CMD_STORAGE_LIST",
74+
"_CMD_STORAGE_MIGRATE_INFO",
75+
"_CMD_STORAGE_PULL",
76+
"_CMD_STORAGE_STATUS",
77+
"_CMD_STORAGE_TRACK",
78+
"_CMD_STORAGE_UNTRACK",
79+
"_LFS_HEADER",
80+
"_global_config_dir",
81+
]
82+
83+
client1 = LocalClient(str(tmpdir.mkdir("project1")))
84+
85+
client2 = LocalClient(str(tmpdir.mkdir("project2")))
86+
class_attributes = inspect.getmembers(LocalClient, lambda a: not (inspect.isroutine(a)))
87+
class_attributes = [a for a in class_attributes if not a[0].startswith("__") and not a[0].endswith("__")]
88+
identical_attributes = []
89+
for a, v in class_attributes:
90+
if a in safe_attributes or isinstance(v, property):
91+
continue
92+
if id(getattr(client1, a)) == id(getattr(client2, a)):
93+
identical_attributes.append(a)
94+
95+
assert not identical_attributes

0 commit comments

Comments
 (0)