1 /** 2 * Copyright © 2019 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "extensions/openpower-pels/callouts.hpp" 17 #include "pel_utils.hpp" 18 19 #include <gtest/gtest.h> 20 21 using namespace openpower::pels; 22 using namespace openpower::pels::src; 23 24 TEST(CalloutsTest, UnflattenFlattenTest) 25 { 26 std::vector<uint8_t> data{0xC0, 0x00, 0x00, 27 0x00}; // ID, flags, length in words 28 29 // Add 2 callouts 30 auto callout = srcDataFactory(TestSRCType::calloutStructureA); 31 data.insert(data.end(), callout.begin(), callout.end()); 32 33 callout = srcDataFactory(TestSRCType::calloutStructureB); 34 data.insert(data.end(), callout.begin(), callout.end()); 35 36 Stream stream{data}; 37 38 // Set the actual word length value at offset 2 39 uint16_t wordLength = data.size() / 4; 40 stream.offset(2); 41 stream << wordLength; 42 stream.offset(0); 43 44 Callouts callouts{stream}; 45 46 EXPECT_EQ(callouts.flattenedSize(), data.size()); 47 EXPECT_EQ(callouts.callouts().size(), 2); 48 49 // spot check that each callout has the right substructures 50 EXPECT_TRUE(callouts.callouts().front()->fruIdentity()); 51 EXPECT_FALSE(callouts.callouts().front()->pceIdentity()); 52 EXPECT_FALSE(callouts.callouts().front()->mru()); 53 54 EXPECT_TRUE(callouts.callouts().back()->fruIdentity()); 55 EXPECT_TRUE(callouts.callouts().back()->pceIdentity()); 56 EXPECT_TRUE(callouts.callouts().back()->mru()); 57 58 // Flatten 59 std::vector<uint8_t> newData; 60 Stream newStream{newData}; 61 62 callouts.flatten(newStream); 63 EXPECT_EQ(data, newData); 64 } 65 66 TEST(CalloutsTest, BadDataTest) 67 { 68 // Start out with a valid 2 callout object, then truncate it. 69 std::vector<uint8_t> data{0xC0, 0x00, 0x00, 70 0x00}; // ID, flags, length in words 71 72 // Add 2 callouts 73 auto callout = srcDataFactory(TestSRCType::calloutStructureA); 74 data.insert(data.end(), callout.begin(), callout.end()); 75 76 callout = srcDataFactory(TestSRCType::calloutStructureB); 77 data.insert(data.end(), callout.begin(), callout.end()); 78 79 Stream stream{data}; 80 81 // Set the actual word length value at offset 2 82 uint16_t wordLength = data.size() / 4; 83 stream.offset(2); 84 stream << wordLength; 85 stream.offset(0); 86 87 // Shorten the data by an arbitrary amount so unflattening goes awry. 88 data.resize(data.size() - 37); 89 90 EXPECT_THROW(Callouts callouts{stream}, std::out_of_range); 91 } 92 93 TEST(CalloutsTest, TestAddCallouts) 94 { 95 Callouts callouts; 96 97 // Empty Callouts size 98 size_t lastSize = 4; 99 100 for (size_t i = 0; i < maxNumberOfCallouts; i++) 101 { 102 auto callout = std::make_unique<Callout>( 103 CalloutPriority::high, "U1-P1", "1234567", "ABCD", "123456789ABC"); 104 auto calloutSize = callout->flattenedSize(); 105 106 callouts.addCallout(std::move(callout)); 107 108 EXPECT_EQ(callouts.flattenedSize(), lastSize + calloutSize); 109 110 lastSize = callouts.flattenedSize(); 111 112 EXPECT_EQ(callouts.callouts().size(), i + 1); 113 } 114 115 // Try to add an 11th callout. Shouldn't work 116 117 auto callout = std::make_unique<Callout>(CalloutPriority::high, "U1-P1", 118 "1234567", "ABCD", "123456789ABC"); 119 callouts.addCallout(std::move(callout)); 120 121 EXPECT_EQ(callouts.callouts().size(), maxNumberOfCallouts); 122 } 123 124 TEST(CalloutsTest, TestSortCallouts) 125 { 126 Callouts callouts; 127 128 // Add callouts with different priorities to test sorting in descending 129 // order 130 131 auto c0 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1", 132 "1234567", "ABC", "123456789ABC"); 133 134 callouts.addCallout(std::move(c0)); 135 136 auto c1 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P2", 137 "1234567", "ABCD", "123456789ABC"); 138 139 callouts.addCallout(std::move(c1)); 140 141 auto c2 = std::make_unique<Callout>(CalloutPriority::low, "U1-P3", 142 "1234567", "ABCDE", "123456789ABC"); 143 144 callouts.addCallout(std::move(c2)); 145 146 auto c3 = std::make_unique<Callout>(CalloutPriority::high, "U1-P4", 147 "1234567", "ABCDE1", "123456789ABC"); 148 149 callouts.addCallout(std::move(c3)); 150 151 auto c4 = std::make_unique<Callout>(CalloutPriority::high, "U1-P5", 152 "1234567", "ABCDE2", "123456789ABC"); 153 154 callouts.addCallout(std::move(c4)); 155 156 auto c5 = std::make_unique<Callout>(CalloutPriority::low, "U1-P6", 157 "1234567", "ABCDE2", "123456789ABC"); 158 159 callouts.addCallout(std::move(c5)); 160 161 auto c6 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P7", 162 "1234567", "ABCD2", "123456789ABC"); 163 164 callouts.addCallout(std::move(c6)); 165 166 auto c7 = std::make_unique<Callout>(CalloutPriority::mediumGroupA, "U1-P8", 167 "1234567", "ABCDE3", "123456789ABC"); 168 169 callouts.addCallout(std::move(c7)); 170 171 auto c8 = std::make_unique<Callout>(CalloutPriority::mediumGroupC, "U1-P9", 172 "1234567", "ABCDE4", "123456789ABC"); 173 174 callouts.addCallout(std::move(c8)); 175 176 auto c9 = std::make_unique<Callout>(CalloutPriority::low, "U1-P10", 177 "1234567", "ABCDE3", "123456789ABC"); 178 179 callouts.addCallout(std::move(c9)); 180 181 const auto& calloutObjects = callouts.callouts(); 182 EXPECT_EQ(calloutObjects[0]->locationCode(), "U1-P1"); 183 EXPECT_EQ(calloutObjects[0]->priority(), 'H'); 184 EXPECT_EQ(calloutObjects[1]->locationCode(), "U1-P4"); 185 EXPECT_EQ(calloutObjects[1]->priority(), 'H'); 186 EXPECT_EQ(calloutObjects[2]->locationCode(), "U1-P5"); 187 EXPECT_EQ(calloutObjects[2]->priority(), 'H'); 188 EXPECT_EQ(calloutObjects[3]->locationCode(), "U1-P2"); 189 EXPECT_EQ(calloutObjects[3]->priority(), 'M'); 190 EXPECT_EQ(calloutObjects[4]->locationCode(), "U1-P7"); 191 EXPECT_EQ(calloutObjects[4]->priority(), 'M'); 192 EXPECT_EQ(calloutObjects[5]->locationCode(), "U1-P8"); 193 EXPECT_EQ(calloutObjects[5]->priority(), 'A'); 194 EXPECT_EQ(calloutObjects[6]->locationCode(), "U1-P9"); 195 EXPECT_EQ(calloutObjects[6]->priority(), 'C'); 196 EXPECT_EQ(calloutObjects[7]->locationCode(), "U1-P3"); 197 EXPECT_EQ(calloutObjects[7]->priority(), 'L'); 198 EXPECT_EQ(calloutObjects[8]->locationCode(), "U1-P6"); 199 EXPECT_EQ(calloutObjects[8]->priority(), 'L'); 200 EXPECT_EQ(calloutObjects[9]->locationCode(), "U1-P10"); 201 EXPECT_EQ(calloutObjects[9]->priority(), 'L'); 202 } 203