@@ -35,6 +35,68 @@ pub enum PerfCheckError {
35
35
TimeOut { elapsed : Duration , limit : Duration } ,
36
36
}
37
37
38
+ #[ cfg( build_type = "release" ) ]
39
+ fn dummy_file_path ( ) -> std:: io:: Result < std:: path:: PathBuf > {
40
+ use std:: { fs, io, path:: Path } ;
41
+
42
+ let home_dir =
43
+ std:: env:: var ( "HOME" ) . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) ) ?;
44
+ let path = Path :: new ( & home_dir) . join ( ".polkadot" ) ;
45
+
46
+ if let Err ( err) = fs:: create_dir ( & path) {
47
+ if err. kind ( ) != io:: ErrorKind :: AlreadyExists {
48
+ return Err ( err)
49
+ }
50
+ }
51
+
52
+ Ok ( path. join ( "perf_check_passed" ) )
53
+ }
54
+
55
+ #[ cfg( build_type = "release" ) ]
56
+ fn check_dummy_file ( path : & std:: path:: Path ) -> std:: io:: Result < bool > {
57
+ use nix:: unistd;
58
+ use std:: {
59
+ fs,
60
+ io:: { self , Read } ,
61
+ } ;
62
+
63
+ let host_name_max_len = unistd:: SysconfVar :: HOST_NAME_MAX as usize ;
64
+
65
+ let mut host_name = vec ! [ 0u8 ; host_name_max_len] ;
66
+ let mut buf = host_name. clone ( ) ;
67
+ unistd:: gethostname ( & mut host_name) . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) ) ?;
68
+
69
+ let dummy_file = match fs:: File :: open ( path) {
70
+ Ok ( file) => file,
71
+ Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => return Ok ( false ) ,
72
+ Err ( err) => return Err ( err) ,
73
+ } ;
74
+ let mut reader = io:: BufReader :: new ( dummy_file) ;
75
+
76
+ reader. read_exact ( & mut buf) ?;
77
+
78
+ Ok ( host_name == buf)
79
+ }
80
+
81
+ #[ cfg( build_type = "release" ) ]
82
+ fn save_dummy_file ( path : & std:: path:: Path ) -> std:: io:: Result < ( ) > {
83
+ use nix:: unistd;
84
+ use std:: {
85
+ fs:: OpenOptions ,
86
+ io:: { self , Write } ,
87
+ } ;
88
+
89
+ let host_name_max_len = unistd:: SysconfVar :: HOST_NAME_MAX as usize ;
90
+ let mut host_name = vec ! [ 0u8 ; host_name_max_len] ;
91
+ unistd:: gethostname ( & mut host_name) . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) ) ?;
92
+
93
+ let mut dummy_file = OpenOptions :: new ( ) . truncate ( true ) . create ( true ) . write ( true ) . open ( path) ?;
94
+
95
+ dummy_file. write ( & host_name) ?;
96
+
97
+ Ok ( ( ) )
98
+ }
99
+
38
100
/// Runs a performance check via compiling sample wasm code with a timeout.
39
101
/// Should only be run in release build since the check would take too much time otherwise.
40
102
/// Returns `Ok` immediately if the check has been passed previously.
@@ -46,29 +108,26 @@ pub fn host_perf_check() -> Result<(), PerfCheckError> {
46
108
#[ cfg( build_type = "release" ) ]
47
109
{
48
110
use polkadot_node_core_pvf:: sp_maybe_compressed_blob;
49
- use std:: { fs:: OpenOptions , path:: Path } ;
50
111
51
112
const PERF_CHECK_TIME_LIMIT : Duration = Duration :: from_secs ( 20 ) ;
52
113
const CODE_SIZE_LIMIT : usize = 1024usize . pow ( 3 ) ;
53
114
const WASM_CODE : & [ u8 ] = include_bytes ! (
54
115
"../../target/release/wbuild/kusama-runtime/kusama_runtime.compact.compressed.wasm"
55
116
) ;
56
- const CHECK_PASSED_FILE_NAME : & str = ".perf_check_passed" ;
57
-
58
- // We will try to save a dummy file to the same path as the polkadot binary
59
- // to make it independent from the current directory.
60
- let check_passed_path = std:: env:: current_exe ( )
61
- . map ( |mut path| {
62
- path. pop ( ) ;
63
- path
64
- } )
65
- . unwrap_or_default ( )
66
- . join ( CHECK_PASSED_FILE_NAME ) ;
67
-
68
- // To avoid running the check on every launch we create a dummy dot-file on success.
69
- if Path :: new ( & check_passed_path) . exists ( ) {
70
- log:: info!( "Performance check skipped: already passed" ) ;
71
- return Ok ( ( ) )
117
+
118
+ // We will try to save a dummy file at $HOME/.polkadot/perf_check_passed.
119
+ let dummy_file_path =
120
+ dummy_file_path ( )
121
+ . map_err ( |err| {
122
+ log:: info!( "Performance check result is not going to be persisted due to an error: {:?}" , err)
123
+ } )
124
+ . ok ( ) ;
125
+
126
+ if let Some ( ref path) = dummy_file_path {
127
+ if let Ok ( true ) = check_dummy_file ( path) {
128
+ log:: info!( "Performance check skipped: already passed" ) ;
129
+ return Ok ( ( ) )
130
+ }
72
131
}
73
132
74
133
log:: info!( "Running the performance check..." ) ;
@@ -84,8 +143,8 @@ pub fn host_perf_check() -> Result<(), PerfCheckError> {
84
143
let elapsed = start. elapsed ( ) ;
85
144
if elapsed <= PERF_CHECK_TIME_LIMIT {
86
145
log:: info!( "Performance check passed, elapsed: {:?}" , start. elapsed( ) ) ;
87
- // `touch` a dummy file.
88
- let _ = OpenOptions :: new ( ) . create ( true ) . write ( true ) . open ( Path :: new ( & check_passed_path ) ) ;
146
+ // Save a dummy file.
147
+ dummy_file_path . map ( |path| save_dummy_file ( & path ) ) ;
89
148
Ok ( ( ) )
90
149
} else {
91
150
Err ( PerfCheckError :: TimeOut { elapsed, limit : PERF_CHECK_TIME_LIMIT } )
0 commit comments