mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 22:59:27 +00:00
Add #[test]s, fix [State::merge()], fix [quit_twice]
This commit is contained in:
parent
95fffac3cd
commit
e35f5b243b
6 changed files with 627 additions and 116 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
421
src/disk.rs
421
src/disk.rs
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
176
src/helper.rs
176
src/helper.rs
|
@ -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, ®ex);
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
33
src/node.rs
33
src/node.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue