github.com/prebid/prebid-server@v0.275.0/hooks/hookexecution/test_utils.go (about)

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