Skip to content

Commit 3fdef73

Browse files
committed
Update concurrency tests to use ConcurrencyTestBase and add result validation
1 parent d71b5d8 commit 3fdef73

3 files changed

Lines changed: 68 additions & 77 deletions

File tree

opentelemetry-api/tests/metrics/test_instruments.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414
# type: ignore
1515

16-
import threading
1716
from inspect import Signature, isabstract, signature
1817
from unittest import TestCase
1918

@@ -32,6 +31,7 @@
3231
UpDownCounter,
3332
_Gauge,
3433
)
34+
from opentelemetry.test.concurrency_test import ConcurrencyTestBase
3535

3636

3737
class ChildInstrument(Instrument):
@@ -725,42 +725,31 @@ def test_description_check(self):
725725
)
726726

727727

728-
class TestConcurrency(TestCase):
729-
def _run_concurrently(self, fn, num_threads=10, calls_per_thread=100):
730-
"""Helper: run fn concurrently across threads and assert no exceptions."""
731-
errors = []
732-
733-
def worker():
734-
try:
735-
for _ in range(calls_per_thread):
736-
fn()
737-
except Exception as exc: # pylint: disable=broad-except
738-
errors.append(exc)
739-
740-
threads = [threading.Thread(target=worker) for _ in range(num_threads)]
741-
for thread in threads:
742-
thread.start()
743-
for thread in threads:
744-
thread.join()
745-
746-
self.assertEqual([], errors)
747-
728+
class TestConcurrency(ConcurrencyTestBase):
748729
def test_counter_add_concurrent(self):
749730
"""Test that Counter.add can be called concurrently safely."""
750731
counter = NoOpCounter("name")
751-
self._run_concurrently(lambda: counter.add(1))
732+
results = self.run_with_many_threads(lambda: counter.add(1))
733+
self.assertEqual(len(results), 100)
734+
self.assertTrue(all(result is None for result in results))
752735

753736
def test_up_down_counter_add_concurrent(self):
754737
"""Test that UpDownCounter.add can be called concurrently safely."""
755738
up_down_counter = NoOpUpDownCounter("name")
756-
self._run_concurrently(lambda: up_down_counter.add(1))
739+
results = self.run_with_many_threads(lambda: up_down_counter.add(1))
740+
self.assertEqual(len(results), 100)
741+
self.assertTrue(all(result is None for result in results))
757742

758743
def test_histogram_record_concurrent(self):
759744
"""Test that Histogram.record can be called concurrently safely."""
760745
histogram = NoOpHistogram("name")
761-
self._run_concurrently(lambda: histogram.record(1))
746+
results = self.run_with_many_threads(lambda: histogram.record(1))
747+
self.assertEqual(len(results), 100)
748+
self.assertTrue(all(result is None for result in results))
762749

763750
def test_gauge_set_concurrent(self):
764751
"""Test that Gauge.set can be called concurrently safely."""
765752
gauge = NoOpMeter("name").create_gauge("name")
766-
self._run_concurrently(lambda: gauge.set(1))
753+
results = self.run_with_many_threads(lambda: gauge.set(1))
754+
self.assertEqual(len(results), 100)
755+
self.assertTrue(all(result is None for result in results))

opentelemetry-api/tests/metrics/test_meter.py

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@
1313
# limitations under the License.
1414
# type: ignore
1515

16-
import threading
1716
from logging import WARNING
1817
from unittest import TestCase
1918
from unittest.mock import Mock, patch
2019

21-
from opentelemetry.metrics import Meter, NoOpMeter
20+
from opentelemetry.metrics import (
21+
Counter,
22+
Histogram,
23+
Meter,
24+
NoOpMeter,
25+
ObservableCounter,
26+
ObservableGauge,
27+
ObservableUpDownCounter,
28+
UpDownCounter,
29+
_Gauge,
30+
)
31+
from opentelemetry.test.concurrency_test import ConcurrencyTestBase
2232

2333

2434
class ChildMeter(Meter):
@@ -196,71 +206,74 @@ def test_create_observable_up_down_counter(self):
196206
)
197207

198208

199-
class TestConcurrency(TestCase):
200-
def _run_concurrently(self, fn, num_threads=10, calls_per_thread=100):
201-
"""Helper: run fn concurrently across threads and assert no exceptions."""
202-
errors = []
203-
204-
def worker():
205-
try:
206-
for _ in range(calls_per_thread):
207-
fn()
208-
except Exception as exc: # pylint: disable=broad-except
209-
errors.append(exc)
210-
211-
threads = [threading.Thread(target=worker) for _ in range(num_threads)]
212-
for thread in threads:
213-
thread.start()
214-
for thread in threads:
215-
thread.join()
216-
217-
self.assertEqual([], errors)
218-
209+
class TestConcurrency(ConcurrencyTestBase):
219210
def test_create_counter_concurrent(self):
220211
"""Test that Meter.create_counter can be called concurrently safely."""
221212
meter = NoOpMeter("name")
222-
self._run_concurrently(lambda: meter.create_counter("counter"))
213+
results = self.run_with_many_threads(
214+
lambda: meter.create_counter("counter")
215+
)
216+
self.assertEqual(len(results), 100)
217+
self.assertTrue(all(isinstance(r, Counter) for r in results))
223218

224219
def test_create_up_down_counter_concurrent(self):
225220
"""Test that Meter.create_up_down_counter can be called concurrently safely."""
226221
meter = NoOpMeter("name")
227-
self._run_concurrently(
222+
results = self.run_with_many_threads(
228223
lambda: meter.create_up_down_counter("up_down_counter")
229224
)
225+
self.assertEqual(len(results), 100)
226+
self.assertTrue(all(isinstance(r, UpDownCounter) for r in results))
230227

231228
def test_create_observable_counter_concurrent(self):
232229
"""Test that Meter.create_observable_counter can be called concurrently safely."""
233230
meter = NoOpMeter("name")
234-
self._run_concurrently(
231+
results = self.run_with_many_threads(
235232
lambda: meter.create_observable_counter(
236233
"observable_counter", lambda options: []
237234
)
238235
)
236+
self.assertEqual(len(results), 100)
237+
self.assertTrue(all(isinstance(r, ObservableCounter) for r in results))
239238

240239
def test_create_histogram_concurrent(self):
241240
"""Test that Meter.create_histogram can be called concurrently safely."""
242241
meter = NoOpMeter("name")
243-
self._run_concurrently(lambda: meter.create_histogram("histogram"))
242+
results = self.run_with_many_threads(
243+
lambda: meter.create_histogram("histogram")
244+
)
245+
self.assertEqual(len(results), 100)
246+
self.assertTrue(all(isinstance(r, Histogram) for r in results))
244247

245248
def test_create_gauge_concurrent(self):
246249
"""Test that Meter.create_gauge can be called concurrently safely."""
247250
meter = NoOpMeter("name")
248-
self._run_concurrently(lambda: meter.create_gauge("gauge"))
251+
results = self.run_with_many_threads(
252+
lambda: meter.create_gauge("gauge")
253+
)
254+
self.assertEqual(len(results), 100)
255+
self.assertTrue(all(isinstance(r, _Gauge) for r in results))
249256

250257
def test_create_observable_gauge_concurrent(self):
251258
"""Test that Meter.create_observable_gauge can be called concurrently safely."""
252259
meter = NoOpMeter("name")
253-
self._run_concurrently(
260+
results = self.run_with_many_threads(
254261
lambda: meter.create_observable_gauge(
255262
"observable_gauge", lambda options: []
256263
)
257264
)
265+
self.assertEqual(len(results), 100)
266+
self.assertTrue(all(isinstance(r, ObservableGauge) for r in results))
258267

259268
def test_create_observable_up_down_counter_concurrent(self):
260269
"""Test that Meter.create_observable_up_down_counter can be called concurrently safely."""
261270
meter = NoOpMeter("name")
262-
self._run_concurrently(
271+
results = self.run_with_many_threads(
263272
lambda: meter.create_observable_up_down_counter(
264273
"observable_up_down_counter", lambda options: []
265274
)
266275
)
276+
self.assertEqual(len(results), 100)
277+
self.assertTrue(
278+
all(isinstance(r, ObservableUpDownCounter) for r in results)
279+
)

opentelemetry-api/tests/metrics/test_meter_provider.py

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
# pylint: disable=protected-access
1717

18-
import threading
1918
from unittest import TestCase
2019
from unittest.mock import Mock, patch
2120

@@ -44,6 +43,7 @@
4443
_ProxyObservableUpDownCounter,
4544
_ProxyUpDownCounter,
4645
)
46+
from opentelemetry.test.concurrency_test import ConcurrencyTestBase
4747
from opentelemetry.test.globals_test import (
4848
MetricsGlobalsTest,
4949
reset_metrics_globals,
@@ -164,35 +164,24 @@ def test_get_meter_wrapper(self):
164164
self.assertEqual(meter.schema_url, "schema_url")
165165

166166

167-
class TestConcurrency(TestCase):
168-
def _run_concurrently(self, fn, num_threads=10, calls_per_thread=100):
169-
"""Helper: run fn concurrently across threads and assert no exceptions."""
170-
errors = []
171-
172-
def worker():
173-
try:
174-
for _ in range(calls_per_thread):
175-
fn()
176-
except Exception as exc: # pylint: disable=broad-except
177-
errors.append(exc)
178-
179-
threads = [threading.Thread(target=worker) for _ in range(num_threads)]
180-
for thread in threads:
181-
thread.start()
182-
for thread in threads:
183-
thread.join()
184-
185-
self.assertEqual([], errors)
186-
167+
class TestConcurrency(ConcurrencyTestBase):
187168
def test_no_op_meter_provider_get_meter_concurrent(self):
188169
"""Test that NoOpMeterProvider.get_meter can be called concurrently safely."""
189170
meter_provider = NoOpMeterProvider()
190-
self._run_concurrently(lambda: meter_provider.get_meter("name"))
171+
results = self.run_with_many_threads(
172+
lambda: meter_provider.get_meter("name")
173+
)
174+
self.assertEqual(len(results), 100)
175+
self.assertTrue(all(isinstance(r, NoOpMeter) for r in results))
191176

192177
def test_proxy_meter_provider_get_meter_concurrent(self):
193178
"""Test that _ProxyMeterProvider.get_meter can be called concurrently safely."""
194179
meter_provider = _ProxyMeterProvider()
195-
self._run_concurrently(lambda: meter_provider.get_meter("name"))
180+
results = self.run_with_many_threads(
181+
lambda: meter_provider.get_meter("name")
182+
)
183+
self.assertEqual(len(results), 100)
184+
self.assertTrue(all(isinstance(r, _ProxyMeter) for r in results))
196185

197186

198187
class TestProxy(MetricsGlobalsTest, TestCase):

0 commit comments

Comments
 (0)