Browse Source

Fix ZeroDivisionError in reconstructor.stats_line

Despite a check to prevent zero values in the denominator python
integer division could result in ZeroDivisionError in the compute_eta
helper function.  Make sure we always have a non-zero value even if it
is small.

NotImplemented:

 * stats calculation is still not great, see lp bug #1488608

Closes-Bug: #1549110
Change-Id: I54f2081c92c2a0b8f02c31e82f44f4250043d837
tags/2.11.0
Clay Gerrard 2 years ago
parent
commit
f4adb2f28f
3 changed files with 28 additions and 1 deletions
  1. 1
    1
      swift/obj/reconstructor.py
  2. 1
    0
      test/unit/__init__.py
  3. 26
    0
      test/unit/obj/test_reconstructor.py

+ 1
- 1
swift/obj/reconstructor.py View File

@@ -354,7 +354,7 @@ class ObjectReconstructor(Daemon):
354 354
                 self.reconstruction_device_count):
355 355
             elapsed = (time.time() - self.start) or 0.000001
356 356
             rate = self.reconstruction_part_count / elapsed
357
-            total_part_count = (self.part_count *
357
+            total_part_count = (1.0 * self.part_count *
358 358
                                 self.device_count /
359 359
                                 self.reconstruction_device_count)
360 360
             self.logger.info(

+ 1
- 0
test/unit/__init__.py View File

@@ -200,6 +200,7 @@ class PatchPolicies(object):
200 200
     def __enter__(self):
201 201
         self._orig_POLICIES = storage_policy._POLICIES
202 202
         storage_policy._POLICIES = self.policies
203
+        self._setup_rings()
203 204
 
204 205
     def __exit__(self, *args):
205 206
         storage_policy._POLICIES = self._orig_POLICIES

+ 26
- 0
test/unit/obj/test_reconstructor.py View File

@@ -1145,6 +1145,9 @@ class TestObjectReconstructor(unittest.TestCase):
1145 1145
         # directly, so you end up with a /0 when you try to show the
1146 1146
         # percentage of complete jobs as ratio of the total job count
1147 1147
         self.reconstructor.job_count = 1
1148
+        # if we ever let a test through without properly patching the
1149
+        # REPLICATE and SSYNC calls - let's fail sort fast-ish
1150
+        self.reconstructor.lockup_timeout = 3
1148 1151
 
1149 1152
     def tearDown(self):
1150 1153
         self.reconstructor._reset_stats()
@@ -1154,6 +1157,29 @@ class TestObjectReconstructor(unittest.TestCase):
1154 1157
     def ts(self):
1155 1158
         return next(self.ts_iter)
1156 1159
 
1160
+    def test_two_ec_policies(self):
1161
+        with patch_policies([
1162
+                StoragePolicy(0, name='zero', is_deprecated=True),
1163
+                ECStoragePolicy(1, name='one', is_default=True,
1164
+                                ec_type=DEFAULT_TEST_EC_TYPE,
1165
+                                ec_ndata=4, ec_nparity=3),
1166
+                ECStoragePolicy(2, name='two',
1167
+                                ec_type=DEFAULT_TEST_EC_TYPE,
1168
+                                ec_ndata=8, ec_nparity=2)],
1169
+                            fake_ring_args=[
1170
+                                {}, {'replicas': 7}, {'replicas': 10}]):
1171
+            self._configure_reconstructor()
1172
+            jobs = []
1173
+
1174
+            def process_job(job):
1175
+                jobs.append(job)
1176
+
1177
+            self.reconstructor.process_job = process_job
1178
+
1179
+            os.makedirs(os.path.join(self.devices, 'sda', 'objects-1', '0'))
1180
+            self.reconstructor.run_once()
1181
+            self.assertEqual(1, len(jobs))
1182
+
1157 1183
     def test_collect_parts_skips_non_ec_policy_and_device(self):
1158 1184
         stub_parts = (371, 78, 419, 834)
1159 1185
         for policy in POLICIES:

Loading…
Cancel
Save