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

[projmgr] Update connections validation rules #1091

Merged
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: 0 additions & 2 deletions test/packs/ARM/RteTest_DFP/0.2.0/Layers/board1.clayer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ layer:

connections:
- connect: Board1 Connections
provides:
- MultipleProvided # same connection is provided multiple times with identical values
consumes:
- ExactMatch: 42 # both key and value exact match
- EmptyConsumedValue # key exact match, consumed value is empty
Expand Down
2 changes: 0 additions & 2 deletions test/packs/ARM/RteTest_DFP/0.2.0/Layers/board2.clayer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ layer:

connections:
- connect: Board2 Connections
provides:
- MultipleProvided # same connection is provided multiple times with identical values
consumes:
- ExactMatch: 42 # both key and value exact match
- EmptyConsumedValue # key exact match, consumed value is empty
Expand Down
2 changes: 0 additions & 2 deletions test/packs/ARM/RteTest_DFP/0.2.0/Layers/board3.clayer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ layer:

connections:
- connect: Board3 Connections
provides:
- MultipleProvided # same connection is provided multiple times with identical values
consumes:
- ExactMatch: 42 # both key and value exact match
- EmptyConsumedValue # key exact match, consumed value is empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ layer:
connections:
- connect: Incompatible Connections
provides:
- MultipleProvided # same connection is provided multiple times with identical values
- MultipleProvidedNonIdentical0: 111 # same connection is provided multiple times with non identical values
- MultipleProvidedNonIdentical1: 222 # same connection is provided multiple times with non identical values
consumes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ layer:

connections:
- connect: Test variant Connections
provides:
- MultipleProvided # same connection is provided multiple times with identical values
consumes:
- AddedValueLessThanProvided: +49 # added consumed values are less than provided
- AddedValueEqualToProvided: +499 # added consumed values are equal to provided
5 changes: 4 additions & 1 deletion tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
* conflicted connections,
* overflowed connections,
* incompatible connections,
* missed provided combined connections,
* provided connections
*/
struct ConnectionsValidationResult {
bool valid;
StrVec conflicts;
StrPairVec overflows;
StrPairVec incompatibles;
std::vector<ConnectionsCollection> missedCollections;
StrPairPtrVec provides;
};

Expand Down Expand Up @@ -648,7 +650,7 @@ class ProjMgrWorker {
void CollectConnections(ContextItem& context, ConnectionsCollectionVec& connections);
void GetConsumesProvides(const ConnectionsCollectionVec& collection, ConnectionsList& connections);
ConnectionsCollectionMap ClassifyConnections(const ConnectionsCollectionVec& connections);
ConnectionsValidationResult ValidateConnections(ConnectionsList& connections);
ConnectionsValidationResult ValidateConnections(ConnectionsCollectionVec combination);
void GetAllCombinations(const ConnectionsCollectionMap& src, const ConnectionsCollectionMap::iterator& it,
std::vector<ConnectionsCollectionVec>& combinations, const ConnectionsCollectionVec& previous = ConnectionsCollectionVec());
void GetAllSelectCombinations(const ConnectPtrVec& src, const ConnectPtrVec::iterator& it,
Expand All @@ -662,6 +664,7 @@ class ProjMgrWorker {
bool IsConnectionSubset(const ConnectionsCollection& connectionSubset, const ConnectionsCollection& connectionSuperset);
bool IsCollectionSubset(const ConnectionsCollectionVec& collectionSubset, const ConnectionsCollectionVec& collectionSuperset);
void RemoveRedundantSubsets(std::vector<ConnectionsCollectionVec>& validConnections);
bool ProvidedConnectionsMatch(ConnectionsCollection collection, ConnectionsList connections);
StrSet GetValidSets(ContextItem& context, const std::string& clayer);
void SetDefaultLinkerScript(ContextItem& context);
void CheckAndGenerateRegionsHeader(ContextItem& context);
Expand Down
74 changes: 62 additions & 12 deletions tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,15 +677,15 @@ bool ProjMgrWorker::DiscoverMatchingLayers(ContextItem& context, const string& c
debugMsg += "\n";
}
// validate connections
ConnectionsList connections;
GetConsumesProvides(combination, connections);
ConnectionsValidationResult result = ValidateConnections(connections);
ConnectionsValidationResult result = ValidateConnections(combination);

// update list of compatible layers
if (result.valid) {
context.validConnections.push_back(combination);
for (const auto& [type, _] : matchedTypeClayers) {
for (const auto& item : combination) {
if (item.type == type) {
ProjMgrUtils::PushBackUniquely(context.compatibleLayers[type], item.filename);
for (const auto& collection : combination) {
if (collection.type == type) {
ProjMgrUtils::PushBackUniquely(context.compatibleLayers[type], collection.filename);
}
}
}
Expand Down Expand Up @@ -775,7 +775,7 @@ bool ProjMgrWorker::DiscoverMatchingLayers(ContextItem& context, const string& c
void ProjMgrWorker::PrintConnectionsValidation(ConnectionsValidationResult result, string& msg) {
if (!result.valid) {
if (!result.conflicts.empty()) {
msg += "connections provided with multiple different values:";
msg += "connections provided multiple times:";
for (const auto& id : result.conflicts) {
msg += "\n " + id;
}
Expand All @@ -795,6 +795,20 @@ void ProjMgrWorker::PrintConnectionsValidation(ConnectionsValidationResult resul
}
msg += "\n";
}

if (!result.missedCollections.empty()) {
msg += "provided combined connections not consumed:";
for (const auto& missedCollection : result.missedCollections) {
msg += "\n " + missedCollection.filename + (missedCollection.type.empty() ? "" : " (layer type: " + missedCollection.type + ")");
for (const auto& connect : missedCollection.connections) {
for (const auto& provided : connect->provides) {
msg += "\n " + provided.first;
}
}
}
msg += "\n";
}

}
}

Expand Down Expand Up @@ -870,8 +884,13 @@ ConnectionsCollectionMap ProjMgrWorker::ClassifyConnections(const ConnectionsCol

void ProjMgrWorker::GetConsumesProvides(const ConnectionsCollectionVec& collection, ConnectionsList& connections) {
// collect consumed and provided connections
ConnectPtrVec visitedConnect;
for (const auto& item : collection) {
for (const auto& connect : item.connections) {
if (find(visitedConnect.begin(), visitedConnect.end(), connect) != visitedConnect.end()) {
continue;
}
visitedConnect.push_back(connect);
for (const auto& consumed : connect->consumes) {
connections.consumes.push_back(&consumed);
}
Expand All @@ -882,15 +901,40 @@ void ProjMgrWorker::GetConsumesProvides(const ConnectionsCollectionVec& collecti
}
}

ConnectionsValidationResult ProjMgrWorker::ValidateConnections(ConnectionsList& connections) {
bool ProjMgrWorker::ProvidedConnectionsMatch(ConnectionsCollection collection, ConnectionsList connections) {
// for a given collection check if provided connections match at least a consumed one
if (collection.connections.size() == 0) {
return true;
}
for (const auto& connect : collection.connections) {
if (connect->provides.size() == 0) {
return true;
}
for (const auto& provided : connect->provides) {
for (const auto& consumed : connections.consumes) {
if (provided.first == (*consumed).first) {
return true;
}
}
}
}
return false;
}

ConnectionsValidationResult ProjMgrWorker::ValidateConnections(ConnectionsCollectionVec combination) {
// get connections
ConnectionsList connections;
GetConsumesProvides(combination, connections);

// elaborate provided list
StrMap providedValues;
StrVec conflicts;
vector<ConnectionsCollection> missedCollections;
for (const auto& provided : connections.provides) {
const auto& key = provided->first;
const auto& value = provided->second;
if ((providedValues.find(key) != providedValues.end()) && (providedValues.at(key) != value)) {
// interface is provided with multiple different values
if ((providedValues.find(key) != providedValues.end())) {
// connection is provided multiple times
ProjMgrUtils::PushBackUniquely(conflicts, key);
continue;
}
Expand Down Expand Up @@ -930,10 +974,16 @@ ConnectionsValidationResult ProjMgrWorker::ValidateConnections(ConnectionsList&
incompatibles.push_back({ consumedKey, consumed->second });
}
}
// validate provided connections of each combination match at least one consumed
for (const auto& collection : combination) {
if (!ProvidedConnectionsMatch(collection, connections)) {
missedCollections.push_back(collection);
}
}

// set results
bool result = !conflicts.empty() || !overflows.empty() || !incompatibles.empty() ? false : true;
return { result, conflicts, overflows, incompatibles, connections.provides };
bool result = !conflicts.empty() || !overflows.empty() || !incompatibles.empty() || !missedCollections.empty() ? false : true;
return { result, conflicts, overflows, incompatibles, missedCollections, connections.provides };
}

bool ProjMgrWorker::ProcessDevice(ContextItem& context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ project:
- EmptyValues # key exact match, both values empty
- AddedValueLessThanProvided: 99 # added consumed values are less than provided
- AddedValueEqualToProvided: 998 # added consumed values are equal to provided
- MultipleProvided # same connection is provided multiple times with identical values
# incompatible connections
- MultipleProvided # same connection is provided multiple times with identical values
- MultipleProvidedNonIdentical0: 222 # same connection is provided multiple times with non identical values
- MultipleProvidedNonIdentical1 # same connection is provided multiple times with non identical values
- ProvidedDontMatch: 0 # consumed connection doesn't match provided one
Expand Down
24 changes: 21 additions & 3 deletions tools/projmgr/test/src/ProjMgrUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,14 +1020,20 @@ check combined connections:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
\\(Incompatible Connections\\)\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/pdsc-type-mismatch.clayer.yml \\(layer type: DifferentFromDescriptionInPdsc\\)\n\
connections provided with multiple different values:\n\
connections provided multiple times:\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
required connections not provided:\n\
ProvidedDontMatch: -1\n\
ProvidedEmpty: 123\n\
sum of required values exceed provided:\n\
AddedValueHigherThanProvided: 100 > 99\n\
provided combined connections not consumed:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
connections are invalid\n\
\n\
check combined connections:\n\
Expand All @@ -1038,14 +1044,20 @@ check combined connections:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
\\(Incompatible Connections\\)\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/pdsc-type-mismatch.clayer.yml \\(layer type: DifferentFromDescriptionInPdsc\\)\n\
connections provided with multiple different values:\n\
connections provided multiple times:\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
required connections not provided:\n\
ProvidedDontMatch: -1\n\
ProvidedEmpty: 123\n\
sum of required values exceed provided:\n\
AddedValueHigherThanProvided: 100 > 99\n\
provided combined connections not consumed:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
connections are invalid\n\
\n\
check combined connections:\n\
Expand All @@ -1056,14 +1068,20 @@ check combined connections:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
\\(Incompatible Connections\\)\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/pdsc-type-mismatch.clayer.yml \\(layer type: DifferentFromDescriptionInPdsc\\)\n\
connections provided with multiple different values:\n\
connections provided multiple times:\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
required connections not provided:\n\
ProvidedDontMatch: -1\n\
ProvidedEmpty: 123\n\
sum of required values exceed provided:\n\
AddedValueHigherThanProvided: 100 > 99\n\
provided combined connections not consumed:\n\
.*/ARM/RteTest_DFP/0.2.0/Layers/incompatible.clayer.yml \\(layer type: Incompatible\\)\n\
MultipleProvided\n\
MultipleProvidedNonIdentical0\n\
MultipleProvidedNonIdentical1\n\
connections are invalid\n\
\n\
no valid combination of clayers was found\n\
Expand Down
28 changes: 9 additions & 19 deletions tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,6 @@ TEST_F(ProjMgrWorkerUnitTests, GetAllSelectCombinations) {

TEST_F(ProjMgrWorkerUnitTests, ValidateConnections) {
ConnectionsValidationResult result;
ConnectionsList connections;

// valid connections
StrPairVec consumedList = {
Expand All @@ -1038,50 +1037,41 @@ TEST_F(ProjMgrWorkerUnitTests, ValidateConnections) {
{"Lemon", "+150"},
{"Lemon", "+20"},
};
for (const auto& item : consumedList) {
connections.consumes.push_back(&item);
}
StrPairVec providedList = {
{"Orange", "3"}, // both key and value exact match
{"Grape Fruit", "999"}, // key exact match, consumed value is empty
{"Peach", ""}, // key exact match, both values empty
{"Lemon", "200"}, // added consumed values are less than provided
{"Lime", "100"}, // added consumed values are equal to provided
{"Ananas", "2"}, {"Ananas", "2"}, // same interface is provided multiple times with identical values
};
for (const auto& item : providedList) {
connections.provides.push_back(&item);
}
result = ValidateConnections(connections);

ConnectItem validConnectItem = { RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, providedList, consumedList };
ConnectionsCollection validCollection = { RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, {&validConnectItem} };
result = ValidateConnections({ validCollection });
EXPECT_TRUE(result.valid);

// invalid connections
connections.consumes.clear();
connections.provides.clear();
// same interface is provided multiple times with non identical values
consumedList = {
{"Lemon", "+150"},
{"Lemon", "+20"},
{"Ananas", "98"},
{"Grape Fruit", "1"},
};
for (const auto& item : consumedList) {
connections.consumes.push_back(&item);
}
providedList = {
{"Ananas", "97"}, // consumed interface doesn't match provided one
{"Grape Fruit", ""}, // consumed interface doesn't match empty provided one
{"Lemon", "160"}, // sum of consumed added values is higher than provided value
{"Ananas", "2"}, {"Ananas", "2"}, // same interface is provided multiple times with identical values
{"Orange", "3"}, {"Orange", "4"}, // same interface is provided multiple times with non identical values
{"Banana", ""}, {"Banana", "0"}, // same interface is provided multiple times with non identical values
};
for (const auto& item : providedList) {
connections.provides.push_back(&item);
}
StrVec expectedConflicts = { "Orange", "Banana" };
StrVec expectedConflicts = { "Ananas", "Orange", "Banana" };
StrPairVec expectedOverflow = {{"Lemon", "170 > 160"}};
StrPairVec expectedIncompatibles = {{"Ananas", "98"}, {"Grape Fruit", "1"}};
result = ValidateConnections(connections);
ConnectItem invalidConnectItem = { RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, providedList, consumedList };
ConnectionsCollection invalidCollection = { RteUtils::EMPTY_STRING, RteUtils::EMPTY_STRING, {&invalidConnectItem} };
result = ValidateConnections({ invalidCollection });
EXPECT_FALSE(result.valid);
EXPECT_EQ(result.conflicts, expectedConflicts);
EXPECT_EQ(result.overflows, expectedOverflow);
Expand Down
Loading