Add #[test]s, fix [State::merge()], fix [quit_twice]

This commit is contained in:
hinto-janaiyo 2022-12-17 17:17:26 -05:00
parent 95fffac3cd
commit e35f5b243b
No known key found for this signature in database
GPG key ID: B1C5A64B80691E45
6 changed files with 627 additions and 116 deletions

52
Cargo.lock generated
View file

@ -2095,9 +2095,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jni"
@ -2787,9 +2787,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b"
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "pathdiff"
@ -3009,9 +3009,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.47"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
checksum = "e9d89e5dba24725ae5678020bf8f1357a9aa7ff10736b551adbcd3f8d17d766f"
dependencies = [
"unicode-ident",
]
@ -3024,9 +3024,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "556d0f47a940e895261e77dc200d5eadfc6ef644c179c6f5edfc105e3a2292c8"
dependencies = [
"proc-macro2",
]
@ -3291,15 +3291,15 @@ dependencies = [
[[package]]
name = "rustversion"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
checksum = "4378ea89513870b6e2303ec50618e97da0fa43cdd9ded83ad3b6bad2693c08c6"
[[package]]
name = "ryu"
version = "1.0.11"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "safe_arch"
@ -3405,9 +3405,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.14"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
checksum = "3bfa246f936730408c0abee392cc1a50b118ece708c7f630516defd64480c7d8"
[[package]]
name = "serde"
@ -3431,18 +3431,18 @@ dependencies = [
[[package]]
name = "serde_ignored"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b3da7eedd967647a866f67829d1c79d184d7c4521126e9cc2c46a9585c6d21"
checksum = "51212eb6171778353d78ef5860fdffe29ac17f03a69375d2dc14fbb5754d54a4"
dependencies = [
"serde",
]
[[package]]
name = "serde_json"
version = "1.0.89"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
checksum = "8778cc0b528968fe72abec38b5db5a20a70d148116cd9325d2bc5f5180ca3faf"
dependencies = [
"itoa",
"ryu",
@ -3800,9 +3800,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.105"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
checksum = "09ee3a69cd2c7e06684677e5629b3878b253af05e4714964204279c6bc02cf0b"
dependencies = [
"proc-macro2",
"quote",
@ -3904,18 +3904,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
@ -4730,9 +4730,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.5"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-normalization"

View file

@ -293,3 +293,24 @@ pub const ARG_COPYRIGHT: &str =
r#"Gupax is licensed under GPLv3.
For more information, see link below:
<https://github.com/hinto-janaiyo/gupax>"#;
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn gupax_version_is_semver() {
assert_eq!(crate::GUPAX_VERSION.len(), 6);
}
#[test]
fn app_ratio_is_4_by_3() {
assert_eq!(format!("{:.3}", crate::APP_MIN_WIDTH/crate::APP_MIN_HEIGHT), "1.333");
assert_eq!(format!("{:.3}", crate::APP_MAX_WIDTH/crate::APP_MAX_HEIGHT), "1.333");
assert_eq!(format!("{:.3}", crate::APP_DEFAULT_WIDTH/crate::APP_DEFAULT_HEIGHT), "1.333");
}
#[test]
fn git_commit_is_41_chars() {
assert_eq!(crate::COMMIT.len(), 41);
}
}

View file

@ -151,74 +151,10 @@ impl State {
let max_threads = num_cpus::get();
let current_threads = if max_threads == 1 { 1 } else { max_threads / 2 };
Self {
gupax: Gupax {
simple: true,
auto_update: true,
auto_p2pool: false,
auto_xmrig: false,
ask_before_quit: true,
save_before_quit: true,
#[cfg(not(target_os = "macos"))]
update_via_tor: true,
#[cfg(target_os = "macos")] // Arti library has issues on macOS
update_via_tor: false,
p2pool_path: DEFAULT_P2POOL_PATH.to_string(),
xmrig_path: DEFAULT_XMRIG_PATH.to_string(),
absolute_p2pool_path: into_absolute_path(DEFAULT_P2POOL_PATH.to_string()).unwrap(),
absolute_xmrig_path: into_absolute_path(DEFAULT_XMRIG_PATH.to_string()).unwrap(),
selected_width: APP_DEFAULT_WIDTH as u16,
selected_height: APP_DEFAULT_HEIGHT as u16,
ratio: Ratio::Width,
tab: Tab::About,
},
p2pool: P2pool {
simple: true,
mini: true,
auto_ping: true,
auto_select: true,
out_peers: 10,
in_peers: 10,
log_level: 3,
node: crate::NodeEnum::C3pool,
arguments: String::new(),
address: String::with_capacity(96),
name: "Local Monero Node".to_string(),
ip: "localhost".to_string(),
rpc: "18081".to_string(),
zmq: "18083".to_string(),
selected_index: 0,
selected_name: "Local Monero Node".to_string(),
selected_ip: "localhost".to_string(),
selected_rpc: "18081".to_string(),
selected_zmq: "18083".to_string(),
},
xmrig: Xmrig {
simple: true,
pause: 0,
simple_rig: String::with_capacity(30),
arguments: String::with_capacity(300),
address: String::with_capacity(96),
name: "Local P2Pool".to_string(),
rig: GUPAX_VERSION_UNDERSCORE.to_string(),
ip: "localhost".to_string(),
port: "3333".to_string(),
selected_index: 0,
selected_name: "Local P2Pool".to_string(),
selected_ip: "localhost".to_string(),
selected_rig: GUPAX_VERSION_UNDERSCORE.to_string(),
selected_port: "3333".to_string(),
api_ip: "localhost".to_string(),
api_port: "18088".to_string(),
tls: false,
keepalive: false,
current_threads,
max_threads,
},
version: Arc::new(Mutex::new(Version {
gupax: GUPAX_VERSION.to_string(),
p2pool: P2POOL_VERSION.to_string(),
xmrig: XMRIG_VERSION.to_string(),
})),
gupax: Gupax::default(),
p2pool: P2pool::default(),
xmrig: Xmrig::with_threads(max_threads, current_threads),
version: Arc::new(Mutex::new(Version::default())),
}
}
@ -237,6 +173,14 @@ impl State {
}
}
// Conver [State] to [String]
pub fn to_string(&self) -> Result<String, TomlError> {
match toml::ser::to_string(self) {
Ok(s) => Ok(s),
Err(e) => { error!("State | Couldn't serialize default file: {}", e); Err(TomlError::Serialize(e)) },
}
}
// Combination of multiple functions:
// 1. Attempt to read file from path into [String]
// |_ Create a default file if not found
@ -261,7 +205,10 @@ impl State {
Ok(s) => Ok(s),
Err(_) => {
warn!("State | Attempting merge...");
Self::merge(string, path)
match Self::merge(&string) {
Ok(mut new) => { Self::save(&mut new, path)?; Ok(new) },
Err(e) => Err(e),
}
},
}
}
@ -271,10 +218,7 @@ impl State {
pub fn create_new(path: &PathBuf) -> Result<Self, TomlError> {
info!("State | Creating new default...");
let new = Self::new();
let string = match toml::ser::to_string(&new) {
Ok(o) => o,
Err(e) => { error!("State | Couldn't serialize default file: {}", e); return Err(TomlError::Serialize(e)) },
};
let string = Self::to_string(&new)?;
fs::write(path, string)?;
info!("State | Write ... OK");
Ok(new)
@ -302,18 +246,12 @@ impl State {
// Take [String] as input, merge it with whatever the current [default] is,
// leaving behind old keys+values and updating [default] with old valid ones.
// Automatically overwrite current file.
pub fn merge(old: String, path: &PathBuf) -> Result<Self, TomlError> {
let default = match toml::ser::to_string(&Self::new()) {
Ok(string) => { info!("State | Default TOML parse ... OK"); string },
Err(err) => { error!("State | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
};
let mut new: Self = match Figment::new().merge(Toml::string(&old)).merge(Toml::string(&default)).extract() {
pub fn merge(old: &str) -> Result<Self, TomlError> {
let default = toml::ser::to_string(&Self::new()).unwrap();
let new: Self = match Figment::from(Toml::string(&default)).merge(Toml::string(&old)).extract() {
Ok(new) => { info!("State | TOML merge ... OK"); new },
Err(err) => { error!("State | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
};
// Attempt save
Self::save(&mut new, path)?;
Ok(new)
}
}
@ -705,3 +643,322 @@ pub struct Version {
pub p2pool: String,
pub xmrig: String,
}
//---------------------------------------------------------------------------------------------------- [State] Defaults
impl Default for Gupax {
fn default() -> Self {
Self {
simple: true,
auto_update: true,
auto_p2pool: false,
auto_xmrig: false,
ask_before_quit: true,
save_before_quit: true,
#[cfg(not(target_os = "macos"))]
update_via_tor: true,
#[cfg(target_os = "macos")] // Arti library has issues on macOS
update_via_tor: false,
p2pool_path: DEFAULT_P2POOL_PATH.to_string(),
xmrig_path: DEFAULT_XMRIG_PATH.to_string(),
absolute_p2pool_path: into_absolute_path(DEFAULT_P2POOL_PATH.to_string()).unwrap(),
absolute_xmrig_path: into_absolute_path(DEFAULT_XMRIG_PATH.to_string()).unwrap(),
selected_width: APP_DEFAULT_WIDTH as u16,
selected_height: APP_DEFAULT_HEIGHT as u16,
ratio: Ratio::Width,
tab: Tab::About,
}
}
}
impl Default for P2pool {
fn default() -> Self {
Self {
simple: true,
mini: true,
auto_ping: true,
auto_select: true,
out_peers: 10,
in_peers: 10,
log_level: 3,
node: crate::NodeEnum::C3pool,
arguments: String::new(),
address: String::with_capacity(96),
name: "Local Monero Node".to_string(),
ip: "localhost".to_string(),
rpc: "18081".to_string(),
zmq: "18083".to_string(),
selected_index: 0,
selected_name: "Local Monero Node".to_string(),
selected_ip: "localhost".to_string(),
selected_rpc: "18081".to_string(),
selected_zmq: "18083".to_string(),
}
}
}
impl Xmrig {
fn with_threads(max_threads: usize, current_threads: usize) -> Self {
let mut xmrig = Self::default();
Self {
max_threads,
current_threads,
..xmrig
}
}
}
impl Default for Xmrig {
fn default() -> Self {
Self {
simple: true,
pause: 0,
simple_rig: String::with_capacity(30),
arguments: String::with_capacity(300),
address: String::with_capacity(96),
name: "Local P2Pool".to_string(),
rig: GUPAX_VERSION_UNDERSCORE.to_string(),
ip: "localhost".to_string(),
port: "3333".to_string(),
selected_index: 0,
selected_name: "Local P2Pool".to_string(),
selected_ip: "localhost".to_string(),
selected_rig: GUPAX_VERSION_UNDERSCORE.to_string(),
selected_port: "3333".to_string(),
api_ip: "localhost".to_string(),
api_port: "18088".to_string(),
tls: false,
keepalive: false,
current_threads: 1,
max_threads: 1,
}
}
}
impl Default for Version {
fn default() -> Self {
Self {
gupax: GUPAX_VERSION.to_string(),
p2pool: P2POOL_VERSION.to_string(),
xmrig: XMRIG_VERSION.to_string(),
}
}
}
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn serde_default_state() {
let state = crate::State::new();
let string = crate::State::to_string(&state).unwrap();
crate::State::from_str(&string).unwrap();
}
#[test]
fn serde_default_node() {
let node = crate::Node::new_vec();
let string = crate::Node::to_string(&node).unwrap();
crate::Node::from_str_to_vec(&string).unwrap();
}
#[test]
fn serde_default_pool() {
let pool = crate::Pool::new_vec();
let string = crate::Pool::to_string(&pool).unwrap();
crate::Pool::from_str_to_vec(&string).unwrap();
}
#[test]
fn serde_custom_state() {
let state = r#"
[gupax]
simple = true
auto_update = true
auto_p2pool = false
auto_xmrig = false
ask_before_quit = true
save_before_quit = true
update_via_tor = true
p2pool_path = "p2pool/p2pool"
xmrig_path = "xmrig/xmrig"
absolute_p2pool_path = "/home/hinto/p2pool/p2pool"
absolute_xmrig_path = "/home/hinto/xmrig/xmrig"
selected_width = 1280
selected_height = 960
tab = "About"
ratio = "Width"
[p2pool]
simple = true
mini = true
auto_ping = true
auto_select = true
out_peers = 10
in_peers = 450
log_level = 3
node = "Seth"
arguments = ""
address = "44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW"
name = "Local Monero Node"
ip = "192.168.1.123"
rpc = "18089"
zmq = "18083"
selected_index = 0
selected_name = "Local Monero Node"
selected_ip = "192.168.1.123"
selected_rpc = "18089"
selected_zmq = "18083"
[xmrig]
simple = true
pause = 0
simple_rig = ""
arguments = ""
tls = false
keepalive = false
max_threads = 32
current_threads = 16
address = ""
api_ip = "localhost"
api_port = "18088"
name = "linux"
rig = "Gupax"
ip = "192.168.1.122"
port = "3333"
selected_index = 1
selected_name = "linux"
selected_rig = "Gupax"
selected_ip = "192.168.1.122"
selected_port = "3333"
[version]
gupax = "v1.0.0"
p2pool = "v2.5"
xmrig = "v6.18.0"
"#;
let state = crate::State::from_str(state).unwrap();
crate::State::to_string(&state).unwrap();
}
#[test]
fn serde_custom_node() {
let node = r#"
['Local Monero Node']
ip = "localhost"
rpc = "18081"
zmq = "18083"
['asdf-_. ._123']
ip = "localhost"
rpc = "11"
zmq = "1234"
['aaa bbb']
ip = "192.168.2.333"
rpc = "1"
zmq = "65535"
"#;
let node = crate::Node::from_str_to_vec(node).unwrap();
crate::Node::to_string(&node).unwrap();
}
#[test]
fn serde_custom_pool() {
let pool = r#"
['Local P2Pool']
rig = "Gupax_v1.0.0"
ip = "localhost"
port = "3333"
['aaa xx .. -']
rig = "Gupax"
ip = "192.168.22.22"
port = "1"
[' a']
rig = "Gupax_v1.0.0"
ip = "127.0.0.1"
port = "65535"
"#;
let pool = crate::Pool::from_str_to_vec(pool).unwrap();
crate::Pool::to_string(&pool).unwrap();
}
// Make sure we keep the user's old values that are still
// valid but discard the ones that don't exist anymore.
#[test]
fn merge_state() {
let bad_state = r#"
[gupax]
SETTING_THAT_DOESNT_EXIST_ANYMORE = 123123
simple = false
auto_update = true
auto_p2pool = false
auto_xmrig = false
ask_before_quit = true
save_before_quit = true
update_via_tor = true
p2pool_path = "p2pool/p2pool"
xmrig_path = "xmrig/xmrig"
absolute_p2pool_path = ""
absolute_xmrig_path = ""
selected_width = 0
selected_height = 0
tab = "About"
ratio = "Width"
[p2pool]
SETTING_THAT_DOESNT_EXIST_ANYMORE = "String"
simple = true
mini = true
auto_ping = true
auto_select = true
out_peers = 10
in_peers = 450
log_level = 6
node = "Seth"
arguments = ""
address = "44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW"
name = "Local Monero Node"
ip = "localhost"
rpc = "18081"
zmq = "18083"
selected_index = 0
selected_name = "Local Monero Node"
selected_ip = "localhost"
selected_rpc = "18081"
selected_zmq = "18083"
[xmrig]
SETTING_THAT_DOESNT_EXIST_ANYMORE = true
simple = true
pause = 0
simple_rig = ""
arguments = ""
tls = false
keepalive = false
max_threads = 32
current_threads = 16
address = ""
api_ip = "localhost"
api_port = "18088"
name = "Local P2Pool"
rig = "Gupax_v1.0.0"
ip = "localhost"
port = "3333"
selected_index = 0
selected_name = "Local P2Pool"
selected_rig = "Gupax_v1.0.0"
selected_ip = "localhost"
selected_port = "3333"
[version]
gupax = "v1.0.0"
p2pool = "v2.5"
xmrig = "v6.18.0"
"#.to_string();
let merged_state = crate::State::merge(&bad_state).unwrap();
let merged_state = crate::State::to_string(&merged_state).unwrap();
println!("{}", merged_state);
assert!(merged_state.contains("simple = false"));
assert!(merged_state.contains("in_peers = 450"));
assert!(merged_state.contains("log_level = 6"));
assert!(merged_state.contains(r#"node = "Seth""#));
assert!(!merged_state.contains("SETTING_THAT_DOESNT_EXIST_ANYMORE"));
assert!(merged_state.contains("44hintoFpuo3ugKfcqJvh5BmrsTRpnTasJmetKC4VXCt6QDtbHVuixdTtsm6Ptp7Y8haXnJ6j8Gj2dra8CKy5ewz7Vi9CYW"));
}
}

View file

@ -1713,3 +1713,179 @@ impl Hashrate {
}
}
}
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn calc_payouts_and_xmr_from_output_p2pool() {
use crate::helper::{PubP2poolApi,P2poolRegex};
use std::sync::{Arc,Mutex};
let public = Arc::new(Mutex::new(PubP2poolApi::new()));
let output_parse = Arc::new(Mutex::new(String::from(
r#"You received a payout of 5.000000000001 XMR in block 1111
You received a payout of 5.000000000001 XMR in block 1112
You received a payout of 5.000000000001 XMR in block 1113"#
)));
let output_pub = Arc::new(Mutex::new(String::new()));
let elapsed = std::time::Duration::from_secs(60);
let regex = P2poolRegex::new();
PubP2poolApi::update_from_output(&public, &output_parse, &output_pub, elapsed, &regex);
let public = public.lock().unwrap();
println!("{:#?}", public);
assert_eq!(public.payouts, 3);
assert_eq!(public.payouts_hour, 180.0);
assert_eq!(public.payouts_day, 4320.0);
assert_eq!(public.payouts_month, 129600.0);
assert_eq!(public.xmr, 15.000000000003);
assert_eq!(public.xmr_hour, 900.00000000018);
assert_eq!(public.xmr_day, 21600.00000000432);
assert_eq!(public.xmr_month, 648000.0000001296);
}
#[test]
fn serde_priv_p2pool_api() {
let data =
r#"{
"hashrate_15m": 12,
"hashrate_1h": 11111,
"hashrate_24h": 468967,
"total_hashes": 2019283840922394082390,
"shares_found": 289037,
"average_effort": 915.563,
"current_effort": 129.297,
"connections": 123,
"incoming_connections": 96
}"#;
use crate::helper::PrivP2poolApi;
let priv_api = PrivP2poolApi::str_to_priv_p2pool_api(data).unwrap();
let json = serde_json::ser::to_string_pretty(&priv_api).unwrap();
println!("{}", json);
let data_after_ser =
r#"{
"hashrate_15m": 12,
"hashrate_1h": 11111,
"hashrate_24h": 468967,
"shares_found": 289037,
"average_effort": 915.563,
"current_effort": 129.297,
"connections": 123
}"#;
assert_eq!(data_after_ser, json)
}
#[test]
fn serde_priv_xmrig_api() {
let data =
r#"{
"id": "6226e3sd0cd1a6es",
"worker_id": "hinto",
"uptime": 123,
"restricted": true,
"resources": {
"memory": {
"free": 123,
"total": 123123,
"resident_set_memory": 123123123
},
"load_average": [10.97, 10.58, 10.47],
"hardware_concurrency": 12
},
"features": ["api", "asm", "http", "hwloc", "tls", "opencl", "cuda"],
"results": {
"diff_current": 123,
"shares_good": 123,
"shares_total": 123,
"avg_time": 123,
"avg_time_ms": 123,
"hashes_total": 123,
"best": [123, 123, 123, 13, 123, 123, 123, 123, 123, 123],
"error_log": []
},
"algo": "rx/0",
"connection": {
"pool": "localhost:3333",
"ip": "127.0.0.1",
"uptime": 123,
"uptime_ms": 123,
"ping": 0,
"failures": 0,
"tls": null,
"tls-fingerprint": null,
"algo": "rx/0",
"diff": 123,
"accepted": 123,
"rejected": 123,
"avg_time": 123,
"avg_time_ms": 123,
"hashes_total": 123,
"error_log": []
},
"version": "6.18.0",
"kind": "miner",
"ua": "XMRig/6.18.0 (Linux x86_64) libuv/2.0.0-dev gcc/10.2.1",
"cpu": {
"brand": "blah blah blah",
"family": 1,
"model": 2,
"stepping": 0,
"proc_info": 123,
"aes": true,
"avx2": true,
"x64": true,
"64_bit": true,
"l2": 123123,
"l3": 123123,
"cores": 12,
"threads": 24,
"packages": 1,
"nodes": 1,
"backend": "hwloc/2.8.0a1-git",
"msr": "ryzen_19h",
"assembly": "ryzen",
"arch": "x86_64",
"flags": ["aes", "vaes", "avx", "avx2", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "sse4.1", "popcnt", "cat_l3"]
},
"donate_level": 0,
"paused": false,
"algorithms": ["cn/1", "cn/2", "cn/r", "cn/fast", "cn/half", "cn/xao", "cn/rto", "cn/rwz", "cn/zls", "cn/double", "cn/ccx", "cn-lite/1", "cn-heavy/0", "cn-heavy/tube", "cn-heavy/xhv", "cn-pico", "cn-pico/tlo", "cn/upx2", "rx/0", "rx/wow", "rx/arq", "rx/graft", "rx/sfx", "rx/keva", "argon2/chukwa", "argon2/chukwav2", "argon2/ninja", "astrobwt", "astrobwt/v2", "ghostrider"],
"hashrate": {
"total": [111.11, 111.11, 111.11],
"highest": 111.11,
"threads": [
[111.11, 111.11, 111.11]
]
},
"hugepages": true
}"#;
use crate::helper::PrivXmrigApi;
let priv_api = serde_json::from_str::<PrivXmrigApi>(&data).unwrap();
let json = serde_json::ser::to_string_pretty(&priv_api).unwrap();
println!("{}", json);
let data_after_ser =
r#"{
"worker_id": "hinto",
"resources": {
"load_average": [
10.97,
10.58,
10.47
]
},
"connection": {
"pool": "localhost:3333",
"diff": 123,
"accepted": 123,
"rejected": 123
},
"hashrate": {
"total": [
111.11,
111.11,
111.11
]
}
}"#;
assert_eq!(data_after_ser, json)
}
}

View file

@ -471,6 +471,7 @@ pub struct ErrorState {
msg: String, // What message to display?
ferris: ErrorFerris, // Which ferris to display?
buttons: ErrorButtons, // Which buttons to display?
quit_twice: bool, // This indicates the user tried to quit on the [ask_before_quit] screen
}
impl Default for ErrorState {
@ -486,6 +487,7 @@ impl ErrorState {
msg: "Unknown Error".to_string(),
ferris: ErrorFerris::Oops,
buttons: ErrorButtons::Okay,
quit_twice: false,
}
}
@ -506,6 +508,7 @@ impl ErrorState {
msg: msg.into(),
ferris,
buttons,
quit_twice: false,
};
}
@ -524,6 +527,7 @@ impl ErrorState {
msg: String::new(),
ferris: ErrorFerris::Sudo,
buttons: ErrorButtons::Sudo,
quit_twice: false,
};
SudoState::reset(state)
}
@ -914,14 +918,16 @@ fn main() {
impl eframe::App for App {
fn on_close_event(&mut self) -> bool {
// If we're already on the [ask_before_quit] screen and
// the user tries to exit again, exit.
if self.error_state.buttons == ErrorButtons::StayQuit {
if self.state.gupax.save_before_quit { self.save_before_quit(); }
true
// Else, set up the [ask_before_quit] screen (if enabled).
} else if self.state.gupax.ask_before_quit {
if self.state.gupax.ask_before_quit {
// If we're already on the [ask_before_quit] screen and
// the user tried to exit again, exit.
if self.error_state.quit_twice {
if self.state.gupax.save_before_quit { self.save_before_quit(); }
return true
}
// Else, set the error
self.error_state.set("", ErrorFerris::Oops, ErrorButtons::StayQuit);
self.error_state.quit_twice = true;
false
// Else, just quit.
} else {
@ -1553,3 +1559,23 @@ impl eframe::App for App {
});
}
}
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn build_app() {
let mut app = crate::App::new(std::time::Instant::now());
crate::init_auto(&mut app);
}
#[test]
fn build_regex() {
crate::Regexes::new();
}
#[test]
fn build_images() {
crate::Images::new();
}
}

View file

@ -58,6 +58,7 @@ pub const NODE_IPS: [&str; 17] = [
];
pub const COMMUNITY_NODE_LENGTH: usize = NODE_IPS.len();
pub const COMMUNITY_NODE_MAX_CHARS: usize = 14;
#[derive(Copy,Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
pub enum NodeEnum {
@ -65,7 +66,17 @@ pub enum NodeEnum {
Plowsof2,Rino,Feather1,Feather2,Seth,SupportXmr,SupportXmrIr,XmrVsBeast,
}
impl Default for NodeEnum {
fn default() -> Self {
Self::new()
}
}
impl NodeEnum {
fn new() -> Self {
ip_to_enum(NODE_IPS[0])
}
fn get_index(&self) -> usize {
match self {
C3pool => 0,
@ -280,7 +291,7 @@ impl Ping {
pub fn new() -> Self {
Self {
nodes: NodeData::new_vec(),
fastest: NodeEnum::C3pool,
fastest: NodeEnum::new(),
pinging: false,
msg: "No ping in progress".to_string(),
prog: 0.0,
@ -417,3 +428,23 @@ impl Ping {
node_vec.lock().unwrap().push(NodeData { id: ip_to_enum(ip), ip, ms, color, });
}
}
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn validate_node_ips() {
for ip in crate::NODE_IPS {
assert!(ip.len() < 255);
assert!(ip.is_ascii());
assert!(ip.ends_with(":18081") || ip.ends_with(":18089"));
}
}
#[test]
fn spacing() {
for ip in crate::NODE_IPS {
assert!(crate::format_enum(crate::ip_to_enum(ip)).len() == crate::COMMUNITY_NODE_MAX_CHARS);
}
}
}