-
Notifications
You must be signed in to change notification settings - Fork 9
Debug server file watching issues #130
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
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ pub struct ServerConfig { | |
| pub config_path: Option<String>, | ||
| pub plugins: Vec<Arc<dyn CustomHook>>, | ||
| pub header: String, | ||
| pub chaos_monkey: Option<Arc<dyn Fn() + Send + Sync>>, | ||
| } | ||
|
|
||
| impl ServerConfig { | ||
|
|
@@ -39,6 +40,7 @@ impl ServerConfig { | |
| config_path: None, | ||
| plugins: Vec::new(), | ||
| header: String::new(), | ||
| chaos_monkey: None, | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -443,8 +445,126 @@ fn run_analysis( | |
| previous_scan_data, | ||
| previous_analysis_result, | ||
| changes, | ||
| || {}, | ||
| || { | ||
| if let Some(f) = &config.chaos_monkey { | ||
| f(); | ||
| } | ||
| }, | ||
| Some(progress), | ||
| ) | ||
| .map_err(|e| e.to_string()) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use hakana_logger::Logger; | ||
| use hakana_protocol::{ClientSocket, GetIssuesRequest, Message}; | ||
| use std::{ | ||
| path::{Path, PathBuf}, | ||
| sync::{Arc, atomic::AtomicBool}, | ||
| }; | ||
| use tokio::fs; | ||
|
|
||
| use crate::{Server, ServerConfig, watchman}; | ||
|
|
||
| #[tokio::test] | ||
| async fn handles_file_changes_during_analysis() -> std::io::Result<()> { | ||
| let tmp = tempfile::Builder::new() | ||
| .prefix("hakana-test") | ||
| .tempdir() | ||
| .expect("failed to create temp dir"); | ||
| let hack_file = tmp.path().join("index.hack"); | ||
| let config_path = tmp.path().join("hakana.json"); | ||
| fs::write(hack_file.clone(), "function main(): void {}") | ||
| .await | ||
| .expect("failed to create test file"); | ||
| fs::write(config_path.clone(), "{}") | ||
| .await | ||
| .expect("failed to create test file"); | ||
|
|
||
| eprintln!("{:?}", hack_file); | ||
|
|
||
| let did_mutate = AtomicBool::new(false); | ||
|
|
||
| let server_config = ServerConfig { | ||
| root_dir: tmp.path().to_str().unwrap().to_string(), | ||
| threads: 2, | ||
| config_path: Some(config_path.to_str().unwrap().to_string()), | ||
| plugins: vec![], | ||
| header: "".to_string(), | ||
| chaos_monkey: Some(Arc::new(move || { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice |
||
| // Simulate a file change between the first scan and first analysis | ||
| if !did_mutate.load(std::sync::atomic::Ordering::Relaxed) { | ||
| eprintln!("editing file before analysis"); | ||
| did_mutate.store(true, std::sync::atomic::Ordering::Relaxed); | ||
| std::fs::write(hack_file.clone(), "function foo(): void {}") | ||
| .expect("failed to mutate file before analysis"); | ||
| } | ||
| })), | ||
| }; | ||
|
|
||
| let watchman_clock = watchman::get_clock(Path::new(&server_config.root_dir)).await?; | ||
| let mut watchman_handle = watchman::start_subscription( | ||
| PathBuf::from(&server_config.root_dir), | ||
| vec![], | ||
| watchman_clock, | ||
| server_config.config_path.as_ref().map(&PathBuf::from), | ||
| ); | ||
|
|
||
| let mut server = Server::new( | ||
| server_config, | ||
| Arc::new(Logger::CommandLine(hakana_logger::Verbosity::Debugging)), | ||
| ) | ||
| .expect("failed to create server"); | ||
|
|
||
| let socket_path = server.socket_path().clone(); | ||
| let shutdown_tx = server.shutdown_tx.clone(); | ||
|
|
||
| let server_task = | ||
| tokio::spawn(async move { server.run().await.expect("failed to run server") }); | ||
|
|
||
| // Wait for Watchman to send a notification (which should also have notified the server) | ||
| watchman_handle.recv().await; | ||
|
|
||
| let mut client = ClientSocket::connect(&socket_path) | ||
| .await | ||
| .expect("failed to connect"); | ||
|
|
||
| let request = Message::GetIssues(GetIssuesRequest { | ||
| filter: None, | ||
| find_unused_expressions: false, | ||
| find_unused_definitions: false, | ||
| block_until_next_analysis: false, | ||
| send_progress_report: false, | ||
| }); | ||
|
|
||
| let response = client | ||
| .request(&request) | ||
| .await | ||
| .expect("Failed to send request"); | ||
|
|
||
| if let Message::GetIssuesResult(result) = response { | ||
| eprintln!("{:?}", result.issues); | ||
| assert!( | ||
| result.analysis_complete, | ||
| "Analysis should be complete after server is ready" | ||
| ); | ||
| assert_eq!(0, result.issues.len(), "there should be no issues reported"); | ||
| assert_eq!( | ||
| 1, result.files_analyzed, | ||
| "one file should have been analyzed" | ||
| ) | ||
| } else { | ||
| panic!("Expected GetIssuesResult, got {:?}", response); | ||
| } | ||
|
|
||
| shutdown_tx | ||
| .send(true) | ||
| .await | ||
| .expect("failed to shutdown server"); | ||
|
|
||
| server_task.await.expect("failed to join server task"); | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I have the only prepackaged watchman for Noble...