Software APIs
error_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/error.h"
6 
7 #include <climits>
8 #include <cstdint>
9 #include <map>
10 #include <string>
11 
12 #include "gtest/gtest.h"
14 #include "sw/device/silicon_creator/lib/error_unittest_util.h"
15 
16 namespace error_unittest {
17 namespace {
18 
19 constexpr int kMinimumHammingDistance = 6;
20 
21 rom_error_t ReturnIfError(rom_error_t value) {
22  RETURN_IF_ERROR(value);
23 
24  // Return something other than kErrorOk just in case RETURN_IF_ERROR
25  // was wrong.
26  return static_cast<rom_error_t>(0);
27 }
28 
29 int HammingDistance(uint32_t a, uint32_t b) {
30  // The hamming distance is the number of bits different between the two words.
31  return bitfield_popcount32(a ^ b);
32 }
33 
34 // Checks that there are no duplicate values in the error definitions.
35 TEST(ErrorsTest, NoDuplicateValues) {
36  const auto &errors = GetErrorMap();
37 
38  for (auto a = errors.begin(); a != errors.end(); ++a) {
39  for (auto b = a; b != errors.end(); ++b) {
40  if (a == b) {
41  continue;
42  }
43  EXPECT_NE(a->second, b->second)
44  << "Error codes '" << a->first << "' and '" << b->first
45  << "' have the same value.";
46  }
47  }
48 }
49 
50 // Checks that the RETURN_IF_ERROR macro works as expected.
51 TEST(ErrorsTest, CheckReturnIfError) {
52  EXPECT_EQ(kErrorUnknown, ReturnIfError(kErrorUnknown));
53 
54  rom_error_t ok = ReturnIfError(kErrorOk);
55  EXPECT_EQ(0, static_cast<int>(ok));
56 }
57 
58 TEST(ErrorsTest, CheckHammingDistanceToOk) {
59  const auto &errors = GetErrorMap();
60  int max_distance = 0;
61  int min_distance = INT_MAX;
62  int distance;
63 
64  for (const auto &a : errors) {
65  if (a.second == kErrorOk) {
66  distance = HammingDistance(a.second, 0);
67  std::cout << "Hamming distance between '" << a.first
68  << "' and zero: " << distance << std::endl;
69  } else {
70  distance = HammingDistance(a.second, kErrorOk);
71  std::cout << "Hamming distance between '" << a.first
72  << "' and kErrorOk: " << distance << std::endl;
73  }
74  EXPECT_GE(distance, kMinimumHammingDistance);
75  min_distance = std::min(min_distance, distance);
76  max_distance = std::max(max_distance, distance);
77  }
78  std::cout << "Minimum hamming distance observed: " << min_distance
79  << std::endl;
80  std::cout << "Maximum hamming distance observed: " << max_distance
81  << std::endl;
82 }
83 
84 } // namespace
85 } // namespace error_unittest