github.com/koko1123/flow-go-1@v0.29.6/tools/test_monitor/level2/process_summary2_results_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/koko1123/flow-go-1/tools/test_monitor/common" 12 "github.com/koko1123/flow-go-1/tools/test_monitor/common/testdata" 13 "github.com/koko1123/flow-go-1/utils/unittest" 14 ) 15 16 func TestGenerateLevel2Summary_Struct(t *testing.T) { 17 testDataMap := map[string]testdata.Level2TestData{ 18 "1 level 1 summary, 1 failure the rest pass": { 19 Directory: "test1-1package-1failure", 20 HasFailures: true, 21 HasExceptions: false, 22 Level1Summaries: testdata.GetTestData_Level2_1FailureRestPass(), 23 }, 24 25 "1 level 1 summary, 1 exception, no other tests": { 26 Directory: "test2-1-exception", 27 HasFailures: false, 28 HasExceptions: true, 29 Level1Summaries: testdata.GetTestsData_Level2_1ExceptionNoOtherTests(), 30 }, 31 32 "many level 1 summaries, many exceptions": { 33 Directory: "test3-multi-exceptions", 34 HasFailures: false, 35 HasExceptions: true, 36 Level1Summaries: testdata.GetTestData_Level2_MultipleL1SummariesExceptions(), 37 }, 38 39 "many level 1 summaries, many failures, many passes": { 40 Directory: "test4-multi-failures", 41 HasFailures: true, 42 HasExceptions: false, 43 Level1Summaries: testdata.GetTestData_Level2MultipleL1SummariesFailuresPasses(), 44 }, 45 46 "many level 1 summaries, many failures, many passes, many exceptions": { 47 Directory: "test5-multi-failures-multi-exceptions", 48 HasFailures: true, 49 HasExceptions: true, 50 Level1Summaries: testdata.GetTestData_Level2MultipleL1SummariesFailuresPassesExceptions(), 51 }, 52 } 53 54 for k, testData := range testDataMap { 55 t.Run(k, func(t *testing.T) { 56 setUp(t) 57 // ************************ 58 actualLevel2Summary := generateLevel2SummaryFromStructs(testData.Level1Summaries) 59 // ************************ 60 checkLevel2Summary(t, actualLevel2Summary, testData) 61 tearDown(t) 62 }) 63 } 64 } 65 66 // TestGenerateLevel2Summary_JSON uses real level 1 JSON files as input 67 // Don't want to use too many tests since they are more brittle to changes to JSON data structure. 68 // That's why have very few of these. For new tests, it's best to add level 1 data as structs. 69 func TestGenerateLevel2Summary_JSON(t *testing.T) { 70 unittest.SkipUnless(t, unittest.TEST_TODO, "broken") 71 testDataMap := map[string]testdata.Level2TestData{ 72 "1 level 1 summary, 1 failure the rest pass": { 73 Directory: "test1-1package-1failure", 74 Level1DataPath: "../testdata/summary2/test1-1package-1failure/input", 75 HasFailures: true, 76 HasExceptions: false, 77 }, 78 } 79 for k, testData := range testDataMap { 80 t.Run(k, func(t *testing.T) { 81 setUp(t) 82 // ************************ 83 actualLevel2Summary := generateLevel2Summary(testData.Level1DataPath) 84 // ************************ 85 checkLevel2Summary(t, actualLevel2Summary, testData) 86 tearDown(t) 87 }) 88 } 89 } 90 91 func setUp(t *testing.T) { 92 deleteMessagesDir(t) 93 } 94 95 func tearDown(t *testing.T) { 96 deleteMessagesDir(t) 97 } 98 99 // HELPERS - UTILITIES 100 101 const actualFailureMessagesPath = "./failures" 102 const actualExceptionMessagesPath = "./exceptions" 103 104 func deleteMessagesDir(t *testing.T) { 105 // delete failure test dir that stores failure messages 106 err := os.RemoveAll(actualFailureMessagesPath) 107 require.Nil(t, err) 108 109 // delete exceptions test dir that stores exception messages 110 err = os.RemoveAll(actualExceptionMessagesPath) 111 require.Nil(t, err) 112 } 113 114 func checkLevel2Summary(t *testing.T, actualLevel2Summary common.Level2Summary, testData testdata.Level2TestData) { 115 expectedOutputTestDataPath := filepath.Join("../testdata/summary2", testData.Directory, "expected-output", testData.Directory+".json") 116 expectedFailureMessagesPath := filepath.Join("../testdata/summary2", testData.Directory, "expected-output/failures") 117 expectedExceptionMessagesPath := filepath.Join("../testdata/summary2", testData.Directory, "expected-output/exceptions") 118 119 // read in expected summary level 2 120 var expectedLevel2Summary common.Level2Summary 121 expectedLevel2SummaryJsonBytes, err := os.ReadFile(expectedOutputTestDataPath) 122 require.Nil(t, err) 123 require.NotEmpty(t, expectedLevel2SummaryJsonBytes) 124 err = json.Unmarshal(expectedLevel2SummaryJsonBytes, &expectedLevel2Summary) 125 require.Nil(t, err) 126 127 require.Equal(t, len(expectedLevel2Summary.TestResultsMap), len(actualLevel2Summary.TestResultsMap)) 128 129 // check every expected test runs level 2 summary exists in map of actual test runs level 2 summaries 130 for expectedLevel2TestResultKey := range expectedLevel2Summary.TestResultsMap { 131 expectedLevel2TestResult := expectedLevel2Summary.TestResultsMap[expectedLevel2TestResultKey] 132 actualLevel2TestResults, isFoundActual := actualLevel2Summary.TestResultsMap[expectedLevel2TestResultKey] 133 134 require.True(t, isFoundActual, common.PrintLevel2TestResult(expectedLevel2TestResult, "expected not in actual")) 135 136 common.AssertLevel2TestResults(t, *expectedLevel2TestResult, *actualLevel2TestResults) 137 } 138 139 // check every actual test runs level 2 summary exists in map of expected test runs level 2 summaries 140 for actualLevel2TestResultKey := range actualLevel2Summary.TestResultsMap { 141 actualLevel2TestResult := actualLevel2Summary.TestResultsMap[actualLevel2TestResultKey] 142 exptectedLevel2TestResult, isFoundExpected := expectedLevel2Summary.TestResultsMap[actualLevel2TestResultKey] 143 144 require.True(t, isFoundExpected, common.PrintLevel2TestResult(actualLevel2TestResult, "actual not in expected")) 145 146 common.AssertLevel2TestResults(t, *exptectedLevel2TestResult, *actualLevel2TestResult) 147 } 148 149 checkFailureMessages(t, testData.HasFailures, expectedFailureMessagesPath) 150 checkExceptionMessages(t, testData.HasExceptions, expectedExceptionMessagesPath) 151 } 152 153 // check failure messages created 154 // there are 2 types of scenarios: 155 // 1. test summaries with no failures - these will not have a `failures` sub-directory and no more checking is needed 156 // 2. test summaries with failures - these will have a `failures` sub-directory with failure messages saved 157 // in text files (1 file/failure under separate sub-directory for each test that has failures) 158 func checkFailureMessages(t *testing.T, hasFailures bool, expectedFailureMessagesPath string) { 159 if !hasFailures { 160 return 161 } 162 checkMessagesHelper(t, expectedFailureMessagesPath, actualFailureMessagesPath) 163 } 164 165 // check exception messages created - for tests that generated no pass / fail 166 // there are 2 types of scenarios: 167 // 1. test summaries with no "exception" - these will not have an `exception` sub-directory and no more checking is needed 168 // 2. test summaries with exceptions - these will have an `exception` sub-directory with output messages saved 169 // in text files (1 file/exception under separate sub-directory for each test that has exceptions) 170 func checkExceptionMessages(t *testing.T, HasExceptions bool, expectedExceptionMessagesPath string) { 171 if !HasExceptions { 172 return 173 } 174 checkMessagesHelper(t, expectedExceptionMessagesPath, actualExceptionMessagesPath) 175 } 176 177 // helps check for both failures and exception messages since they are very similar, just under 178 // different directories 179 func checkMessagesHelper(t *testing.T, expectedMessagesPath string, actualMessagesPath string) { 180 181 // count expected failure / exception directories (1 directory/test) 182 expectedMessageDirs, err := os.ReadDir(expectedMessagesPath) 183 require.Nil(t, err) 184 185 // count actual failure / exception directories 186 actualMessageDirs, err := os.ReadDir(actualMessagesPath) 187 require.Nil(t, err) 188 189 // expected test summary has at least 1 failure / exception 190 require.Equal(t, len(expectedMessageDirs), len(actualMessageDirs)) 191 192 // compare expected vs actual messages 193 for expectedMessageDirIndex, expectedMessageDir := range expectedMessageDirs { 194 195 // sub-directory names should be the same - each sub directory corresponds to a failed / exception test name 196 require.Equal(t, expectedMessageDir.Name(), actualMessageDirs[expectedMessageDirIndex].Name()) 197 198 // under each sub-directory, there should be 1 or more text files (failure1.txt/exception1.txt, failure2.txt/exception2.txt, etc) 199 // that holds the raw failure / exception message for that test 200 expectedMessagesDirFiles, err := os.ReadDir(filepath.Join(expectedMessagesPath, expectedMessageDir.Name())) 201 require.Nil(t, err) 202 203 actualMessageDirFiles, err := os.ReadDir(filepath.Join(actualMessagesPath, actualMessageDirs[expectedMessageDirIndex].Name())) 204 require.Nil(t, err) 205 206 // make sure there are the expected number of failed / exception text files in the sub-directory 207 require.Equal(t, len(expectedMessagesDirFiles), len(actualMessageDirFiles)) 208 209 // check contents of each text file for expected failure / exception message 210 // for every test that has failures / exception, there should be 1 text file per failure / exception 211 212 // if test has failures / exceptions, there should be directory of failure / exception messages text files 213 // a sub-directory of the test name will hold all test failure / exception messages 214 215 for expectedMessageFileIndex, expectedMessageFileDirEntry := range expectedMessagesDirFiles { 216 expectedMessageFilePath := filepath.Join(expectedMessagesPath, expectedMessageDir.Name(), expectedMessageFileDirEntry.Name()) 217 expectedMessageFileBytes, err := os.ReadFile(expectedMessageFilePath) 218 require.Nil(t, err) 219 220 actualMessageFilePath := filepath.Join(actualMessagesPath, actualMessageDirs[expectedMessageDirIndex].Name(), actualMessageDirFiles[expectedMessageFileIndex].Name()) 221 actualMessageFileBytes, err := os.ReadFile(actualMessageFilePath) 222 require.Nil(t, err) 223 224 // read expected and actual text files as bytes and compare them all at once 225 require.Equal(t, expectedMessageFileBytes, actualMessageFileBytes) 226 } 227 } 228 }