go.undefinedlabs.com/scopeagent@v0.4.2/tracer/concurrency_test.go (about)

     1  package tracer
     2  
     3  import (
     4  	"strings"
     5  	"sync"
     6  	"testing"
     7  
     8  	opentracing "github.com/opentracing/opentracing-go"
     9  )
    10  
    11  const op = "test"
    12  
    13  func TestDebugAssertSingleGoroutine(t *testing.T) {
    14  	opts := DefaultOptions()
    15  	opts.EnableSpanPool = true
    16  	opts.Recorder = NewInMemoryRecorder()
    17  	opts.DebugAssertSingleGoroutine = true
    18  	tracer := NewWithOptions(opts)
    19  	sp := tracer.StartSpan(op)
    20  	sp.LogEvent("something on my goroutine")
    21  	wait := make(chan struct{})
    22  	var panicked bool
    23  	go func() {
    24  		defer func() {
    25  			if r := recover(); r != nil {
    26  				_, panicked = r.(*errAssertionFailed)
    27  			}
    28  			close(wait)
    29  		}()
    30  		sp.LogEvent("something on your goroutine")
    31  	}()
    32  	<-wait
    33  	if !panicked {
    34  		t.Fatal("expected a panic")
    35  	}
    36  }
    37  
    38  func TestDebugAssertUseAfterFinish(t *testing.T) {
    39  	opts := DefaultOptions()
    40  	opts.EnableSpanPool = true
    41  	opts.Recorder = NewInMemoryRecorder()
    42  	opts.DebugAssertUseAfterFinish = true
    43  	tracer := NewWithOptions(opts)
    44  	const msg = "I shall be finished"
    45  	for _, double := range []bool{false, true} {
    46  		sp := tracer.StartSpan(op)
    47  		sp.Log(opentracing.LogData{Event: msg})
    48  		if double {
    49  			sp.Finish()
    50  		}
    51  		var panicked bool
    52  		func() {
    53  			defer func() {
    54  				r := recover()
    55  				var assertionErr error
    56  				assertionErr, panicked = r.(*errAssertionFailed)
    57  				if !panicked && r != nil {
    58  					panic(r)
    59  				}
    60  				if panicked && !strings.Contains(assertionErr.Error(), msg) {
    61  					t.Fatalf("debug output did not contain log message '%s': %+v", msg, assertionErr)
    62  				}
    63  				spImpl := sp.(*spanImpl)
    64  				// The panic should leave the Mutex unlocked.
    65  				spImpl.Mutex.Lock()
    66  				spImpl.Mutex.Unlock()
    67  			}()
    68  			sp.Finish()
    69  		}()
    70  		if panicked != double {
    71  			t.Errorf("finished double = %t, but panicked = %t", double, panicked)
    72  		}
    73  	}
    74  }
    75  
    76  func TestConcurrentUsage(t *testing.T) {
    77  	opts := DefaultOptions()
    78  	opts.EnableSpanPool = true
    79  	var cr CountingRecorder
    80  	opts.Recorder = &cr
    81  	opts.DebugAssertSingleGoroutine = true
    82  	tracer := NewWithOptions(opts)
    83  	var wg sync.WaitGroup
    84  	const num = 100
    85  	wg.Add(num)
    86  	for i := 0; i < num; i++ {
    87  		go func() {
    88  			defer wg.Done()
    89  			for j := 0; j < num; j++ {
    90  				sp := tracer.StartSpan(op)
    91  				sp.LogEvent("test event")
    92  				sp.SetTag("foo", "bar")
    93  				sp.SetBaggageItem("boo", "far")
    94  				sp.SetOperationName("x")
    95  				csp := tracer.StartSpan(
    96  					"csp",
    97  					opentracing.ChildOf(sp.Context()))
    98  				csp.Finish()
    99  				defer sp.Finish()
   100  			}
   101  		}()
   102  	}
   103  	wg.Wait()
   104  }
   105  
   106  func TestDisableSpanPool(t *testing.T) {
   107  	opts := DefaultOptions()
   108  	var cr CountingRecorder
   109  	opts.Recorder = &cr
   110  	tracer := NewWithOptions(opts)
   111  
   112  	parent := tracer.StartSpan("parent")
   113  	parent.Finish()
   114  	// This shouldn't panic.
   115  	child := tracer.StartSpan(
   116  		"child",
   117  		opentracing.ChildOf(parent.Context()))
   118  	child.Finish()
   119  }