-
Notifications
You must be signed in to change notification settings - Fork 0
nginx test #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
nginx test #62
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @dentiny, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
The primary goal of this pull request is to introduce a comprehensive standalone test for the moonlink_service. This test suite validates the service's ability to interact with an Nginx data server, manage table schemas, ingest data, and perform data scans. It ensures the core functionalities of the moonlink_service are working as expected in an integrated environment.
Highlights
- New Standalone Test Suite: A new test file
src/moonlink_service/src/test.rshas been added, containingtest_moonlink_standaloneand associated helper functions. This test simulates a full workflow including service startup, table creation, data ingestion via REST API, and data scanning via RPC, interacting with a mock Nginx server. - Dependency Updates:
Cargo.lockandsrc/moonlink_service/Cargo.tomlhave been updated to include new development dependencies such asreqwest,arrow,parquet,bytes, andtempfile, which are essential for the new testing infrastructure. - Test Utility Export: A new utility function,
decode_serialized_read_state_for_testing, has been exposed in themoonlinkcrate to facilitate the deserialization of read state data for testing purposes. - Service Configuration Enhancements: The
ServiceConfigstruct inmoonlink_servicenow derivesDebugfor easier debugging, and theREADINESS_PROBE_PORTconstant's visibility has been adjusted topub(crate)to allow access within the crate's test modules.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces tests for the moonlink service, including an integration test that uses nginx. The changes are a good step towards ensuring the service's reliability. However, there are several areas that need improvement.
I've found some leftover debugging println! statements that should be removed. More importantly, the main test function test_moonlink_standalone is currently broken because a helper function read_all_batches is incomplete. I've provided a suggestion to fix it.
Additionally, I've made some suggestions to make the tests more robust, such as using tempfile for temporary directories and improving error handling in test helper functions.
| pub async fn read_all_batches(url: &str) -> Vec<RecordBatch> { | ||
| let resp = reqwest::get(url).await.unwrap(); | ||
| println!("status = {}", resp.status()); | ||
|
|
||
| assert!(resp.status().is_success()); | ||
|
|
||
| println!("content = {}", resp.text().await.unwrap()); | ||
|
|
||
| vec![] | ||
|
|
||
| // let data: Bytes = resp.bytes().await.unwrap(); | ||
| // println!("read len = {}", data.len()); | ||
| // let mut reader = ParquetRecordBatchReaderBuilder::try_new(data).unwrap() | ||
| // .build().unwrap(); | ||
|
|
||
| // // Collect all record batches | ||
| // let batches = reader | ||
| // .into_iter() | ||
| // .map(|b| b.unwrap()) // handle Err properly in production | ||
| // .collect(); | ||
|
|
||
| // batches | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is incomplete and returns an empty vector, which causes test_moonlink_standalone to fail. The intended implementation appears to be commented out. The println! statements should also be removed, and unwrap() calls should be replaced with expect() to provide more context on failure.
pub async fn read_all_batches(url: &str) -> Vec<RecordBatch> {
let resp = reqwest::get(url)
.await
.unwrap_or_else(|e| panic!("Failed to GET from url: {}: {}", url, e));
assert!(resp.status().is_success(), "Request to {} failed with status {}", url, resp.status());
let data: Bytes = resp.bytes().await.expect("Failed to read response bytes");
let reader = ParquetRecordBatchReaderBuilder::try_new(data)
.expect("Failed to create parquet reader builder")
.build()
.expect("Failed to build parquet reader");
// Collect all record batches
reader
.map(|b| b.expect("Failed to read record batch"))
.collect()
}|
|
||
| println!("data files = {:?}", data_files); | ||
|
|
||
| let remapped_data_files = data_files | ||
| .into_iter() | ||
| .map(|path| read_state_filepath_remap(path)) | ||
| .collect::<Vec<_>>(); | ||
|
|
||
| println!("remapped data files = {:?}", remapped_data_files); | ||
|
|
||
| let remapped_puffin_files = puffin_files | ||
| .into_iter() | ||
| .map(|path| read_state_filepath_remap(path)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These println! statements appear to be for debugging purposes and should be removed before merging.
| println!("data files = {:?}", data_files); | |
| let remapped_data_files = data_files | |
| .into_iter() | |
| .map(|path| read_state_filepath_remap(path)) | |
| .collect::<Vec<_>>(); | |
| println!("remapped data files = {:?}", remapped_data_files); | |
| let remapped_puffin_files = puffin_files | |
| .into_iter() | |
| .map(|path| read_state_filepath_remap(path)) | |
| // Map from local filepath to remote file path if needed and if possible. | |
| let remapped_data_files = data_files | |
| .into_iter() | |
| .map(|path| read_state_filepath_remap(path)) | |
| .collect::<Vec<_>>(); | |
| let remapped_puffin_files = puffin_files | |
| .into_iter() | |
| .map(|path| read_state_filepath_remap(path)) |
|
|
||
| println!("start with config = {:?}", config); | ||
|
|
||
| println!("sqlite metadata store = {}", config.base_path); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| recreate_directory(MOONLINK_BACKEND_DIR); | ||
| let config = ServiceConfig { | ||
| base_path: MOONLINK_BACKEND_DIR.to_string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using a hardcoded directory and a manual cleanup function, it's better to use tempfile::TempDir for creating a temporary directory for the test. This avoids hardcoded paths, potential conflicts, and ensures the directory is cleaned up automatically. Please also remove the MOONLINK_BACKEND_DIR constant and the recreate_directory function.
| recreate_directory(MOONLINK_BACKEND_DIR); | |
| let config = ServiceConfig { | |
| base_path: MOONLINK_BACKEND_DIR.to_string(), | |
| let temp_dir = TempDir::new().expect("Failed to create temp dir"); | |
| let config = ServiceConfig { | |
| base_path: temp_dir.path().to_str().expect("temp dir path is not valid utf8").to_string(), |
| async fn test_readiness_probe() { | ||
| let url = format!("http://127.0.0.1:{}/ready", READINESS_PROBE_PORT); | ||
| loop { | ||
| if let Ok(resp) = reqwest::get(&url).await { | ||
| if resp.status() == reqwest::StatusCode::OK { | ||
| return; | ||
| } | ||
| } | ||
| tokio::time::sleep(std::time::Duration::from_millis(100)).await; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This readiness probe loop can run indefinitely and will silently ignore connection errors, making test failures hard to debug. It's better to have a timeout and to panic with a clear error message if the service doesn't become ready within a reasonable time.
| async fn test_readiness_probe() { | |
| let url = format!("http://127.0.0.1:{}/ready", READINESS_PROBE_PORT); | |
| loop { | |
| if let Ok(resp) = reqwest::get(&url).await { | |
| if resp.status() == reqwest::StatusCode::OK { | |
| return; | |
| } | |
| } | |
| tokio::time::sleep(std::time::Duration::from_millis(100)).await; | |
| } | |
| } | |
| async fn test_readiness_probe() { | |
| let url = format!("http://127.0.0.1:{}/ready", READINESS_PROBE_PORT); | |
| for _ in 0..30 { // ~3 seconds timeout | |
| if let Ok(resp) = reqwest::get(&url).await { | |
| if resp.status() == reqwest::StatusCode::OK { | |
| return; | |
| } | |
| } | |
| tokio::time::sleep(std::time::Duration::from_millis(100)).await; | |
| } | |
| panic!("Readiness probe failed to respond after 3 seconds."); | |
| } |
a090111 to
f5f51d2
Compare
Summary
Briefly explain what this PR does.
Related Issues
Closes # or links to related issues.
Changes
Checklist