Skip to content
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

Fix ListMetadata #112

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ https://www.eclipse.org/projects/handbook/#resources-commit

Contact the project developers via the project's "dev" list.

* https://dev.eclipse.org/mailman/listinfo/kuksa-dev
* https://accounts.eclipse.org/mailing-list/kuksa-dev

## Pre-commit set up
This repository is set up to use [pre-commit](https://pre-commit.com/) hooks.
Expand Down
127 changes: 82 additions & 45 deletions databroker/src/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,36 @@ pub struct Matcher {
impl Matcher {
pub fn new(glob_pattern: &str) -> Result<Self, MatchError> {
// Check if the pattern is valid
if is_valid_pattern(glob_pattern) {
// See https://github.com/eclipse-kuksa/kuksa-databroker/blob/main/doc/wildcard_matching.md
// for reference

// Empty string is ok, and by some reason also quoted empty string
// Must be replaced before checking if valid regexp
let glob_pattern_modified = if glob_pattern.eq("\"\"") || glob_pattern.is_empty() {
"**".to_string()
} else {
glob_pattern.to_string()
};

if is_valid_pattern(&glob_pattern_modified) {
Ok(Matcher {
glob_pattern: Matcher::to_glob_string(glob_pattern),
glob_pattern: Matcher::to_glob_string(&glob_pattern_modified),
})
} else {
Err(MatchError::MatchError)
}
}

pub fn is_match(&self, path: &str) -> bool {
glob_match(&self.glob_pattern, path)
let mut res: bool = glob_match(&self.glob_pattern, path);
// Special case - if we have something like A.B.C as input we want to both match
// the explicit signal A.B.C if existing but also
// sub-signals if A.B.C is a branch
if !res && self.glob_pattern.ends_with("/**") {
let new_pattern = self.glob_pattern.strip_suffix("/**").unwrap();
res = glob_match(new_pattern, path);
}
res
}

pub fn as_string(&self) -> String {
Expand All @@ -53,19 +72,10 @@ impl Matcher {
fn to_glob_string(glob: &str) -> String {
let mut glob_string = String::new();

if glob.eq("\"\"") || glob.is_empty() {
glob_string += "**";
return glob_string;
}

let mut glob_path_string = glob.replace('.', "/");

if !glob.contains('*') {
if glob.ends_with('.') {
glob_path_string += "/*";
} else if !glob.contains('.') {
glob_path_string += "/**";
}
glob_path_string += "/**";
}

glob_string.push_str(glob_path_string.as_str());
Expand Down Expand Up @@ -1266,7 +1276,6 @@ mod tests {
.should_match_signal("Vehicle.TraveledDistance"));
}

#[ignore]
#[test]
fn test_regex_single_subpath() {
assert!(using_glob("Vehicle").should_equal_regex_pattern("^Vehicle(?:\\..+)?$"));
Expand Down Expand Up @@ -1296,7 +1305,6 @@ mod tests {
.should_match_signals(ALL_SIGNALS));
}

#[ignore]
#[test]
fn test_regex_matches_multi_subpath() {
assert!(using_glob("Vehicle.Cabin.Sunroof")
Expand All @@ -1311,14 +1319,14 @@ mod tests {
}
#[test]
fn test_matches_multi_subpath() {
using_glob("Vehicle.Cabin.Sunroof")
assert!(using_glob("Vehicle.Cabin.Sunroof")
.with_signals(ALL_SIGNALS)
.should_match_signals(&[
"Vehicle.Cabin.Sunroof.Position",
"Vehicle.Cabin.Sunroof.Shade.Position",
"Vehicle.Cabin.Sunroof.Shade.Switch",
"Vehicle.Cabin.Sunroof.Switch",
]);
]));

// Make sure partial "last component" doesn't match
assert!(using_glob("Vehicle.Cabin.Sunroof")
Expand All @@ -1334,7 +1342,6 @@ mod tests {
.should_match_signal("Vehicle.Cabin.Sunroof.Shade.Position"));
}

#[ignore]
#[test]
fn test_regex_wildcard_at_end() {
assert!(using_glob("Vehicle.Cabin.Sunroof.*")
Expand All @@ -1351,7 +1358,6 @@ mod tests {
],));
}

#[ignore]
#[test]
fn test_regex_single_wildcard_in_middle() {
assert!(using_glob("Vehicle.Cabin.Sunroof.*.Position")
Expand Down Expand Up @@ -1425,7 +1431,6 @@ mod tests {
],));
}

#[ignore]
#[test]
fn test_regex_double_wildcard_at_beginning() {
assert!(using_glob("**.Sunroof").should_equal_regex_pattern(r"^.+\.Sunroof$"));
Expand All @@ -1442,7 +1447,6 @@ mod tests {
.should_match_no_signals());
}

#[ignore]
#[test]
fn test_regex_single_wildcard_at_the_beginning() {
assert!(using_glob("*.Sunroof").should_equal_regex_pattern(r"^[^.\s\:]+\.Sunroof$"));
Expand All @@ -1455,7 +1459,6 @@ mod tests {
.should_match_no_signals());
}

#[ignore]
#[test]
fn test_regex_single_non_matching_literal() {
assert!(using_glob("Sunroof").should_equal_regex_pattern(r"^Sunroof(?:\..+)?$"));
Expand Down Expand Up @@ -2540,16 +2543,33 @@ mod tests_glob_matching {
fn should_match_signals(&self, signals: &[&str]) -> bool {
let mut should_have_matched = Vec::new();
let mut should_not_have_matched = Vec::new();

// We cannot just check self.signals, then we miss the items in signals
// that is not part of self.signals

let mut matches = Vec::new();
for signal in self.signals {
if signals.contains(signal) {
if !self.glob.is_match(signal) {
should_have_matched.push(signal);
}
} else if self.glob.is_match(signal) {
if self.glob.is_match(signal) {
matches.push(signal);
}
}

// Now compare in two loops
for signal in &matches {
if !signals.contains(signal) {
should_not_have_matched.push(signal);
}
}

let mut i = 0;

while i < signals.len() {
if !matches.contains(&&signals[i]) {
should_have_matched.push(signals[i]);
}
i += 1
}

for signal in &should_have_matched {
println!(
"glob '{}' should have matched signal '{}' but didn't",
Expand Down Expand Up @@ -2678,7 +2698,6 @@ mod tests_glob_matching {
.should_match_signal("Vehicle/TraveledDistance"));
}

#[ignore]
#[test]
fn test_glob_single_subpath() {
assert!(using_glob_matching("Vehicle").should_equal_glob_string_pattern("Vehicle/**"));
Expand All @@ -2704,11 +2723,12 @@ mod tests_glob_matching {
.should_match_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS));
}

#[ignore]
#[test]
fn test_glob_matches_multi_subpath() {
// We append "/**"", but later compare also without if needed
// to cover the case that Vehicle.Cabin.Sunroof would be a signal
assert!(using_glob_matching("Vehicle.Cabin.Sunroof")
.should_equal_glob_string_pattern(r"Vehicle/Cabin/Sunroof",));
.should_equal_glob_string_pattern(r"Vehicle/Cabin/Sunroof/**",));
}

#[test]
Expand All @@ -2719,18 +2739,28 @@ mod tests_glob_matching {
}
#[test]
fn test_matches_multi_subpath() {
using_glob_matching("Vehicle.Cabin.Sunroof")
// Note .** should give same result as without
assert!(using_glob_matching("Vehicle.Cabin.Sunroof.**")
.with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS)
.should_match_signals(&[
"Vehicle.Cabin.Sunroof.Position",
"Vehicle.Cabin.Sunroof.Shade.Position",
"Vehicle.Cabin.Sunroof.Shade.Switch",
"Vehicle.Cabin.Sunroof.Switch",
]);
"Vehicle/Cabin/Sunroof/Position",
"Vehicle/Cabin/Sunroof/Shade/Position",
"Vehicle/Cabin/Sunroof/Shade/Switch",
"Vehicle/Cabin/Sunroof/Switch",
]));

assert!(using_glob_matching("Vehicle.Cabin.Sunroof")
.with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS)
.should_match_signals(&[
"Vehicle/Cabin/Sunroof/Position",
"Vehicle/Cabin/Sunroof/Shade/Position",
"Vehicle/Cabin/Sunroof/Shade/Switch",
"Vehicle/Cabin/Sunroof/Switch",
]));

// Make sure partial "last component" doesn't match
assert!(using_glob_matching("Vehicle.Cabin.Sunroof")
.with_signals(&["Vehicle.Cabin.SunroofThing"])
.with_signals(&["Vehicle/Cabin/SunroofThing"])
.should_match_no_signals());
}

Expand All @@ -2742,7 +2772,6 @@ mod tests_glob_matching {
.should_match_signal("Vehicle/Cabin/Sunroof/Shade/Position"));
}

#[ignore]
#[test]
fn test_glob_wildcard_at_end() {
assert!(using_glob_matching("Vehicle.Cabin.Sunroof.*")
Expand All @@ -2759,7 +2788,6 @@ mod tests_glob_matching {
],));
}

#[ignore]
#[test]
fn test_glob_single_wildcard_in_middle() {
assert!(using_glob_matching("Vehicle.Cabin.Sunroof.*.Position")
Expand All @@ -2783,11 +2811,17 @@ mod tests_glob_matching {
.should_match_signals(&["Vehicle/Cabin/Sunroof/Shade/Position"]));
}

#[ignore]
#[ignore] // Ignored due to comment below
#[test]
fn test_matches_combination_of_multiple_wildcard_and_single_wildcard() {
/*
This is the only case that can not be supported by the new glob match lib used.
Known problem, see e.g.
https://github.com/devongovett/glob-match/issues/8
https://github.com/devongovett/glob-match/issues/9
https://github.com/devongovett/glob-match/pull/18
But repo seems to be abandoned!
*/
assert!(using_glob_matching("**.*.*.*.Position")
.with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS)
Expand Down Expand Up @@ -2837,7 +2871,6 @@ mod tests_glob_matching {
],));
}

#[ignore]
#[test]
fn test_glob_double_wildcard_at_beginning() {
assert!(using_glob_matching("**.Sunroof").should_equal_glob_string_pattern(r"**/Sunroof"));
Expand All @@ -2854,7 +2887,6 @@ mod tests_glob_matching {
.should_match_no_signals());
}

#[ignore]
#[test]
fn test_glob_single_wildcard_at_the_beginning() {
assert!(using_glob_matching("*.Sunroof").should_equal_glob_string_pattern(r"*/Sunroof"));
Expand All @@ -2867,10 +2899,10 @@ mod tests_glob_matching {
.should_match_no_signals());
}

#[ignore]
#[test]
fn test_glob_single_non_matching_literal() {
assert!(using_glob_matching("Sunroof").should_equal_glob_string_pattern(r"Sunroof"));
// Single word without dash should result in everything below, thats why /** is expected
assert!(using_glob_matching("Sunroof").should_equal_glob_string_pattern(r"Sunroof/**"));
}

#[test]
Expand All @@ -2893,6 +2925,7 @@ mod tests_glob_matching {

#[test]
fn test_valid_glob_path() {
assert_eq!(Matcher::to_glob_string("String"), "String/**");
assert_eq!(Matcher::to_glob_string("String.*"), "String/*");
assert_eq!(Matcher::to_glob_string("String.**"), "String/**");
assert_eq!(
Expand All @@ -2905,7 +2938,7 @@ mod tests_glob_matching {
);
assert_eq!(
Matcher::to_glob_string("String.String.String.String"),
"String/String/String/String"
"String/String/String/String/**"
);
assert_eq!(
Matcher::to_glob_string("String.String.String.String.String.**"),
Expand Down Expand Up @@ -2949,6 +2982,10 @@ mod tests_glob_matching {
);
assert_eq!(Matcher::to_glob_string("**.String"), "**/String");
assert_eq!(Matcher::to_glob_string("*.String"), "*/String");
assert_eq!(
Matcher::to_glob_string("**.*.*.*.String"),
"**/*/*/*/String"
);
assert_eq!(
Matcher::to_glob_string("*.String.String.String"),
"*/String/String/String"
Expand Down
1 change: 1 addition & 0 deletions databroker/src/grpc/kuksa_val_v2/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ impl From<&broker::Metadata> for proto::Metadata {
fn from(metadata: &broker::Metadata) -> Self {
proto::Metadata {
id: metadata.id,
path: metadata.path.clone(),
data_type: proto::DataType::from(metadata.data_type.clone()) as i32,
entry_type: proto::EntryType::from(metadata.entry_type.clone()) as i32,
description: metadata.description.clone(),
Expand Down
Loading
Loading