github.com/prebid/prebid-server/v2@v2.18.0/hooks/hookexecution/test_utils.go (about)

     1  package hookexecution
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/prebid/prebid-server/v2/util/jsonutil"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  // AssertEqualModulesData is the test helper function which asserts
    12  // that expected modules data fully corresponds the actual modules data.
    13  // Dynamic data for execution time is calculated from actual modules data.
    14  func AssertEqualModulesData(t *testing.T, expectedData, actualData json.RawMessage) {
    15  	t.Helper()
    16  
    17  	var expectedModulesOutcome ModulesOutcome
    18  	var actualModulesOutcome ModulesOutcome
    19  
    20  	assert.NoError(t, jsonutil.UnmarshalValid(expectedData, &expectedModulesOutcome), "Failed to unmarshal expected modules data.")
    21  	assert.NoError(t, jsonutil.UnmarshalValid(actualData, &actualModulesOutcome), "Failed to unmarshal actual modules data.")
    22  	assert.Equal(t, expectedModulesOutcome.Errors, actualModulesOutcome.Errors, "Invalid error messages.")
    23  	assert.Equal(t, expectedModulesOutcome.Warnings, actualModulesOutcome.Warnings, "Invalid warning messages.")
    24  
    25  	assertEqualTraces(t, expectedModulesOutcome.Trace, actualModulesOutcome.Trace)
    26  }
    27  
    28  func assertEqualTraces(t *testing.T, expectedTrace *TraceOutcome, actualTrace *TraceOutcome) {
    29  	if expectedTrace == nil {
    30  		assert.Nil(t, actualTrace, "Nil trace not expected.")
    31  	}
    32  
    33  	// calculate expected timings from actual modules outcome
    34  	for i, actualStage := range actualTrace.Stages {
    35  		expectedStage := expectedTrace.Stages[i]
    36  		expectedTrace.ExecutionTimeMillis += actualStage.ExecutionTimeMillis
    37  
    38  		for _, actualOutcome := range actualStage.Outcomes {
    39  			if expectedStage.ExecutionTimeMillis < actualOutcome.ExecutionTimeMillis {
    40  				expectedStage.ExecutionTimeMillis = actualOutcome.ExecutionTimeMillis
    41  			}
    42  
    43  			expectedOutcome := findCorrespondingStageOutcome(expectedStage, actualOutcome)
    44  			assert.NotNil(t, expectedOutcome, "Not found corresponding stage outcome, actual:`", actualOutcome)
    45  			assertEqualStageOutcomes(t, *expectedOutcome, actualOutcome)
    46  		}
    47  
    48  		assert.Equal(t, expectedStage.Stage, actualStage.Stage, "Invalid stage name.")
    49  		assert.Equal(t, expectedStage.ExecutionTimeMillis, actualStage.ExecutionTimeMillis, "Invalid stage execution time.")
    50  	}
    51  
    52  	assert.Equal(t, expectedTrace.ExecutionTimeMillis, actualTrace.ExecutionTimeMillis, "Invalid trace execution time.")
    53  }
    54  
    55  func assertEqualStageOutcomes(t *testing.T, expected StageOutcome, actual StageOutcome) {
    56  	t.Helper()
    57  
    58  	assert.Equal(t, len(actual.Groups), len(expected.Groups), "Stage outcomes contain different number of groups")
    59  
    60  	// calculate expected timings from actual outcome
    61  	for i, group := range actual.Groups {
    62  		expected.ExecutionTimeMillis += group.ExecutionTimeMillis
    63  		for _, hook := range group.InvocationResults {
    64  			if hook.ExecutionTimeMillis > expected.Groups[i].ExecutionTimeMillis {
    65  				expected.Groups[i].ExecutionTimeMillis = hook.ExecutionTimeMillis
    66  			}
    67  		}
    68  	}
    69  
    70  	assert.Equal(t, expected.ExecutionTimeMillis, actual.ExecutionTimeMillis, "Incorrect stage execution time")
    71  	assert.Equal(t, expected.Stage, actual.Stage, "Incorrect stage name")
    72  	assert.Equal(t, expected.Entity, actual.Entity, "Incorrect stage entity name")
    73  
    74  	for i, expGroup := range expected.Groups {
    75  		gotGroup := actual.Groups[i]
    76  		assert.Equal(t, len(expGroup.InvocationResults), len(gotGroup.InvocationResults), "Group outcomes #%d contain different number of invocation results", i)
    77  		assert.Equal(t, expGroup.ExecutionTimeMillis, gotGroup.ExecutionTimeMillis, "Incorrect group #%d execution time", i)
    78  
    79  		for _, expHook := range expGroup.InvocationResults {
    80  			gotHook := findCorrespondingHookResult(expHook.HookID, gotGroup)
    81  			assert.NotNil(t, gotHook, "Expected to get hook, got nil: group #%d, hookID %v", i, expHook.HookID)
    82  
    83  			gotHook.ExecutionTimeMillis = 0 // reset hook execution time, we cannot predict it
    84  			assert.Equal(t, expHook, *gotHook, "Incorrect hook outcome: group #%d, hookID %v", i, expHook.HookID)
    85  		}
    86  	}
    87  }
    88  
    89  func findCorrespondingStageOutcome(stage Stage, outcome StageOutcome) *StageOutcome {
    90  	for _, out := range stage.Outcomes {
    91  		if out.Entity == outcome.Entity {
    92  			return &out
    93  		}
    94  	}
    95  	return nil
    96  }
    97  
    98  func findCorrespondingHookResult(hookID HookID, group GroupOutcome) *HookOutcome {
    99  	for _, hook := range group.InvocationResults {
   100  		if hook.HookID.ModuleCode == hookID.ModuleCode &&
   101  			hook.HookID.HookImplCode == hookID.HookImplCode {
   102  			return &hook
   103  		}
   104  	}
   105  	return nil
   106  }