qontract-reconcile 0.9.1rc274__py3-none-any.whl → 0.9.1rc275__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.9.1rc274
3
+ Version: 0.9.1rc275
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Home-page: https://github.com/app-sre/qontract-reconcile
6
6
  Author: Red Hat App-SRE Team
@@ -258,9 +258,9 @@ reconcile/jenkins/types.py,sha256=-WMs4TsCEcbJNF_n-615Fealk08boBYZcTzVUk3Wlns,26
258
258
  reconcile/ocm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
259
259
  reconcile/ocm/types.py,sha256=gCuVra66cIk2Wvoj8PQ-hvsZiozFDFXxUOilPdC0w-c,3138
260
260
  reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
- reconcile/saas_auto_promotions_manager/integration.py,sha256=EAQipdFjlwbKUENTlnd_UKoUYy3LHjRD9K-LXFOvFe0,6208
261
+ reconcile/saas_auto_promotions_manager/integration.py,sha256=hmRWva3_ZEO845wMkttEt4X6Izl5p8ZKs09NXWp8mkY,5609
262
262
  reconcile/saas_auto_promotions_manager/publisher.py,sha256=gdzR7jNDKy130pO6J-UNwXI__EXgiREzdaXvNkE3Bhg,1845
263
- reconcile/saas_auto_promotions_manager/subscriber.py,sha256=JsS_wrCGZC3-86kHSUTq8veLpdGH6XFL_zqlXKx-eNk,5891
263
+ reconcile/saas_auto_promotions_manager/subscriber.py,sha256=PAncXY973uGMAHZRkV7QqSYSHhyZO_SuLGhwCn0pukI,6177
264
264
  reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
265
265
  reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=diDb4BkErloZF6MfzQbMkqC1gx8tglYkw10Vuf_4_Ho,1147
266
266
  reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py,sha256=QVaaL0hQn0fy-NPmoKyJMp3NxNfE8umYjReaTztxCps,9763
@@ -406,12 +406,13 @@ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_
406
406
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py,sha256=lpMMllzRYzq-WI5JAyX6B9-VOK8N5IBFJn7KUMuvKxk,2008
407
407
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py,sha256=cwAPrQ_v3DR_CHU7Nt2xBGutC-1XslyJ5mXM8FXW-3o,1111
408
408
  reconcile/test/saas_auto_promotions_manager/subscriber/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
409
- reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py,sha256=IShISmgW0FECL82wIy6wFUpCxIKlVIg2WngtpY5Dxxg,2843
409
+ reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py,sha256=R4xSKYtRDeCs2c2d5WTfRnqW9br8p54H8jtP0K-WMmg,2428
410
410
  reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py,sha256=0MPM188d-7kUcqFvOEsjMEhJpSlPZua8rQvlto_50PE,360
411
411
  reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py,sha256=6Nkyix3Uyf7Zd9t2C6RnYlQG_y3NsZ6v6zu3G-qF4to,5186
412
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py,sha256=5D9EHJ83304sFZqIQqCFsXI8icAD1bVhhlHfLZfgBag,5805
413
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py,sha256=gB2u4DshlrbiD9r8zw5CNQhOP_bJw10VHu-sEoJudts,5567
414
- reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py,sha256=QPhzVw5dCMj0ZzjbkN8G-MF_39DefBaY9Zo_tLsnt6o,8040
412
+ reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py,sha256=GoCl8m63ikzd0fqlqS0z5VwgSVAZSkKk8d0lDbOoS08,2521
413
+ reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py,sha256=1xdM2gJ4Q6ew1xeHijMrrZx_R7UYbIchlg-bSDLO_x4,6955
414
+ reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py,sha256=Q0YLTz-tTyYcyS0OeDuy5EKwdbIwr2tcoaDK6YnXwWo,6717
415
+ reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py,sha256=UaKEgI_yMaILEiD-f9sl7FmlEiTICptSC4roapwE8tY,8642
415
416
  reconcile/test/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
416
417
  reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
417
418
  reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py,sha256=A2bw4U2jcwpQpTd8nab2Pe7QeF-__2CEJp8kWocVHVc,2414
@@ -563,8 +564,8 @@ tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y
563
564
  tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
564
565
  tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
565
566
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
566
- qontract_reconcile-0.9.1rc274.dist-info/METADATA,sha256=xthG7Wqcl1nyjbzY_r0nq6MIqEuaG0bJ0TsErFkHVfs,2287
567
- qontract_reconcile-0.9.1rc274.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
568
- qontract_reconcile-0.9.1rc274.dist-info/entry_points.txt,sha256=aIVvB7OTCxYu0QkONzBPfFEyg68Pr8KUVKEEm4ChDVc,333
569
- qontract_reconcile-0.9.1rc274.dist-info/top_level.txt,sha256=j0CHPIc8TsVRB50wOz_jhxjjaRyCJB3NOQeXhuHS67c,34
570
- qontract_reconcile-0.9.1rc274.dist-info/RECORD,,
567
+ qontract_reconcile-0.9.1rc275.dist-info/METADATA,sha256=_flJtRC5kagWx1H5IKnB2RlUXZWqepaSiNJnfWvtUbY,2287
568
+ qontract_reconcile-0.9.1rc275.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
569
+ qontract_reconcile-0.9.1rc275.dist-info/entry_points.txt,sha256=aIVvB7OTCxYu0QkONzBPfFEyg68Pr8KUVKEEm4ChDVc,333
570
+ qontract_reconcile-0.9.1rc275.dist-info/top_level.txt,sha256=j0CHPIc8TsVRB50wOz_jhxjjaRyCJB3NOQeXhuHS67c,34
571
+ qontract_reconcile-0.9.1rc275.dist-info/RECORD,,
@@ -13,10 +13,7 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer impor
13
13
  Renderer,
14
14
  )
15
15
  from reconcile.saas_auto_promotions_manager.publisher import Publisher
16
- from reconcile.saas_auto_promotions_manager.subscriber import (
17
- ConfigHash,
18
- Subscriber,
19
- )
16
+ from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
20
17
  from reconcile.saas_auto_promotions_manager.utils.saas_files_inventory import (
21
18
  SaasFilesInventory,
22
19
  )
@@ -77,20 +74,7 @@ class SaasAutoPromotionsManager:
77
74
  subscriber.compute_desired_state()
78
75
 
79
76
  def _get_subscribers_with_diff(self) -> list[Subscriber]:
80
- subscribers_with_diff: list[Subscriber] = []
81
- for subscriber in self._saas_file_inventory.subscribers:
82
- current_hashes: list[ConfigHash] = []
83
- for s in subscriber.config_hashes_by_channel_name.values():
84
- for el in s:
85
- current_hashes.append(el)
86
- if (
87
- set(subscriber.desired_hashes) == set(current_hashes)
88
- and subscriber.desired_ref == subscriber.ref
89
- ):
90
- # There is no change that requires a promotion
91
- continue
92
- subscribers_with_diff.append(subscriber)
93
- return subscribers_with_diff
77
+ return [s for s in self._saas_file_inventory.subscribers if s.has_diff()]
94
78
 
95
79
  def reconcile(self) -> None:
96
80
  self._deployment_state.cache_commit_shas_from_s3()
@@ -45,6 +45,15 @@ class Subscriber:
45
45
  self.namespace_file_path = namespace_file_path
46
46
  self._content_hash = ""
47
47
 
48
+ def has_diff(self) -> bool:
49
+ current_hashes = {
50
+ el for s in self.config_hashes_by_channel_name.values() for el in s
51
+ }
52
+ return not (
53
+ set(self.desired_hashes) == set(current_hashes)
54
+ and self.desired_ref == self.ref
55
+ )
56
+
48
57
  def compute_desired_state(self) -> None:
49
58
  self._compute_desired_ref()
50
59
  self._compute_desired_config_hashes()
@@ -1,7 +1,6 @@
1
1
  from collections import defaultdict
2
2
  from collections.abc import (
3
3
  Callable,
4
- Iterable,
5
4
  Mapping,
6
5
  )
7
6
  from typing import Any
@@ -23,6 +22,8 @@ from .data_keys import (
23
22
  CONFIG_HASH,
24
23
  CUR_CONFIG_HASHES,
25
24
  CUR_SUBSCRIBER_REF,
25
+ DESIRED_REF,
26
+ DESIRED_TARGET_HASHES,
26
27
  NAMESPACE_REF,
27
28
  REAL_WORLD_SHA,
28
29
  SUCCESSFUL_DEPLOYMENT,
@@ -30,23 +31,6 @@ from .data_keys import (
30
31
  )
31
32
 
32
33
 
33
- @pytest.fixture
34
- def config_hashes_builder() -> Callable[
35
- [Iterable[tuple[str, str, str]]], list[ConfigHash]
36
- ]:
37
- def builder(data: Iterable[tuple[str, str, str]]) -> list[ConfigHash]:
38
- return [
39
- ConfigHash(
40
- channel=d[0],
41
- parent_saas=d[1],
42
- target_config_hash=d[2],
43
- )
44
- for d in data
45
- ]
46
-
47
- return builder
48
-
49
-
50
34
  @pytest.fixture
51
35
  def subscriber_builder() -> Callable[[Mapping[str, Any]], Subscriber]:
52
36
  def builder(data: Mapping[str, Any]) -> Subscriber:
@@ -69,12 +53,8 @@ def subscriber_builder() -> Callable[[Mapping[str, Any]], Subscriber]:
69
53
  channels.append(channel)
70
54
  cur_config_hashes_by_channel: dict[str, list[ConfigHash]] = defaultdict(list)
71
55
  for cur_config_hash in data.get(CUR_CONFIG_HASHES, []):
72
- cur_config_hashes_by_channel[cur_config_hash[0]].append(
73
- ConfigHash(
74
- channel=cur_config_hash[0],
75
- parent_saas=cur_config_hash[1],
76
- target_config_hash=cur_config_hash[2],
77
- )
56
+ cur_config_hashes_by_channel[cur_config_hash.channel].append(
57
+ cur_config_hash
78
58
  )
79
59
  subscriber = Subscriber(
80
60
  namespace_file_path=data.get(NAMESPACE_REF, ""),
@@ -85,6 +65,8 @@ def subscriber_builder() -> Callable[[Mapping[str, Any]], Subscriber]:
85
65
  )
86
66
  subscriber.channels = channels
87
67
  subscriber.config_hashes_by_channel_name = cur_config_hashes_by_channel
68
+ subscriber.desired_ref = data.get(DESIRED_REF, "")
69
+ subscriber.desired_hashes = data.get(DESIRED_TARGET_HASHES, [])
88
70
  return subscriber
89
71
 
90
72
  return builder
@@ -0,0 +1,93 @@
1
+ from collections.abc import (
2
+ Callable,
3
+ Mapping,
4
+ )
5
+ from typing import Any
6
+
7
+ from reconcile.saas_auto_promotions_manager.subscriber import (
8
+ ConfigHash,
9
+ Subscriber,
10
+ )
11
+
12
+ from .data_keys import (
13
+ CUR_CONFIG_HASHES,
14
+ CUR_SUBSCRIBER_REF,
15
+ DESIRED_REF,
16
+ DESIRED_TARGET_HASHES,
17
+ )
18
+
19
+
20
+ def test_has_config_hash_diff(
21
+ subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
22
+ ) -> None:
23
+ subscriber = subscriber_builder(
24
+ {
25
+ CUR_SUBSCRIBER_REF: "current_sha",
26
+ CUR_CONFIG_HASHES: [
27
+ ConfigHash(
28
+ channel="channel-a",
29
+ parent_saas="publisher_a",
30
+ target_config_hash="pub_a_hash",
31
+ ),
32
+ ConfigHash(
33
+ channel="channel-b",
34
+ parent_saas="publisher_b",
35
+ target_config_hash="pub_b_hash",
36
+ ),
37
+ ],
38
+ DESIRED_REF: "current_sha",
39
+ DESIRED_TARGET_HASHES: [
40
+ ConfigHash(
41
+ channel="channel-a",
42
+ parent_saas="publisher_a",
43
+ target_config_hash="pub_a_hash",
44
+ ),
45
+ ConfigHash(
46
+ channel="channel-b",
47
+ parent_saas="publisher_b",
48
+ target_config_hash="new_hash",
49
+ ),
50
+ ],
51
+ }
52
+ )
53
+ assert subscriber.has_diff()
54
+
55
+
56
+ def test_has_ref_diff(
57
+ subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
58
+ ) -> None:
59
+ subscriber = subscriber_builder(
60
+ {
61
+ CUR_SUBSCRIBER_REF: "current_sha",
62
+ CUR_CONFIG_HASHES: [],
63
+ DESIRED_REF: "new_sha",
64
+ DESIRED_TARGET_HASHES: [],
65
+ }
66
+ )
67
+ assert subscriber.has_diff()
68
+
69
+
70
+ def test_no_diff(
71
+ subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
72
+ ) -> None:
73
+ config_hashes = [
74
+ ConfigHash(
75
+ channel="channel-a",
76
+ parent_saas="publisher_a",
77
+ target_config_hash="pub_a_hash",
78
+ ),
79
+ ConfigHash(
80
+ channel="channel-b",
81
+ parent_saas="publisher_b",
82
+ target_config_hash="pub_b_hash",
83
+ ),
84
+ ]
85
+ subscriber = subscriber_builder(
86
+ {
87
+ CUR_SUBSCRIBER_REF: "current_sha",
88
+ CUR_CONFIG_HASHES: config_hashes,
89
+ DESIRED_REF: "current_sha",
90
+ DESIRED_TARGET_HASHES: list(reversed(config_hashes)),
91
+ }
92
+ )
93
+ assert not subscriber.has_diff()
@@ -1,6 +1,5 @@
1
1
  from collections.abc import (
2
2
  Callable,
3
- Iterable,
4
3
  Mapping,
5
4
  )
6
5
  from typing import Any
@@ -22,16 +21,21 @@ from .data_keys import (
22
21
 
23
22
  def test_single_new_config_hash(
24
23
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
25
- config_hashes_builder: Callable[
26
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
27
- ],
28
24
  ):
29
25
  subscriber = subscriber_builder(
30
26
  {
31
27
  CUR_SUBSCRIBER_REF: "current_sha",
32
28
  CUR_CONFIG_HASHES: [
33
- ("channel-a", "publisher_a", "pub_a_hash"),
34
- ("channel-b", "publisher_b", "pub_b_hash"),
29
+ ConfigHash(
30
+ channel="channel-a",
31
+ parent_saas="publisher_a",
32
+ target_config_hash="pub_a_hash",
33
+ ),
34
+ ConfigHash(
35
+ channel="channel-b",
36
+ parent_saas="publisher_b",
37
+ target_config_hash="pub_b_hash",
38
+ ),
35
39
  ],
36
40
  CHANNELS: {
37
41
  "channel-a": {
@@ -50,28 +54,39 @@ def test_single_new_config_hash(
50
54
  }
51
55
  )
52
56
  subscriber.compute_desired_state()
53
- expected_config_hashes = config_hashes_builder(
54
- [
55
- ("channel-a", "publisher_a", "new_pub_a_hash"),
56
- ("channel-b", "publisher_b", "pub_b_hash"),
57
- ]
58
- )
57
+ expected_config_hashes = [
58
+ ConfigHash(
59
+ channel="channel-a",
60
+ parent_saas="publisher_a",
61
+ target_config_hash="new_pub_a_hash",
62
+ ),
63
+ ConfigHash(
64
+ channel="channel-b",
65
+ parent_saas="publisher_b",
66
+ target_config_hash="pub_b_hash",
67
+ ),
68
+ ]
59
69
  assert subscriber.desired_ref == "current_sha"
60
70
  assert subscriber.desired_hashes == expected_config_hashes
61
71
 
62
72
 
63
73
  def test_both_new_config_hashes(
64
74
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
65
- config_hashes_builder: Callable[
66
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
67
- ],
68
75
  ):
69
76
  subscriber = subscriber_builder(
70
77
  {
71
78
  CUR_SUBSCRIBER_REF: "current_sha",
72
79
  CUR_CONFIG_HASHES: [
73
- ("channel-a", "publisher_a", "pub_a_hash"),
74
- ("channel-b", "publisher_b", "pub_b_hash"),
80
+ ConfigHash(
81
+ channel="channel-a",
82
+ parent_saas="publisher_a",
83
+ target_config_hash="pub_a_hash",
84
+ ),
85
+ ConfigHash(
86
+ channel="channel-b",
87
+ parent_saas="publisher_b",
88
+ target_config_hash="pub_b_hash",
89
+ ),
75
90
  ],
76
91
  CHANNELS: {
77
92
  "channel-a": {
@@ -90,28 +105,39 @@ def test_both_new_config_hashes(
90
105
  }
91
106
  )
92
107
  subscriber.compute_desired_state()
93
- expected_config_hashes = config_hashes_builder(
94
- [
95
- ("channel-a", "publisher_a", "new_pub_a_hash"),
96
- ("channel-b", "publisher_b", "new_pub_b_hash"),
97
- ]
98
- )
108
+ expected_config_hashes = [
109
+ ConfigHash(
110
+ channel="channel-a",
111
+ parent_saas="publisher_a",
112
+ target_config_hash="new_pub_a_hash",
113
+ ),
114
+ ConfigHash(
115
+ channel="channel-b",
116
+ parent_saas="publisher_b",
117
+ target_config_hash="new_pub_b_hash",
118
+ ),
119
+ ]
99
120
  assert subscriber.desired_ref == "current_sha"
100
121
  assert subscriber.desired_hashes == expected_config_hashes
101
122
 
102
123
 
103
124
  def test_both_new_config_hashes_one_bad_deployment(
104
125
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
105
- config_hashes_builder: Callable[
106
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
107
- ],
108
126
  ):
109
127
  subscriber = subscriber_builder(
110
128
  {
111
129
  CUR_SUBSCRIBER_REF: "current_sha",
112
130
  CUR_CONFIG_HASHES: [
113
- ("channel-a", "publisher_a", "pub_a_hash"),
114
- ("channel-b", "publisher_b", "pub_b_hash"),
131
+ ConfigHash(
132
+ channel="channel-a",
133
+ parent_saas="publisher_a",
134
+ target_config_hash="pub_a_hash",
135
+ ),
136
+ ConfigHash(
137
+ channel="channel-b",
138
+ parent_saas="publisher_b",
139
+ target_config_hash="pub_b_hash",
140
+ ),
115
141
  ],
116
142
  CHANNELS: {
117
143
  "channel-a": {
@@ -131,28 +157,39 @@ def test_both_new_config_hashes_one_bad_deployment(
131
157
  }
132
158
  )
133
159
  subscriber.compute_desired_state()
134
- expected_config_hashes = config_hashes_builder(
135
- [
136
- ("channel-a", "publisher_a", "pub_a_hash"),
137
- ("channel-b", "publisher_b", "new_pub_b_hash"),
138
- ]
139
- )
160
+ expected_config_hashes = [
161
+ ConfigHash(
162
+ channel="channel-a",
163
+ parent_saas="publisher_a",
164
+ target_config_hash="pub_a_hash",
165
+ ),
166
+ ConfigHash(
167
+ channel="channel-b",
168
+ parent_saas="publisher_b",
169
+ target_config_hash="new_pub_b_hash",
170
+ ),
171
+ ]
140
172
  assert subscriber.desired_ref == "current_sha"
141
173
  assert subscriber.desired_hashes == expected_config_hashes
142
174
 
143
175
 
144
176
  def test_both_new_config_hashes_all_bad_deployments(
145
177
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
146
- config_hashes_builder: Callable[
147
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
148
- ],
149
178
  ):
150
179
  subscriber = subscriber_builder(
151
180
  {
152
181
  CUR_SUBSCRIBER_REF: "current_sha",
153
182
  CUR_CONFIG_HASHES: [
154
- ("channel-a", "publisher_a", "pub_a_hash"),
155
- ("channel-b", "publisher_b", "pub_b_hash"),
183
+ ConfigHash(
184
+ channel="channel-a",
185
+ parent_saas="publisher_a",
186
+ target_config_hash="pub_a_hash",
187
+ ),
188
+ ConfigHash(
189
+ channel="channel-b",
190
+ parent_saas="publisher_b",
191
+ target_config_hash="pub_b_hash",
192
+ ),
156
193
  ],
157
194
  CHANNELS: {
158
195
  "channel-a": {
@@ -173,11 +210,17 @@ def test_both_new_config_hashes_all_bad_deployments(
173
210
  }
174
211
  )
175
212
  subscriber.compute_desired_state()
176
- expected_config_hashes = config_hashes_builder(
177
- [
178
- ("channel-a", "publisher_a", "pub_a_hash"),
179
- ("channel-b", "publisher_b", "pub_b_hash"),
180
- ]
181
- )
213
+ expected_config_hashes = [
214
+ ConfigHash(
215
+ channel="channel-a",
216
+ parent_saas="publisher_a",
217
+ target_config_hash="pub_a_hash",
218
+ ),
219
+ ConfigHash(
220
+ channel="channel-b",
221
+ parent_saas="publisher_b",
222
+ target_config_hash="pub_b_hash",
223
+ ),
224
+ ]
182
225
  assert subscriber.desired_ref == "current_sha"
183
226
  assert subscriber.desired_hashes == expected_config_hashes
@@ -1,6 +1,5 @@
1
1
  from collections.abc import (
2
2
  Callable,
3
- Iterable,
4
3
  Mapping,
5
4
  )
6
5
  from typing import Any
@@ -22,16 +21,21 @@ from .data_keys import (
22
21
 
23
22
  def test_no_change(
24
23
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
25
- config_hashes_builder: Callable[
26
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
27
- ],
28
24
  ):
29
25
  subscriber = subscriber_builder(
30
26
  {
31
27
  CUR_SUBSCRIBER_REF: "current_sha",
32
28
  CUR_CONFIG_HASHES: [
33
- ("channel-a", "publisher_a", "pub_a_hash"),
34
- ("channel-b", "publisher_b", "pub_b_hash"),
29
+ ConfigHash(
30
+ channel="channel-a",
31
+ parent_saas="publisher_a",
32
+ target_config_hash="pub_a_hash",
33
+ ),
34
+ ConfigHash(
35
+ channel="channel-b",
36
+ parent_saas="publisher_b",
37
+ target_config_hash="pub_b_hash",
38
+ ),
35
39
  ],
36
40
  CHANNELS: {
37
41
  "channel-a": {
@@ -50,28 +54,39 @@ def test_no_change(
50
54
  }
51
55
  )
52
56
  subscriber.compute_desired_state()
53
- expected_config_hashes = config_hashes_builder(
54
- [
55
- ("channel-a", "publisher_a", "pub_a_hash"),
56
- ("channel-b", "publisher_b", "pub_b_hash"),
57
- ]
58
- )
57
+ expected_config_hashes = [
58
+ ConfigHash(
59
+ channel="channel-a",
60
+ parent_saas="publisher_a",
61
+ target_config_hash="pub_a_hash",
62
+ ),
63
+ ConfigHash(
64
+ channel="channel-b",
65
+ parent_saas="publisher_b",
66
+ target_config_hash="pub_b_hash",
67
+ ),
68
+ ]
59
69
  assert subscriber.desired_ref == "current_sha"
60
70
  assert subscriber.desired_hashes == expected_config_hashes
61
71
 
62
72
 
63
73
  def test_moving_ref(
64
74
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
65
- config_hashes_builder: Callable[
66
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
67
- ],
68
75
  ):
69
76
  subscriber = subscriber_builder(
70
77
  {
71
78
  CUR_SUBSCRIBER_REF: "current_sha",
72
79
  CUR_CONFIG_HASHES: [
73
- ("channel-a", "publisher_a", "pub_a_hash"),
74
- ("channel-b", "publisher_b", "pub_b_hash"),
80
+ ConfigHash(
81
+ channel="channel-a",
82
+ parent_saas="publisher_a",
83
+ target_config_hash="pub_a_hash",
84
+ ),
85
+ ConfigHash(
86
+ channel="channel-b",
87
+ parent_saas="publisher_b",
88
+ target_config_hash="pub_b_hash",
89
+ ),
75
90
  ],
76
91
  CHANNELS: {
77
92
  "channel-a": {
@@ -90,28 +105,39 @@ def test_moving_ref(
90
105
  }
91
106
  )
92
107
  subscriber.compute_desired_state()
93
- expected_config_hashes = config_hashes_builder(
94
- [
95
- ("channel-a", "publisher_a", "pub_a_hash"),
96
- ("channel-b", "publisher_b", "pub_b_hash"),
97
- ]
98
- )
108
+ expected_config_hashes = [
109
+ ConfigHash(
110
+ channel="channel-a",
111
+ parent_saas="publisher_a",
112
+ target_config_hash="pub_a_hash",
113
+ ),
114
+ ConfigHash(
115
+ channel="channel-b",
116
+ parent_saas="publisher_b",
117
+ target_config_hash="pub_b_hash",
118
+ ),
119
+ ]
99
120
  assert subscriber.desired_ref == "new_sha"
100
121
  assert subscriber.desired_hashes == expected_config_hashes
101
122
 
102
123
 
103
124
  def test_moving_ref_mismatch(
104
125
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
105
- config_hashes_builder: Callable[
106
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
107
- ],
108
126
  ):
109
127
  subscriber = subscriber_builder(
110
128
  {
111
129
  CUR_SUBSCRIBER_REF: "current_sha",
112
130
  CUR_CONFIG_HASHES: [
113
- ("channel-a", "publisher_a", "pub_a_hash"),
114
- ("channel-b", "publisher_b", "pub_b_hash"),
131
+ ConfigHash(
132
+ channel="channel-a",
133
+ parent_saas="publisher_a",
134
+ target_config_hash="pub_a_hash",
135
+ ),
136
+ ConfigHash(
137
+ channel="channel-b",
138
+ parent_saas="publisher_b",
139
+ target_config_hash="pub_b_hash",
140
+ ),
115
141
  ],
116
142
  CHANNELS: {
117
143
  "channel-a": {
@@ -130,28 +156,39 @@ def test_moving_ref_mismatch(
130
156
  }
131
157
  )
132
158
  subscriber.compute_desired_state()
133
- expected_config_hashes = config_hashes_builder(
134
- [
135
- ("channel-a", "publisher_a", "pub_a_hash"),
136
- ("channel-b", "publisher_b", "pub_b_hash"),
137
- ]
138
- )
159
+ expected_config_hashes = [
160
+ ConfigHash(
161
+ channel="channel-a",
162
+ parent_saas="publisher_a",
163
+ target_config_hash="pub_a_hash",
164
+ ),
165
+ ConfigHash(
166
+ channel="channel-b",
167
+ parent_saas="publisher_b",
168
+ target_config_hash="pub_b_hash",
169
+ ),
170
+ ]
139
171
  assert subscriber.desired_ref == "current_sha"
140
172
  assert subscriber.desired_hashes == expected_config_hashes
141
173
 
142
174
 
143
175
  def test_moving_ref_bad_deployment(
144
176
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
145
- config_hashes_builder: Callable[
146
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
147
- ],
148
177
  ):
149
178
  subscriber = subscriber_builder(
150
179
  {
151
180
  CUR_SUBSCRIBER_REF: "current_sha",
152
181
  CUR_CONFIG_HASHES: [
153
- ("channel-a", "publisher_a", "pub_a_hash"),
154
- ("channel-b", "publisher_b", "pub_b_hash"),
182
+ ConfigHash(
183
+ channel="channel-a",
184
+ parent_saas="publisher_a",
185
+ target_config_hash="pub_a_hash",
186
+ ),
187
+ ConfigHash(
188
+ channel="channel-b",
189
+ parent_saas="publisher_b",
190
+ target_config_hash="pub_b_hash",
191
+ ),
155
192
  ],
156
193
  CHANNELS: {
157
194
  "channel-a": {
@@ -171,11 +208,17 @@ def test_moving_ref_bad_deployment(
171
208
  }
172
209
  )
173
210
  subscriber.compute_desired_state()
174
- expected_config_hashes = config_hashes_builder(
175
- [
176
- ("channel-a", "publisher_a", "pub_a_hash"),
177
- ("channel-b", "publisher_b", "pub_b_hash"),
178
- ]
179
- )
211
+ expected_config_hashes = [
212
+ ConfigHash(
213
+ channel="channel-a",
214
+ parent_saas="publisher_a",
215
+ target_config_hash="pub_a_hash",
216
+ ),
217
+ ConfigHash(
218
+ channel="channel-b",
219
+ parent_saas="publisher_b",
220
+ target_config_hash="pub_b_hash",
221
+ ),
222
+ ]
180
223
  assert subscriber.desired_ref == "current_sha"
181
224
  assert subscriber.desired_hashes == expected_config_hashes
@@ -1,6 +1,5 @@
1
1
  from collections.abc import (
2
2
  Callable,
3
- Iterable,
4
3
  Mapping,
5
4
  )
6
5
  from typing import Any
@@ -22,15 +21,16 @@ from .data_keys import (
22
21
 
23
22
  def test_no_change(
24
23
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
25
- config_hashes_builder: Callable[
26
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
27
- ],
28
24
  ):
29
25
  subscriber = subscriber_builder(
30
26
  {
31
27
  CUR_SUBSCRIBER_REF: "current_sha",
32
28
  CUR_CONFIG_HASHES: [
33
- ("channel-a", "publisher_a", "current_hash"),
29
+ ConfigHash(
30
+ channel="channel-a",
31
+ parent_saas="publisher_a",
32
+ target_config_hash="current_hash",
33
+ ),
34
34
  ],
35
35
  CHANNELS: {
36
36
  "channel-a": {
@@ -43,24 +43,29 @@ def test_no_change(
43
43
  }
44
44
  )
45
45
  subscriber.compute_desired_state()
46
- expected_config_hashes = config_hashes_builder(
47
- [("channel-a", "publisher_a", "current_hash")]
48
- )
46
+ expected_config_hashes = [
47
+ ConfigHash(
48
+ channel="channel-a",
49
+ parent_saas="publisher_a",
50
+ target_config_hash="current_hash",
51
+ )
52
+ ]
49
53
  assert subscriber.desired_ref == "current_sha"
50
54
  assert subscriber.desired_hashes == expected_config_hashes
51
55
 
52
56
 
53
57
  def test_moving_ref(
54
58
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
55
- config_hashes_builder: Callable[
56
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
57
- ],
58
59
  ):
59
60
  subscriber = subscriber_builder(
60
61
  {
61
62
  CUR_SUBSCRIBER_REF: "current_sha",
62
63
  CUR_CONFIG_HASHES: [
63
- ("channel-a", "publisher_a", "current_hash"),
64
+ ConfigHash(
65
+ channel="channel-a",
66
+ parent_saas="publisher_a",
67
+ target_config_hash="current_hash",
68
+ ),
64
69
  ],
65
70
  CHANNELS: {
66
71
  "channel-a": {
@@ -73,24 +78,29 @@ def test_moving_ref(
73
78
  }
74
79
  )
75
80
  subscriber.compute_desired_state()
76
- expected_config_hashes = config_hashes_builder(
77
- [("channel-a", "publisher_a", "current_hash")]
78
- )
81
+ expected_config_hashes = [
82
+ ConfigHash(
83
+ channel="channel-a",
84
+ parent_saas="publisher_a",
85
+ target_config_hash="current_hash",
86
+ )
87
+ ]
79
88
  assert subscriber.desired_ref == "new_sha"
80
89
  assert subscriber.desired_hashes == expected_config_hashes
81
90
 
82
91
 
83
92
  def test_moving_ref_bad_deployment(
84
93
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
85
- config_hashes_builder: Callable[
86
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
87
- ],
88
94
  ):
89
95
  subscriber = subscriber_builder(
90
96
  {
91
97
  CUR_SUBSCRIBER_REF: "current_sha",
92
98
  CUR_CONFIG_HASHES: [
93
- ("channel-a", "publisher_a", "current_hash"),
99
+ ConfigHash(
100
+ channel="channel-a",
101
+ parent_saas="publisher_a",
102
+ target_config_hash="current_hash",
103
+ ),
94
104
  ],
95
105
  CHANNELS: {
96
106
  "channel-a": {
@@ -104,24 +114,29 @@ def test_moving_ref_bad_deployment(
104
114
  }
105
115
  )
106
116
  subscriber.compute_desired_state()
107
- expected_config_hashes = config_hashes_builder(
108
- [("channel-a", "publisher_a", "current_hash")]
109
- )
117
+ expected_config_hashes = [
118
+ ConfigHash(
119
+ channel="channel-a",
120
+ parent_saas="publisher_a",
121
+ target_config_hash="current_hash",
122
+ )
123
+ ]
110
124
  assert subscriber.desired_ref == "current_sha"
111
125
  assert subscriber.desired_hashes == expected_config_hashes
112
126
 
113
127
 
114
128
  def test_new_config_hash(
115
129
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
116
- config_hashes_builder: Callable[
117
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
118
- ],
119
130
  ):
120
131
  subscriber = subscriber_builder(
121
132
  {
122
133
  CUR_SUBSCRIBER_REF: "current_sha",
123
134
  CUR_CONFIG_HASHES: [
124
- ("channel-a", "publisher_a", "current_hash"),
135
+ ConfigHash(
136
+ channel="channel-a",
137
+ parent_saas="publisher_a",
138
+ target_config_hash="current_hash",
139
+ ),
125
140
  ],
126
141
  CHANNELS: {
127
142
  "channel-a": {
@@ -134,24 +149,29 @@ def test_new_config_hash(
134
149
  }
135
150
  )
136
151
  subscriber.compute_desired_state()
137
- expected_config_hashes = config_hashes_builder(
138
- [("channel-a", "publisher_a", "new_hash")]
139
- )
152
+ expected_config_hashes = [
153
+ ConfigHash(
154
+ channel="channel-a",
155
+ parent_saas="publisher_a",
156
+ target_config_hash="new_hash",
157
+ )
158
+ ]
140
159
  assert subscriber.desired_ref == "current_sha"
141
160
  assert subscriber.desired_hashes == expected_config_hashes
142
161
 
143
162
 
144
163
  def test_new_config_hash_bad_deployment(
145
164
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
146
- config_hashes_builder: Callable[
147
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
148
- ],
149
165
  ):
150
166
  subscriber = subscriber_builder(
151
167
  {
152
168
  CUR_SUBSCRIBER_REF: "current_sha",
153
169
  CUR_CONFIG_HASHES: [
154
- ("channel-a", "publisher_a", "current_hash"),
170
+ ConfigHash(
171
+ channel="channel-a",
172
+ parent_saas="publisher_a",
173
+ target_config_hash="current_hash",
174
+ ),
155
175
  ],
156
176
  CHANNELS: {
157
177
  "channel-a": {
@@ -165,24 +185,29 @@ def test_new_config_hash_bad_deployment(
165
185
  }
166
186
  )
167
187
  subscriber.compute_desired_state()
168
- expected_config_hashes = config_hashes_builder(
169
- [("channel-a", "publisher_a", "current_hash")]
170
- )
188
+ expected_config_hashes = [
189
+ ConfigHash(
190
+ channel="channel-a",
191
+ parent_saas="publisher_a",
192
+ target_config_hash="current_hash",
193
+ )
194
+ ]
171
195
  assert subscriber.desired_ref == "current_sha"
172
196
  assert subscriber.desired_hashes == expected_config_hashes
173
197
 
174
198
 
175
199
  def test_new_config_hash_and_moving_ref(
176
200
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
177
- config_hashes_builder: Callable[
178
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
179
- ],
180
201
  ):
181
202
  subscriber = subscriber_builder(
182
203
  {
183
204
  CUR_SUBSCRIBER_REF: "current_sha",
184
205
  CUR_CONFIG_HASHES: [
185
- ("channel-a", "publisher_a", "current_hash"),
206
+ ConfigHash(
207
+ channel="channel-a",
208
+ parent_saas="publisher_a",
209
+ target_config_hash="current_hash",
210
+ ),
186
211
  ],
187
212
  CHANNELS: {
188
213
  "channel-a": {
@@ -195,24 +220,29 @@ def test_new_config_hash_and_moving_ref(
195
220
  }
196
221
  )
197
222
  subscriber.compute_desired_state()
198
- expected_config_hashes = config_hashes_builder(
199
- [("channel-a", "publisher_a", "new_hash")]
200
- )
223
+ expected_config_hashes = [
224
+ ConfigHash(
225
+ channel="channel-a",
226
+ parent_saas="publisher_a",
227
+ target_config_hash="new_hash",
228
+ )
229
+ ]
201
230
  assert subscriber.desired_ref == "new_sha"
202
231
  assert subscriber.desired_hashes == expected_config_hashes
203
232
 
204
233
 
205
234
  def test_new_config_hash_and_moving_ref_and_bad_deployment(
206
235
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
207
- config_hashes_builder: Callable[
208
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
209
- ],
210
236
  ):
211
237
  subscriber = subscriber_builder(
212
238
  {
213
239
  CUR_SUBSCRIBER_REF: "current_sha",
214
240
  CUR_CONFIG_HASHES: [
215
- ("channel-a", "publisher_a", "current_hash"),
241
+ ConfigHash(
242
+ channel="channel-a",
243
+ parent_saas="publisher_a",
244
+ target_config_hash="current_hash",
245
+ ),
216
246
  ],
217
247
  CHANNELS: {
218
248
  "channel-a": {
@@ -226,18 +256,19 @@ def test_new_config_hash_and_moving_ref_and_bad_deployment(
226
256
  }
227
257
  )
228
258
  subscriber.compute_desired_state()
229
- expected_config_hashes = config_hashes_builder(
230
- [("channel-a", "publisher_a", "current_hash")]
231
- )
259
+ expected_config_hashes = [
260
+ ConfigHash(
261
+ channel="channel-a",
262
+ parent_saas="publisher_a",
263
+ target_config_hash="current_hash",
264
+ )
265
+ ]
232
266
  assert subscriber.desired_ref == "current_sha"
233
267
  assert subscriber.desired_hashes == expected_config_hashes
234
268
 
235
269
 
236
270
  def test_cur_config_hash_did_not_exist(
237
271
  subscriber_builder: Callable[[Mapping[str, Any]], Subscriber],
238
- config_hashes_builder: Callable[
239
- [Iterable[tuple[str, str, str]]], frozenset[ConfigHash]
240
- ],
241
272
  ):
242
273
  subscriber = subscriber_builder(
243
274
  {
@@ -254,8 +285,12 @@ def test_cur_config_hash_did_not_exist(
254
285
  }
255
286
  )
256
287
  subscriber.compute_desired_state()
257
- expected_config_hashes = config_hashes_builder(
258
- [("channel-a", "publisher_a", "new_hash")]
259
- )
288
+ expected_config_hashes = [
289
+ ConfigHash(
290
+ channel="channel-a",
291
+ parent_saas="publisher_a",
292
+ target_config_hash="new_hash",
293
+ )
294
+ ]
260
295
  assert subscriber.desired_ref == "current_sha"
261
296
  assert subscriber.desired_hashes == expected_config_hashes