Skip to content

Conversation

@nikkita1267
Copy link

This pull request implements the GetPlatformInfo action, closes #6.

I left libc_ver and install_date fields blank because function Uname.FromCurrentSystem (link) doesn't fill them. I also add libc crate which provides uname system call.

All fields, except libc_ver and install_date, are currently filled for Linux.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@nikkita1267
Copy link
Author

@googlebot I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

Comment on lines 6 to 9
extern crate sys_info;

/// Using for `uname` syscall.
extern crate libc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need these declarations?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need now, I removed them.

CannotGetOSType(ref error) => {
write!(fmt, "can't get OS type error: {}", error)
},

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excessive blank line.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Cargo.toml Outdated
@@ -15,3 +15,4 @@ rrg-proto = { path = "proto/" }
simplelog = { version = "0.7.6" }
structopt = { version = "0.3.12" }
sys-info = { version = "0.5.1" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recently, I have made a change to use the sysinfo crate rather than sys-info. sys-info does not seem to work on other operating systems and is more low-level, whereas sysinfo gives you more abstractions and works on pretty much all supported platforms and saves us from having a lot of unsafe calls. Have you considered using it?

Right now, the code will not compile on Windows and macOS, I believe.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to find something useful for my action in crate sysinfo, but, seems to me, this package doesn't provide any information about OS, only about system at all.
Also as documentation of sys-info says that it supports Windows and Mac OS too.

/// A Response type for `GetPlatformInfo` action
pub struct Response {
/// Client platform information
platform_information: PlatformInfo,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to have separate types PlatformInfo and Response (that is specific to an action called GetPlatformInfo)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason, now fixed:)

}

/// Funcion that converts raw C-strings into `String` type
#[inline(always)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for forcing inlinining over letting the compiler decide (or a slightly less "demanding" variant: just #[inline])?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that it would be nice if the conversion code was inlined, but probably this solution should be left to the compiler. Thanks!

Comment on lines 62 to 69
system: Option<String>,
release_name: Option<String>,
version_id: Option<String>,
machine: Option<String>,
kernel_release: Option<String>,
fqdn: Option<String>,
architecture: Option<String>,
node: Option<String>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like a lot of these variants would benefit from having a dedicated enum rather than using raw strings for everything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand, what do you mean by dedicated enum?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, for system you could have an enum with Linux, Windows etc. But this might not be ideal solution as it might break on some awkward platforms (that we don't really support, but who knows). On the other hand, passing through library-dependent values is not great either as we bind semantics of our protocol to some third-party internal details. In the end, I think it is fine to leave it as it is, I might look into that in the future.

//! instance of the corresponding request type and send some (zero or more)
//! instances of the corresponding response type.

pub mod platform_info;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just platform.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work, because my file is named platform_info.rs and if I change platform_info to platform I get compilation error. Or, maybe, I don't understand you correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, you should rename the module (both the file and this line) to be just platform.

Comment on lines 7 to 9
#[cfg(target_os = "linux")]
use libc::{uname, utsname};
use libc::c_char;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to put platform-specific imports locally next to the places that actually need them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks! Fixed.

Comment on lines 135 to 136
system: self.system.clone(),
release: self.release_name.clone(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to clone? into_proto takes an owned response.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to clone, because pep425tag also try to move these fields.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? You are just stringifying them, borrowing them should be enough. You probably need to refactor it to a separate variable.

machine: self.machine,
kernel: self.kernel_release,
fqdn: self.fqdn,
architecture: self.architecture.clone(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Comment on lines 143 to 148
pep425tag: Some(
format!("{}_{}_{}",
self.system.unwrap_or(String::from("")),
self.release_name.unwrap_or(String::from("")),
self.architecture.unwrap_or(String::from(""))
)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any of these values is None you could end up with something like foo__bar or _foo_. Is this expected?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to fill this field by analogy with the Python code, but forgot that None converts to 'None' in Python. Thanks!

}

#[cfg(test)]
mod test {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests mostly re-implement the implementation, which makes them quite useless (or even dangerous). In most cases, its of course impossible to write proper tests, so I think it is just better to assert that the values are non-empty.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, understand, thanks!

//! instance of the corresponding request type and send some (zero or more)
//! instances of the corresponding response type.

pub mod platform_info;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, you should rename the module (both the file and this line) to be just platform.

Comment on lines 135 to 136
system: self.system.clone(),
release: self.release_name.clone(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? You are just stringifying them, borrowing them should be enough. You probably need to refactor it to a separate variable.

Comment on lines 161 to 169
fn test_system() {
let mut session = session::test::Fake::new();
assert!(handle(&mut session, ()).is_ok());

assert_eq!(session.reply_count(), 1);
let platform_info = &session.reply::<Response>(0);

assert!(platform_info.system.is_some());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this test you could actually have platform-specific test cases for every supported platform (through #[cfg_attr(..., ignore)]) that actually test this field for some specific values (e.g. "Linux").

Comment on lines 62 to 69
system: Option<String>,
release_name: Option<String>,
version_id: Option<String>,
machine: Option<String>,
kernel_release: Option<String>,
fqdn: Option<String>,
architecture: Option<String>,
node: Option<String>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, for system you could have an enum with Linux, Windows etc. But this might not be ideal solution as it might break on some awkward platforms (that we don't really support, but who knows). On the other hand, passing through library-dependent values is not great either as we bind semantics of our protocol to some third-party internal details. In the end, I think it is fine to leave it as it is, I might look into that in the future.

}
}

/// A Response type for `GetPlatformInfo` action
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Response" should not be uppercase here, there should be a dot at the end of the comment.

Comment on lines 59 to 60
/// Client platform information
system: Option<String>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This documentation item looks like something that applies to the whole struct, not only to the system field.

Comment on lines 112 to 114
"Linux" => {
get_linux_response(session, os_type)?;
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good candidate for conditional compilation rather than some run-time behaviour that depends on what the third-party library decides to return.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement the GetPlatformInfo action

3 participants