go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/logdog/client/butlerlib/streamclient/timebomb_test.go (about)

     1  // Copyright 2019 The LUCI 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 streamclient
    16  
    17  import (
    18  	"runtime"
    19  	"time"
    20  )
    21  
    22  func init() {
    23  	// The numbers here are somewhat arbitrary: On my mac laptop the entire test
    24  	// suite takes .1s to complete in normal mode, and 2s to complete in race
    25  	// mode.
    26  	//
    27  	// On my windows 10 vm, the entire suite takes .5s to complete in normal mode
    28  	// and 2s (yep, same speed) to complete in race mode.
    29  	//
    30  	// Because of the apparent overhead, we multiply the fuse by 10, giving us
    31  	// a normal 10s fuse per-test-case and race 100s fuse per-test-case (not
    32  	// suite!). This should be more than enough, but is still a lot better than
    33  	// the default 10m test timeout.
    34  	if runtime.GOOS == "windows" {
    35  		timebombFuse *= 10
    36  	}
    37  }
    38  
    39  // timebomb forcibly crashes the test executable after timebombFuse time.
    40  //
    41  // Fuse times (x5 on windows):
    42  //   - 1 second in non-race mode
    43  //   - 10 seconds in race mode
    44  //
    45  // use like `defer timebomb()()`
    46  func timebomb() func() {
    47  	diffuseTimebomb := make(chan struct{})
    48  	timebombDiffused := make(chan struct{})
    49  	go func() {
    50  		defer close(timebombDiffused)
    51  		select {
    52  		case <-time.After(timebombFuse):
    53  			panic("runWireProtocolTest took too long.")
    54  		case <-diffuseTimebomb:
    55  		}
    56  	}()
    57  	return func() {
    58  		close(diffuseTimebomb)
    59  		<-timebombDiffused // explicitly sync with the completion of the goroutine.
    60  	}
    61  }