Skip to content

Commit

Permalink
[projmgr] Update connections validation rules
Browse files Browse the repository at this point in the history
  • Loading branch information
grasci-arm authored Aug 21, 2023
1 parent bbf0612 commit 884d70a
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 44 deletions.
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

0 comments on commit 884d70a

Please sign in to comment.