github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/testing/teststeps.go (about)

     1  // Copyright 2019-2024 The Inspektor Gadget 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 testing
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  )
    21  
    22  const stepWaitDuration = 10 * time.Second
    23  
    24  // TestStep allows combining different steps (e.g command, container creation)
    25  // to allow simplified/consistent flow for tests via RunTestSteps
    26  type TestStep interface {
    27  	// Run runs the step and wait its completion.
    28  	Run(t *testing.T)
    29  
    30  	// Start starts the step and immediately returns, it does wait until
    31  	// its completion, use Stop() for that.
    32  	Start(t *testing.T)
    33  
    34  	// Stop stops the step and waits its completion.
    35  	Stop(t *testing.T)
    36  
    37  	// IsStartAndStop returns true if the step should first be started then
    38  	// stopped after some time.
    39  	IsStartAndStop() bool
    40  
    41  	// Running returns true if the step has been started.
    42  	Running() bool
    43  }
    44  
    45  type Option func(*runTestStepsOpts)
    46  
    47  type runTestStepsOpts struct {
    48  	cbBeforeCleanup func(t *testing.T)
    49  }
    50  
    51  // WithCbBeforeCleanup is executed before calling the cleanup functions, it can be use for instance
    52  // to print extra logs when the test fails.
    53  func WithCbBeforeCleanup(f func(t *testing.T)) func(opts *runTestStepsOpts) {
    54  	return func(ops *runTestStepsOpts) {
    55  		ops.cbBeforeCleanup = f
    56  	}
    57  }
    58  
    59  // RunTestSteps is used to run a list of test steps with stopping/clean up logic.
    60  func RunTestSteps(steps []TestStep, t *testing.T, options ...Option) {
    61  	opts := &runTestStepsOpts{}
    62  
    63  	for _, option := range options {
    64  		option(opts)
    65  	}
    66  
    67  	if opts.cbBeforeCleanup != nil {
    68  		defer opts.cbBeforeCleanup(t)
    69  	}
    70  
    71  	// Defer stopping commands
    72  	for _, step := range steps {
    73  		step := step
    74  		defer func() {
    75  			if step.IsStartAndStop() && step.Running() {
    76  				// Wait a bit before stopping the step.
    77  				time.Sleep(stepWaitDuration)
    78  				step.Stop(t)
    79  			}
    80  		}()
    81  	}
    82  
    83  	// Run or Start all steps
    84  	for _, step := range steps {
    85  		if step.IsStartAndStop() {
    86  			step.Start(t)
    87  			continue
    88  		}
    89  
    90  		step.Run(t)
    91  	}
    92  }