...

Source file src/go.opentelemetry.io/otel/internal/global/instruments_test.go

Documentation: go.opentelemetry.io/otel/internal/global

     1  // Copyright The OpenTelemetry Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package global
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"go.opentelemetry.io/otel/metric"
    22  	"go.opentelemetry.io/otel/metric/embedded"
    23  	"go.opentelemetry.io/otel/metric/noop"
    24  )
    25  
    26  func testFloat64ConcurrentSafe(interact func(float64), setDelegate func(metric.Meter)) {
    27  	done := make(chan struct{})
    28  	finish := make(chan struct{})
    29  	go func() {
    30  		defer close(done)
    31  		for {
    32  			interact(1)
    33  			select {
    34  			case <-finish:
    35  				return
    36  			default:
    37  			}
    38  		}
    39  	}()
    40  
    41  	setDelegate(noop.NewMeterProvider().Meter(""))
    42  	close(finish)
    43  	<-done
    44  }
    45  
    46  func testInt64ConcurrentSafe(interact func(int64), setDelegate func(metric.Meter)) {
    47  	done := make(chan struct{})
    48  	finish := make(chan struct{})
    49  	go func() {
    50  		defer close(done)
    51  		for {
    52  			interact(1)
    53  			select {
    54  			case <-finish:
    55  				return
    56  			default:
    57  			}
    58  		}
    59  	}()
    60  
    61  	setDelegate(noop.NewMeterProvider().Meter(""))
    62  	close(finish)
    63  	<-done
    64  }
    65  
    66  func TestAsyncInstrumentSetDelegateConcurrentSafe(t *testing.T) {
    67  	// Float64 Instruments
    68  	t.Run("Float64", func(t *testing.T) {
    69  		t.Run("Counter", func(t *testing.T) {
    70  			delegate := &afCounter{}
    71  			f := func(float64) { _ = delegate.Unwrap() }
    72  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
    73  		})
    74  
    75  		t.Run("UpDownCounter", func(t *testing.T) {
    76  			delegate := &afUpDownCounter{}
    77  			f := func(float64) { _ = delegate.Unwrap() }
    78  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
    79  		})
    80  
    81  		t.Run("Gauge", func(t *testing.T) {
    82  			delegate := &afGauge{}
    83  			f := func(float64) { _ = delegate.Unwrap() }
    84  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
    85  		})
    86  	})
    87  
    88  	// Int64 Instruments
    89  
    90  	t.Run("Int64", func(t *testing.T) {
    91  		t.Run("Counter", func(t *testing.T) {
    92  			delegate := &aiCounter{}
    93  			f := func(int64) { _ = delegate.Unwrap() }
    94  			testInt64ConcurrentSafe(f, delegate.setDelegate)
    95  		})
    96  
    97  		t.Run("UpDownCounter", func(t *testing.T) {
    98  			delegate := &aiUpDownCounter{}
    99  			f := func(int64) { _ = delegate.Unwrap() }
   100  			testInt64ConcurrentSafe(f, delegate.setDelegate)
   101  		})
   102  
   103  		t.Run("Gauge", func(t *testing.T) {
   104  			delegate := &aiGauge{}
   105  			f := func(int64) { _ = delegate.Unwrap() }
   106  			testInt64ConcurrentSafe(f, delegate.setDelegate)
   107  		})
   108  	})
   109  }
   110  
   111  func TestSyncInstrumentSetDelegateConcurrentSafe(t *testing.T) {
   112  	// Float64 Instruments
   113  	t.Run("Float64", func(t *testing.T) {
   114  		t.Run("Counter", func(t *testing.T) {
   115  			delegate := &sfCounter{}
   116  			f := func(v float64) { delegate.Add(context.Background(), v) }
   117  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
   118  		})
   119  
   120  		t.Run("UpDownCounter", func(t *testing.T) {
   121  			delegate := &sfUpDownCounter{}
   122  			f := func(v float64) { delegate.Add(context.Background(), v) }
   123  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
   124  		})
   125  
   126  		t.Run("Histogram", func(t *testing.T) {
   127  			delegate := &sfHistogram{}
   128  			f := func(v float64) { delegate.Record(context.Background(), v) }
   129  			testFloat64ConcurrentSafe(f, delegate.setDelegate)
   130  		})
   131  	})
   132  
   133  	// Int64 Instruments
   134  
   135  	t.Run("Int64", func(t *testing.T) {
   136  		t.Run("Counter", func(t *testing.T) {
   137  			delegate := &siCounter{}
   138  			f := func(v int64) { delegate.Add(context.Background(), v) }
   139  			testInt64ConcurrentSafe(f, delegate.setDelegate)
   140  		})
   141  
   142  		t.Run("UpDownCounter", func(t *testing.T) {
   143  			delegate := &siUpDownCounter{}
   144  			f := func(v int64) { delegate.Add(context.Background(), v) }
   145  			testInt64ConcurrentSafe(f, delegate.setDelegate)
   146  		})
   147  
   148  		t.Run("Histogram", func(t *testing.T) {
   149  			delegate := &siHistogram{}
   150  			f := func(v int64) { delegate.Record(context.Background(), v) }
   151  			testInt64ConcurrentSafe(f, delegate.setDelegate)
   152  		})
   153  	})
   154  }
   155  
   156  type testCountingFloatInstrument struct {
   157  	count int
   158  
   159  	metric.Float64Observable
   160  	embedded.Float64Counter
   161  	embedded.Float64UpDownCounter
   162  	embedded.Float64Histogram
   163  	embedded.Float64ObservableCounter
   164  	embedded.Float64ObservableUpDownCounter
   165  	embedded.Float64ObservableGauge
   166  }
   167  
   168  func (i *testCountingFloatInstrument) observe() {
   169  	i.count++
   170  }
   171  
   172  func (i *testCountingFloatInstrument) Add(context.Context, float64, ...metric.AddOption) {
   173  	i.count++
   174  }
   175  
   176  func (i *testCountingFloatInstrument) Record(context.Context, float64, ...metric.RecordOption) {
   177  	i.count++
   178  }
   179  
   180  type testCountingIntInstrument struct {
   181  	count int
   182  
   183  	metric.Int64Observable
   184  	embedded.Int64Counter
   185  	embedded.Int64UpDownCounter
   186  	embedded.Int64Histogram
   187  	embedded.Int64ObservableCounter
   188  	embedded.Int64ObservableUpDownCounter
   189  	embedded.Int64ObservableGauge
   190  }
   191  
   192  func (i *testCountingIntInstrument) observe() {
   193  	i.count++
   194  }
   195  
   196  func (i *testCountingIntInstrument) Add(context.Context, int64, ...metric.AddOption) {
   197  	i.count++
   198  }
   199  
   200  func (i *testCountingIntInstrument) Record(context.Context, int64, ...metric.RecordOption) {
   201  	i.count++
   202  }
   203  

View as plain text