@@ -1294,6 +1294,143 @@ impl Xtasks {
1294
1294
bail ! ( "Failed to run bencher: {:?}" , out) ;
1295
1295
}
1296
1296
1297
+ // if we're on linux and publishing and on main synch graphs
1298
+ if os == "linux" && is_main && execute {
1299
+ Self :: synch_bencher_graphs ( ) ?;
1300
+ }
1301
+
1302
+ Ok ( ( ) )
1303
+ }
1304
+
1305
+ fn synch_bencher_graphs ( ) -> Result < ( ) > {
1306
+ // first run `bencher benchmark list bms
1307
+ // this produces list of objects each containing a `uuid` and `name`
1308
+
1309
+ let parse_list_of_dicts = |bytes : Vec < u8 > | {
1310
+ serde_json:: from_slice :: < Vec < HashMap < String , String > > > ( & bytes)
1311
+ . with_context ( || "Could not parse bencher output" )
1312
+ } ;
1313
+
1314
+ let token = std:: env:: var ( "BENCHER_API_TOKEN" ) . ok ( ) ;
1315
+ let mut bencher_cmd = Command :: new ( "bencher" ) ;
1316
+ let benchmarks = bencher_cmd
1317
+ . arg ( "benchmark" )
1318
+ . args ( [ "list" , "bms" ] )
1319
+ . args ( [ "--token" , & token. clone ( ) . unwrap_or_default ( ) ] )
1320
+ . output ( )
1321
+ . with_context ( || "Could not list benchmarks" ) ?;
1322
+ if !benchmarks. status . success ( ) {
1323
+ bail ! ( "Failed to list benchmarks: {:?}" , benchmarks) ;
1324
+ }
1325
+
1326
+ // parse teh name and uuid pairs
1327
+ let benchmarks = parse_list_of_dicts ( benchmarks. stdout ) ?
1328
+ . into_iter ( )
1329
+ . map ( |p| {
1330
+ let name = p. get ( "name" ) . expect ( "no name in project" ) ;
1331
+ let uuid = p. get ( "uuid" ) . expect ( "no uuid in project" ) ;
1332
+ ( name. clone ( ) , uuid. clone ( ) )
1333
+ } )
1334
+ . collect :: < Vec < _ > > ( ) ;
1335
+
1336
+ // delete all plots using bencher plot list bms to get "uuid's"
1337
+ // then bencher plot delete bms <uuid>
1338
+
1339
+ let bencher_cmd = Command :: new ( "bencher" )
1340
+ . stdout ( std:: process:: Stdio :: inherit ( ) )
1341
+ . stderr ( std:: process:: Stdio :: inherit ( ) )
1342
+ . args ( [ "plot" , "list" , "bms" ] )
1343
+ . args ( [ "--token" , & token. clone ( ) . unwrap_or_default ( ) ] )
1344
+ . output ( )
1345
+ . with_context ( || "Could not list plots" ) ?;
1346
+
1347
+ if !bencher_cmd. status . success ( ) {
1348
+ bail ! ( "Failed to list plots: {:?}" , bencher_cmd) ;
1349
+ }
1350
+
1351
+ let plots = parse_list_of_dicts ( bencher_cmd. stdout ) ?
1352
+ . into_iter ( )
1353
+ . map ( |p| {
1354
+ let uuid = p. get ( "uuid" ) . expect ( "no uuid in plot" ) ;
1355
+ uuid. clone ( )
1356
+ } )
1357
+ . collect :: < Vec < _ > > ( ) ;
1358
+
1359
+ for uuid in plots {
1360
+ let bencher_cmd = Command :: new ( "bencher" )
1361
+ . stdout ( std:: process:: Stdio :: inherit ( ) )
1362
+ . stderr ( std:: process:: Stdio :: inherit ( ) )
1363
+ . args ( [ "plot" , "delete" , "bms" , & uuid] )
1364
+ . args ( [ "--token" , & token. clone ( ) . unwrap_or_default ( ) ] )
1365
+ . output ( )
1366
+ . with_context ( || "Could not delete plot" ) ?;
1367
+
1368
+ if !bencher_cmd. status . success ( ) {
1369
+ bail ! ( "Failed to delete plot: {:?}" , bencher_cmd) ;
1370
+ }
1371
+ }
1372
+ let testbeds = Command :: new ( "bencher" )
1373
+ . arg ( "testbed" )
1374
+ . args ( [ "list" , "bms" ] )
1375
+ . args ( [ "--token" , & token. clone ( ) . unwrap_or_default ( ) ] )
1376
+ . output ( )
1377
+ . with_context ( || "Could not list testbeds" ) ?;
1378
+
1379
+ if !testbeds. status . success ( ) {
1380
+ bail ! ( "Failed to list testbeds: {:?}" , testbeds) ;
1381
+ }
1382
+
1383
+ let testbeds = parse_list_of_dicts ( testbeds. stdout ) ?
1384
+ . into_iter ( )
1385
+ . map ( |p| {
1386
+ let name = p. get ( "name" ) . expect ( "no name in testbed" ) ;
1387
+ let uuid = p. get ( "uuid" ) . expect ( "no uuid in testbed" ) ;
1388
+ ( name. clone ( ) , uuid. clone ( ) )
1389
+ } )
1390
+ . filter ( |( name, _) | name. contains ( "gha" ) )
1391
+ . collect :: < Vec < _ > > ( ) ;
1392
+
1393
+ let group_to_benchmark_map: HashMap < _ , Vec < _ > > =
1394
+ benchmarks
1395
+ . iter ( )
1396
+ . fold ( HashMap :: new ( ) , |mut acc, ( name, uuid) | {
1397
+ let group = name. split ( '/' ) . next ( ) . unwrap_or_default ( ) ;
1398
+ acc. entry ( group. to_owned ( ) ) . or_default ( ) . push ( uuid. clone ( ) ) ;
1399
+ acc
1400
+ } ) ;
1401
+
1402
+ // create plot using
1403
+ // bencher plot create --x-axis date_time --branches main --testbeds <uuids> --benchmarks <uuids> --measures latency
1404
+
1405
+ for ( group, uuids) in group_to_benchmark_map {
1406
+ for ( testbed_name, testbed_uuid) in testbeds. iter ( ) {
1407
+ let without_gha = testbed_name. replace ( "-gha" , "" ) ;
1408
+ let plot_name = format ! ( "{without_gha} {group}" ) ;
1409
+
1410
+ let window_months = 12 ;
1411
+ let window_seconds = window_months * 30 * 24 * 60 * 60 ;
1412
+ let bencher_cmd = Command :: new ( "bencher" )
1413
+ . stdout ( std:: process:: Stdio :: inherit ( ) )
1414
+ . stderr ( std:: process:: Stdio :: inherit ( ) )
1415
+ . args ( [ "plot" , "create" , "bms" ] )
1416
+ . args ( [ "--title" , & plot_name] )
1417
+ . arg ( "--upper-boundary" )
1418
+ . args ( [ "--x-axis" , "date_time" ] )
1419
+ . args ( [ "--window" , & window_seconds. to_string ( ) ] )
1420
+ . args ( [ "--branches" , "main" ] )
1421
+ . args ( [ "--testbeds" , testbed_uuid] )
1422
+ . args ( [ "--benchmarks" , & uuids. join ( "," ) ] )
1423
+ . args ( [ "--measures" , "latency" ] )
1424
+ . args ( [ "--token" , & token. clone ( ) . unwrap_or_default ( ) ] )
1425
+ . output ( )
1426
+ . with_context ( || "Could not create plot" ) ?;
1427
+
1428
+ if !bencher_cmd. status . success ( ) {
1429
+ bail ! ( "Failed to create plot: {:?}" , bencher_cmd) ;
1430
+ }
1431
+ }
1432
+ }
1433
+
1297
1434
Ok ( ( ) )
1298
1435
}
1299
1436
0 commit comments