-
Notifications
You must be signed in to change notification settings - Fork 17
[BUG] Scenario Parsing Error in Nodeagent(reciever.rs) #114
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
youngtaekiim
merged 2 commits into
eclipse-pullpiri:refactoring
from
seunghwan-bang:refactoring
Jul 10, 2025
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,112 +23,33 @@ use common::spec::{ | |
| /// Convert `Model` to `Pod` | ||
| /// Make `.kube`, `.yaml` files for bluechi | ||
| /// Copy files to the guest node running Bluechi | ||
| pub async fn parse(package_str: String) -> common::Result<()> { | ||
| pub async fn parse(yaml_str: String, nodename: String) -> common::Result<()> { | ||
| let (package_str, models_str) = parser::yaml_split(&yaml_str).await?; | ||
| let package: Package = serde_yaml::from_str(&package_str)?; | ||
|
|
||
| let models: Vec<Model> = parser::get_complete_model(package).await?; | ||
| let models: Vec<Model> = | ||
| parser::get_complete_model(package, nodename.clone(), models_str).await?; | ||
| let pods: Vec<Pod> = models.into_iter().map(Pod::from).collect(); | ||
|
|
||
| let file_names = filemaker::make_files_from_pod(pods).await?; | ||
| filemaker::copy_to_remote_node(file_names)?; | ||
| let _ = filemaker::make_files_from_pod(pods, nodename).await?; | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
|
Contributor
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. do not remove test codes |
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use tokio; | ||
|
|
||
| // Valid YAML string for testing a Package artifact | ||
| fn valid_package_yaml() -> String { | ||
| r#" | ||
| apiVersion: v1 | ||
| kind: Package | ||
| metadata: | ||
| label: null | ||
| name: helloworld | ||
| spec: | ||
| pattern: | ||
| - type: plain | ||
| models: | ||
| - name: helloworld-core | ||
| node: HPC | ||
| resources: | ||
| volume: | ||
| network: | ||
| "# | ||
| .to_string() | ||
| } | ||
| // filemaker::delete_symlink_and_reload(&mi.get_name(), &model_node) | ||
| // .await | ||
| // .map_err(|e| { | ||
| // format!("Failed to delete symlink for '{}': {}", mi.get_name(), e) | ||
| // })?; | ||
|
|
||
| // Test case for parsing a valid package YAML | ||
| #[tokio::test] | ||
| async fn test_parse_success() { | ||
| let yaml_str = valid_package_yaml(); | ||
| let result = parse(yaml_str).await; | ||
| assert!(result.is_ok() || result.err().is_some()); | ||
| } | ||
| // make_symlink_and_reload( | ||
| // &model_node, | ||
| // &mi.get_name(), | ||
| // &scenario.get_targets(), | ||
| // ) | ||
| // .await | ||
| // .map_err(|e| { | ||
| // format!("Failed to create symlink for '{}': {}", mi.get_name(), e) | ||
| // })?; | ||
|
|
||
| // Test case for parsing an invalid package YAML (syntax error) | ||
| #[tokio::test] | ||
| async fn test_parse_invalid_yaml_syntax() { | ||
| let invalid_yaml = "invalid: ::: yaml"; | ||
| let result = parse(invalid_yaml.to_string()).await; | ||
| assert!(result.is_err(), "parse() unexpectedly succeeded"); | ||
| } | ||
| //filemaker::copy_to_remote_node(file_names)?; | ||
|
|
||
| // Test case for parsing a package YAML with missing fields (Missing model) | ||
| #[tokio::test] | ||
| async fn test_parse_missing_model_field() { | ||
| let invalid_yaml = r#" | ||
| apiVersion: v1 | ||
| kind: Package | ||
| metadata: | ||
| name: helloworld | ||
| spec: | ||
| pattern: | ||
| - type: plain | ||
| "#; | ||
| let result = parse(invalid_yaml.to_string()).await; | ||
| assert!( | ||
| result.is_err(), | ||
| "parse() unexpectedly succeeded with missing model field" | ||
| ); | ||
| } | ||
|
|
||
| // Test case for parsing a package YAML with invalid type in resources (e.g., invalid volume type) | ||
| #[tokio::test] | ||
| async fn test_parse_invalid_field_type_in_resources() { | ||
| let invalid_yaml = r#" | ||
| apiVersion: v1 | ||
| kind: Package | ||
| metadata: | ||
| name: helloworld | ||
| spec: | ||
| pattern: | ||
| - type: plain | ||
| models: | ||
| - name: helloworld-core | ||
| node: HPC | ||
| resources: | ||
| volume: 12345 # Invalid type (should be a string, not an integer) | ||
| network: vd-network | ||
| "#; | ||
| let result = parse(invalid_yaml.to_string()).await; | ||
| assert!( | ||
| result.is_err(), | ||
| "parse() unexpectedly succeeded with invalid field type in resources" | ||
| ); | ||
| } | ||
|
|
||
| // Test case for parsing an empty YAML string | ||
| #[tokio::test] | ||
| async fn test_parse_empty_yaml() { | ||
| let empty_yaml = "".to_string(); | ||
| let result = parse(empty_yaml).await; | ||
| assert!( | ||
| result.is_err(), | ||
| "parse() unexpectedly succeeded with empty YAML string" | ||
| ); | ||
| } | ||
| Ok(()) | ||
| } | ||
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 |
|---|---|---|
|
|
@@ -5,7 +5,54 @@ | |
|
|
||
| //! Create Model artifact from given Package information | ||
|
|
||
| use common::spec::artifact::{Model, Network, Package, Volume}; | ||
| use common::spec::artifact::{Artifact, Model, Network, Package, Scenario, Volume}; | ||
|
|
||
| pub async fn yaml_split(body: &str) -> common::Result<(String, Vec<Model>)> { | ||
| let docs: Vec<&str> = body.split("---").collect(); | ||
| let mut scenario_str = String::new(); | ||
| let mut package_str = String::new(); | ||
| let mut models: Vec<Model> = Vec::new(); | ||
| //let mut network_str = String::new(); | ||
|
|
||
| for doc in docs { | ||
| let value: serde_yaml::Value = serde_yaml::from_str(doc)?; | ||
| let artifact_str = serde_yaml::to_string(&value)?; | ||
|
|
||
| if let Some(kind) = value.clone().get("kind").and_then(|k| k.as_str()) { | ||
| let name: String = match kind { | ||
| "Scenario" => serde_yaml::from_value::<Scenario>(value.clone())?.get_name(), | ||
| "Package" => serde_yaml::from_value::<Package>(value.clone())?.get_name(), | ||
| "Volume" => serde_yaml::from_value::<Volume>(value.clone())?.get_name(), | ||
| "Network" => serde_yaml::from_value::<Network>(value.clone())?.get_name(), | ||
| "Model" => serde_yaml::from_value::<Model>(value.clone())?.get_name(), | ||
| _ => { | ||
| println!("unknown artifact"); | ||
| continue; | ||
| } | ||
| }; | ||
|
|
||
| match kind { | ||
| "Scenario" => scenario_str = artifact_str, | ||
| "Package" => package_str = artifact_str, | ||
| "Model" => { | ||
| let model = serde_yaml::from_value::<Model>(value)?; | ||
| models.push(model); | ||
| } | ||
| //"Network" => network_str = artifact_str, | ||
| _ => continue, | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| if scenario_str.is_empty() { | ||
| Err("There is not any scenario in yaml string".into()) | ||
| } else if package_str.is_empty() { | ||
| //Missing Check is Added for Package | ||
| Err("There is not any package in yaml string".into()) | ||
| } else { | ||
| Ok((package_str, models)) //, network_str)) | ||
| } | ||
| } | ||
|
|
||
| /// Get combined `Network`, `Volume`, parsed `Model` information | ||
| /// | ||
|
|
@@ -14,41 +61,56 @@ use common::spec::artifact::{Model, Network, Package, Volume}; | |
| /// ### Description | ||
| /// Get base `Model` information from package spec | ||
| /// Combine `Network`, `Volume`, parsed `Model` information | ||
| pub async fn get_complete_model(p: Package) -> common::Result<Vec<Model>> { | ||
| let mut models: Vec<Model> = Vec::new(); | ||
|
|
||
| pub async fn get_complete_model( | ||
| p: Package, | ||
| node: String, | ||
| models: Vec<Model>, | ||
| ) -> common::Result<Vec<Model>> { | ||
| let mut base_models: Vec<Model> = Vec::new(); | ||
| let mut model_name: String = String::new(); | ||
| for mi in p.get_models() { | ||
| let mut key = format!("Model/{}", mi.get_name()); | ||
| let base_model_str = common::etcd::get(&key).await?; | ||
| let model: Model = serde_yaml::from_str(&base_model_str)?; | ||
|
|
||
| if let Some(volume_name) = mi.get_resources().get_volume() { | ||
| key = format!("Volume/{}", volume_name); | ||
| let volume_str = common::etcd::get(&key).await?; | ||
| let volume: Volume = serde_yaml::from_str(&volume_str)?; | ||
|
|
||
| if let Some(volume_spec) = volume.get_spec() { | ||
| model | ||
| .get_podspec() | ||
| .volumes | ||
| .clone_from(volume_spec.get_volume()); | ||
| if mi.get_node() == node { | ||
| model_name = mi.get_name(); | ||
| for model in models.iter() { | ||
| if model.get_name() == model_name { | ||
| base_models.push(model.clone()); | ||
| } else { | ||
| println!("Model {} is not for this node {}", model.get_name(), node); | ||
| continue; | ||
| } | ||
| } | ||
| } else { | ||
| println!("Model {} is not for this node {}", mi.get_name(), node); | ||
| continue; | ||
| } | ||
| //let mut key = format!("Model/{}", mi.get_name()); | ||
| //let base_model_str = common::etcd::get(&key).await?; | ||
| //let model: Model = serde_yaml::from_str(&base_model_str)?; | ||
|
|
||
| if let Some(network_name) = mi.get_resources().get_network() { | ||
| key = format!("Network/{}", network_name); | ||
| let network_str = common::etcd::get(&key).await?; | ||
| let network: Network = serde_yaml::from_str(&network_str)?; | ||
| // if let Some(volume_name) = mi.get_resources().get_volume() { | ||
| // key = format!("Volume/{}", volume_name); | ||
| // let volume_str: String = common::etcd::get(&key).await?; | ||
| // let volume: Volume = serde_yaml::from_str(&volume_str)?; | ||
|
|
||
| if let Some(network_spec) = network.get_spec() { | ||
| // TODO | ||
| } | ||
| } | ||
| // if let Some(volume_spec) = volume.get_spec() { | ||
| // model | ||
| // .get_podspec() | ||
| // .volumes | ||
| // .clone_from(volume_spec.get_volume()); | ||
| // } | ||
| // } | ||
|
|
||
| models.push(model); | ||
| } | ||
| // if let Some(network_name) = mi.get_resources().get_network() { | ||
| // key = format!("Network/{}", network_name); | ||
| // let network_str = common::etcd::get(&key).await?; | ||
| // let network: Network = serde_yaml::from_str(&network_str)?; | ||
|
|
||
| Ok(models) | ||
| // if let Some(network_spec) = network.get_spec() { | ||
| // // TODO | ||
| // } | ||
| //} | ||
| } | ||
| Ok(base_models) | ||
| } | ||
|
|
||
|
Contributor
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. do not remove test codes |
||
| //UNIT TEST CASES | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
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.
discard change of this file (helloworld.yaml)