Skip to content

Commit b9ee63c

Browse files
committed
Make descriptor test deterministic
Changed MaybeUseHInsteadOfApostrophy to UseHInsteadOfApostrophe. This function now always replaces apostrophes with 'h'. The original Check function was renamed to DoCheck and it's called with an additional parameter which tells it to either leave the prv and pub arguments as is or replace the apostrophes with 'h'. The test runs with apostrophes replaced in prv only, pub only, prv and pub and without replacement at all. Replacement of apostrophes in a descriptor and then running DoCheck is conditional on whether apostrophes are found in that descriptor. Additionally, instead of dropping the checksum recalculate it after replacing apostrophes with 'h' in the function UseHInsteadOfApostrophe using the GetDescriptorChecksum function. That way, this also introduces an indirect unit test to GetDescriptoChecksum.
1 parent 48e5bfe commit b9ee63c

File tree

1 file changed

+54
-14
lines changed

1 file changed

+54
-14
lines changed

src/test/descriptor_tests.cpp

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,33 +42,47 @@ bool EqualDescriptor(std::string a, std::string b)
4242
return a == b;
4343
}
4444

45-
std::string MaybeUseHInsteadOfApostrophy(std::string ret)
45+
std::string UseHInsteadOfApostrophe(const std::string& desc)
4646
{
47-
if (InsecureRandBool()) {
48-
while (true) {
49-
auto it = ret.find("'");
50-
if (it != std::string::npos) {
51-
ret[it] = 'h';
52-
if (ret.size() > 9 && ret[ret.size() - 9] == '#') ret = ret.substr(0, ret.size() - 9); // Changing apostrophe to h breaks the checksum
53-
} else {
54-
break;
55-
}
56-
}
47+
std::string ret = desc;
48+
while (true) {
49+
auto it = ret.find('\'');
50+
if (it == std::string::npos) break;
51+
ret[it] = 'h';
52+
}
53+
54+
// GetDescriptorChecksum returns "" if the checksum exists but is bad.
55+
// Switching apostrophes with 'h' breaks the checksum if it exists - recalculate it and replace the broken one.
56+
if (GetDescriptorChecksum(ret) == "") {
57+
ret = ret.substr(0, desc.size() - 9);
58+
ret += std::string("#") + GetDescriptorChecksum(ret);
5759
}
5860
return ret;
5961
}
6062

6163
const std::set<std::vector<uint32_t>> ONLY_EMPTY{{}};
6264

63-
void Check(const std::string& prv, const std::string& pub, int flags, const std::vector<std::vector<std::string>>& scripts, const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY)
65+
void DoCheck(const std::string& prv, const std::string& pub, int flags, const std::vector<std::vector<std::string>>& scripts, const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY,
66+
bool replace_apostrophe_with_h_in_prv=false, bool replace_apostrophe_with_h_in_pub=false)
6467
{
6568
FlatSigningProvider keys_priv, keys_pub;
6669
std::set<std::vector<uint32_t>> left_paths = paths;
6770
std::string error;
6871

72+
std::unique_ptr<Descriptor> parse_priv;
73+
std::unique_ptr<Descriptor> parse_pub;
6974
// Check that parsing succeeds.
70-
auto parse_priv = Parse(MaybeUseHInsteadOfApostrophy(prv), keys_priv, error);
71-
auto parse_pub = Parse(MaybeUseHInsteadOfApostrophy(pub), keys_pub, error);
75+
if (replace_apostrophe_with_h_in_prv) {
76+
parse_priv = Parse(UseHInsteadOfApostrophe(prv), keys_priv, error);
77+
} else {
78+
parse_priv = Parse(prv, keys_priv, error);
79+
}
80+
if (replace_apostrophe_with_h_in_pub) {
81+
parse_pub = Parse(UseHInsteadOfApostrophe(pub), keys_pub, error);
82+
} else {
83+
parse_pub = Parse(pub, keys_pub, error);
84+
}
85+
7286
BOOST_CHECK(parse_priv);
7387
BOOST_CHECK(parse_pub);
7488

@@ -167,6 +181,32 @@ void Check(const std::string& prv, const std::string& pub, int flags, const std:
167181
BOOST_CHECK_MESSAGE(left_paths.empty(), "Not all expected key paths found: " + prv);
168182
}
169183

184+
void Check(const std::string& prv, const std::string& pub, int flags, const std::vector<std::vector<std::string>>& scripts, const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY)
185+
{
186+
bool found_apostrophes_in_prv = false;
187+
bool found_apostrophes_in_pub = false;
188+
189+
// Do not replace apostrophes with 'h' in prv and pub
190+
DoCheck(prv, pub, flags, scripts, paths);
191+
192+
// Replace apostrophes with 'h' in prv but not in pub, if apostrophes are found in prv
193+
if (prv.find('\'') != std::string::npos) {
194+
found_apostrophes_in_prv = true;
195+
DoCheck(prv, pub, flags, scripts, paths, /* replace_apostrophe_with_h_in_prv = */true, /*replace_apostrophe_with_h_in_pub = */false);
196+
}
197+
198+
// Replace apostrophes with 'h' in pub but not in prv, if apostrophes are found in pub
199+
if (pub.find('\'') != std::string::npos) {
200+
found_apostrophes_in_pub = true;
201+
DoCheck(prv, pub, flags, scripts, paths, /* replace_apostrophe_with_h_in_prv = */false, /*replace_apostrophe_with_h_in_pub = */true);
202+
}
203+
204+
// Replace apostrophes with 'h' both in prv and in pub, if apostrophes are found in both
205+
if (found_apostrophes_in_prv && found_apostrophes_in_pub) {
206+
DoCheck(prv, pub, flags, scripts, paths, /* replace_apostrophe_with_h_in_prv = */true, /*replace_apostrophe_with_h_in_pub = */true);
207+
}
208+
}
209+
170210
}
171211

172212
BOOST_FIXTURE_TEST_SUITE(descriptor_tests, BasicTestingSetup)

0 commit comments

Comments
 (0)