go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/testing_tools/mocks/cluster_mock.ts (about) 1 // Copyright 2022 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 import fetchMock from 'fetch-mock-jest'; 16 17 import { 18 Cluster, 19 ClusterExoneratedTestVariant, 20 ClusterExoneratedTestVariantBranch, 21 ClusterSummary, 22 DistinctClusterFailure, 23 GetClusterRequest, 24 QueryClusterExoneratedTestVariantBranchesRequest, 25 QueryClusterExoneratedTestVariantBranchesResponse, 26 QueryClusterExoneratedTestVariantsRequest, 27 QueryClusterExoneratedTestVariantsResponse, 28 QueryClusterFailuresRequest, 29 QueryClusterFailuresResponse, 30 QueryClusterHistoryResponse, 31 QueryClusterSummariesRequest, 32 QueryClusterSummariesResponse, 33 ReclusteringProgress, 34 } from '@/proto/go.chromium.org/luci/analysis/proto/v1/clusters.pb'; 35 import { DeepMutable } from '@/types/types'; 36 37 export const getMockCluster = (id: string, 38 project = 'testproject', 39 algorithm = 'reason-v2', 40 title = ''): DeepMutable<Cluster> => { 41 return { 42 name: `projects/${project}/clusters/${algorithm}/${id}`, 43 hasExample: true, 44 title: title, 45 metrics: { 46 'human-cls-failed-presubmit': { 47 oneDay: { nominal: '98' }, 48 threeDay: { nominal: '158' }, 49 sevenDay: { nominal: '167' }, 50 }, 51 'critical-failures-exonerated': { 52 oneDay: { nominal: '5625' }, 53 threeDay: { nominal: '14052' }, 54 sevenDay: { nominal: '13800' }, 55 }, 56 'failures': { 57 oneDay: { nominal: '7625' }, 58 threeDay: { nominal: '16052' }, 59 sevenDay: { nominal: '15800' }, 60 }, 61 }, 62 equivalentFailureAssociationRule: '', 63 }; 64 }; 65 66 export const getMockRuleBasicClusterSummary = (id: string): DeepMutable<ClusterSummary> => { 67 return { 68 clusterId: { 69 'algorithm': 'rules-v2', 70 'id': id, 71 }, 72 title: 'reason LIKE "blah%"', 73 bug: { 74 'system': 'buganizer', 75 'id': '123456789', 76 'linkText': 'b/123456789', 77 'url': 'https://buganizer/123456789', 78 }, 79 metrics: { 80 'human-cls-failed-presubmit': { 81 value: '27', 82 dailyBreakdown: [], 83 }, 84 'critical-failures-exonerated': { 85 value: '918', 86 dailyBreakdown: [], 87 }, 88 'failures': { 89 value: '1871', 90 dailyBreakdown: [], 91 }, 92 }, 93 }; 94 }; 95 96 export const getMockRuleFullClusterSummary = (id: string): DeepMutable<ClusterSummary> => { 97 return { 98 clusterId: { 99 'algorithm': 'rules-v2', 100 'id': id, 101 }, 102 title: 'reason LIKE "blah%"', 103 bug: { 104 'system': 'buganizer', 105 'id': '123456789', 106 'linkText': 'b/123456789', 107 'url': 'https://buganizer/123456789', 108 }, 109 metrics: { 110 'human-cls-failed-presubmit': { 111 value: '27', 112 dailyBreakdown: new Array(7).fill('1'), 113 }, 114 'critical-failures-exonerated': { 115 value: '918', 116 dailyBreakdown: new Array(7).fill('2'), 117 }, 118 'failures': { 119 value: '1871', 120 dailyBreakdown: new Array(7).fill('3'), 121 }, 122 }, 123 }; 124 }; 125 126 export const getMockSuggestedBasicClusterSummary = (id: string, algorithm = 'reason-v3'): ClusterSummary => { 127 return { 128 clusterId: { 129 'algorithm': algorithm, 130 'id': id, 131 }, 132 bug: undefined, 133 title: 'reason LIKE "blah%"', 134 metrics: { 135 'human-cls-failed-presubmit': { 136 value: '29', 137 dailyBreakdown: [], 138 }, 139 'critical-failures-exonerated': { 140 value: '919', 141 dailyBreakdown: [], 142 }, 143 'failures': { 144 value: '1872', 145 dailyBreakdown: [], 146 }, 147 }, 148 }; 149 }; 150 151 export const getMockSuggestedFullClusterSummary = (id: string, algorithm = 'reason-v3'): ClusterSummary => { 152 return { 153 clusterId: { 154 'algorithm': algorithm, 155 'id': id, 156 }, 157 bug: undefined, 158 title: 'reason LIKE "blah%"', 159 metrics: { 160 'human-cls-failed-presubmit': { 161 value: '29', 162 dailyBreakdown: new Array(7).fill('4'), 163 }, 164 'critical-failures-exonerated': { 165 value: '919', 166 dailyBreakdown: new Array(7).fill('5'), 167 }, 168 'failures': { 169 value: '1872', 170 dailyBreakdown: new Array(7).fill('6'), 171 }, 172 }, 173 }; 174 }; 175 176 export const getMockClusterExoneratedTestVariant = (id: string, exoneratedFailures: number): ClusterExoneratedTestVariant => { 177 return { 178 testId: id, 179 variant: undefined, 180 criticalFailuresExonerated: exoneratedFailures, 181 lastExoneration: '2052-01-02T03:04:05.678901234Z', 182 }; 183 }; 184 185 export const getMockClusterExoneratedTestVariantBranch = (id: string, exoneratedFailures: number): ClusterExoneratedTestVariantBranch => { 186 return { 187 project: 'myproject', 188 testId: id, 189 variant: undefined, 190 sourceRef: { 191 gitiles: { 192 host: 'myproject.googlesource.com', 193 project: 'myproject/src', 194 ref: 'refs/heads/mybranch', 195 }, 196 }, 197 criticalFailuresExonerated: exoneratedFailures, 198 lastExoneration: '2052-01-02T03:04:05.678901234Z', 199 }; 200 }; 201 202 export const mockQueryClusterSummaries = (request: QueryClusterSummariesRequest, response: QueryClusterSummariesResponse, overwriteRoutes = true) => { 203 fetchMock.post({ 204 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/QueryClusterSummaries', 205 body: QueryClusterSummariesRequest.toJSON(request) as object, 206 }, { 207 headers: { 208 'X-Prpc-Grpc-Code': '0', 209 }, 210 body: ')]}\'\n' + JSON.stringify(QueryClusterSummariesResponse.toJSON(response)), 211 }, { overwriteRoutes: overwriteRoutes }); 212 }; 213 214 export const mockGetCluster = ( 215 project: string, 216 algorithm: string, 217 id: string, 218 response: Cluster) => { 219 const request: GetClusterRequest = { 220 name: `projects/${encodeURIComponent(project)}/clusters/${encodeURIComponent(algorithm)}/${encodeURIComponent(id)}`, 221 }; 222 223 fetchMock.post({ 224 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/Get', 225 body: request, 226 }, { 227 headers: { 228 'X-Prpc-Grpc-Code': '0', 229 }, 230 body: ')]}\'\n' + JSON.stringify(Cluster.toJSON(response) as object), 231 }, { overwriteRoutes: true }); 232 }; 233 234 export const mockQueryClusterFailures = (request: QueryClusterFailuresRequest, failures: DistinctClusterFailure[]) => { 235 const response: QueryClusterFailuresResponse = { 236 failures: failures, 237 }; 238 fetchMock.post({ 239 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/QueryClusterFailures', 240 body: QueryClusterFailuresRequest.toJSON(request) as object, 241 }, { 242 headers: { 243 'X-Prpc-Grpc-Code': '0', 244 }, 245 body: ')]}\'\n' + JSON.stringify(QueryClusterFailuresResponse.toJSON(response) as object), 246 }, { overwriteRoutes: true }); 247 }; 248 249 export const mockQueryExoneratedTestVariants = (parent: string, testVariants: ClusterExoneratedTestVariant[]) => { 250 const request: QueryClusterExoneratedTestVariantsRequest = { 251 parent: parent, 252 }; 253 const response: QueryClusterExoneratedTestVariantsResponse = { 254 testVariants: testVariants, 255 }; 256 fetchMock.post({ 257 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/QueryExoneratedTestVariants', 258 body: QueryClusterExoneratedTestVariantsRequest.toJSON(request) as object, 259 }, { 260 headers: { 261 'X-Prpc-Grpc-Code': '0', 262 }, 263 body: ')]}\'\n' + JSON.stringify(QueryClusterExoneratedTestVariantsResponse.toJSON(response)), 264 }, { overwriteRoutes: true }); 265 }; 266 267 export const mockQueryExoneratedTestVariantBranches = (parent: string, testVariantBranches: ClusterExoneratedTestVariantBranch[]) => { 268 const request: QueryClusterExoneratedTestVariantBranchesRequest = { 269 parent: parent, 270 }; 271 const response: QueryClusterExoneratedTestVariantBranchesResponse = { 272 testVariantBranches: testVariantBranches, 273 }; 274 fetchMock.post({ 275 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/QueryExoneratedTestVariantBranches', 276 body: QueryClusterExoneratedTestVariantBranchesRequest.toJSON(request) as object, 277 }, { 278 headers: { 279 'X-Prpc-Grpc-Code': '0', 280 }, 281 body: ')]}\'\n' + JSON.stringify(QueryClusterExoneratedTestVariantBranchesResponse.toJSON(response)), 282 }, { overwriteRoutes: true }); 283 }; 284 285 export const mockQueryHistory = ( 286 response: QueryClusterHistoryResponse) => { 287 fetchMock.post({ 288 url: 'http://localhost/prpc/luci.analysis.v1.Clusters/QueryHistory', 289 }, { 290 headers: { 291 'X-Prpc-Grpc-Code': '0', 292 }, 293 body: ')]}\'\n' + JSON.stringify(QueryClusterHistoryResponse.toJSON(response)), 294 }, { overwriteRoutes: true }); 295 }; 296 297 export const mockReclusteringProgress = (response: ReclusteringProgress) => { 298 fetchMock.post('http://localhost/prpc/luci.analysis.v1.Clusters/GetReclusteringProgress', { 299 headers: { 300 'X-Prpc-Grpc-Code': '0', 301 }, 302 body: ')]}\'\n'+JSON.stringify(ReclusteringProgress.toJSON(response)), 303 }, { overwriteRoutes: true }); 304 };