mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	[yul-phaser] Replace mutation tests with hard-coded expectations with more robust ones that check the statistical distribution
- The old tests would easily break when adding/removing optimiser steps.
This commit is contained in:
		
							parent
							
								
									d75f0ba437
								
							
						
					
					
						commit
						5637bdcaec
					
				| @ -22,6 +22,7 @@ | |||||||
| #include <tools/yulPhaser/SimulationRNG.h> | #include <tools/yulPhaser/SimulationRNG.h> | ||||||
| 
 | 
 | ||||||
| #include <libsolutil/CommonIO.h> | #include <libsolutil/CommonIO.h> | ||||||
|  | #include <libyul/optimiser/Suite.h> | ||||||
| 
 | 
 | ||||||
| #include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||||
| #include <boost/algorithm/string/predicate.hpp> | #include <boost/algorithm/string/predicate.hpp> | ||||||
| @ -31,6 +32,7 @@ | |||||||
| 
 | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| using namespace solidity::util; | using namespace solidity::util; | ||||||
|  | using namespace solidity::yul; | ||||||
| 
 | 
 | ||||||
| namespace solidity::phaser::test | namespace solidity::phaser::test | ||||||
| { | { | ||||||
| @ -41,19 +43,32 @@ BOOST_AUTO_TEST_SUITE(GeneRandomisationTest) | |||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneRandomisation_should_iterate_over_genes_and_replace_them_with_random_ones_with_given_probability) | BOOST_AUTO_TEST_CASE(geneRandomisation_should_iterate_over_genes_and_replace_them_with_random_ones_with_given_probability) | ||||||
| { | { | ||||||
| 	Chromosome chromosome("fcCUnDvejs"); | 	size_t constexpr inputLength = 1000; | ||||||
| 	function<Mutation> mutation01 = geneRandomisation(0.1); | 	double constexpr tolerance = 0.05; | ||||||
| 	function<Mutation> mutation05 = geneRandomisation(0.5); | 
 | ||||||
| 	function<Mutation> mutation10 = geneRandomisation(1.0); | 	// Use genes that do not represent valid step abbreviations to be able to easily spot added steps.
 | ||||||
|  | 	assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); | ||||||
|  | 	Chromosome input = Chromosome(string(inputLength, '.')); | ||||||
| 
 | 
 | ||||||
| 	SimulationRNG::reset(1); | 	SimulationRNG::reset(1); | ||||||
| 	BOOST_TEST(countDifferences(mutation01(chromosome), chromosome), 2); | 	for (size_t randomisationChancePercent = 20; randomisationChancePercent <= 100; randomisationChancePercent += 20) | ||||||
| 	BOOST_TEST(countDifferences(mutation05(chromosome), chromosome), 5); | 	{ | ||||||
| 	BOOST_TEST(countDifferences(mutation10(chromosome), chromosome), 7); | 		double const randomisationChance = (randomisationChancePercent / 100.0); | ||||||
| 	SimulationRNG::reset(2); | 
 | ||||||
| 	BOOST_TEST(countDifferences(mutation01(chromosome), chromosome), 1); | 		Chromosome output = geneRandomisation(randomisationChance)(input); | ||||||
| 	BOOST_TEST(countDifferences(mutation05(chromosome), chromosome), 3); | 		string outputGenes = output.genes(); | ||||||
| 	BOOST_TEST(countDifferences(mutation10(chromosome), chromosome), 9); | 		BOOST_REQUIRE(output.length() == input.length()); | ||||||
|  | 
 | ||||||
|  | 		double const expectedValue = randomisationChance; | ||||||
|  | 		double const variance = randomisationChance * (1 - randomisationChance); | ||||||
|  | 		double const randomisedGeneCount = input.length() - static_cast<size_t>(count(outputGenes.begin(), outputGenes.end(), '.')); | ||||||
|  | 		double const squaredError = | ||||||
|  | 			(inputLength - randomisedGeneCount) * expectedValue * expectedValue + | ||||||
|  | 			randomisedGeneCount * (1 - expectedValue) * (1 - expectedValue); | ||||||
|  | 
 | ||||||
|  | 		BOOST_TEST(abs(randomisedGeneCount / inputLength - expectedValue) < tolerance); | ||||||
|  | 		BOOST_TEST(abs(squaredError / inputLength - variance) < tolerance); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneRandomisation_should_return_identical_chromosome_if_probability_is_zero) | BOOST_AUTO_TEST_CASE(geneRandomisation_should_return_identical_chromosome_if_probability_is_zero) | ||||||
| @ -66,17 +81,33 @@ BOOST_AUTO_TEST_CASE(geneRandomisation_should_return_identical_chromosome_if_pro | |||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneDeletion_should_iterate_over_genes_and_delete_them_with_given_probability) | BOOST_AUTO_TEST_CASE(geneDeletion_should_iterate_over_genes_and_delete_them_with_given_probability) | ||||||
| { | { | ||||||
| 	Chromosome chromosome("fcCUnDvejs"); | 	size_t constexpr inputLength = 1000; | ||||||
| 	function<Mutation> mutation01 = geneDeletion(0.1); | 	double constexpr tolerance = 0.05; | ||||||
| 	function<Mutation> mutation05 = geneDeletion(0.5); | 
 | ||||||
|  | 	// Use genes that do not represent valid step abbreviations to be able to easily spot added steps.
 | ||||||
|  | 	assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); | ||||||
|  | 	Chromosome input = Chromosome(string(inputLength, '.')); | ||||||
| 
 | 
 | ||||||
| 	SimulationRNG::reset(1); | 	SimulationRNG::reset(1); | ||||||
| 	//                                                               fcCUnDvejs
 | 	for (size_t deletionChancePercent = 20; deletionChancePercent < 100; deletionChancePercent += 20) | ||||||
| 	BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace("fcCU Dvejs"))); | 	{ | ||||||
| 	BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("     D ejs"))); | 		double const deletionChance = (deletionChancePercent / 100.0); | ||||||
| 	SimulationRNG::reset(2); | 
 | ||||||
| 	BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace("fcUnDvejs"))); | 		Chromosome output = geneDeletion(deletionChance)(input); | ||||||
| 	BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("  Un    s"))); | 		string outputGenes = output.genes(); | ||||||
|  | 		BOOST_REQUIRE(output.length() <= input.length()); | ||||||
|  | 		BOOST_REQUIRE(static_cast<size_t>(count(outputGenes.begin(), outputGenes.end(), '.')) == output.length()); | ||||||
|  | 
 | ||||||
|  | 		double const expectedValue = deletionChance; | ||||||
|  | 		double const variance = deletionChance * (1 - deletionChance); | ||||||
|  | 		double const deletedGeneCount = input.length() - output.length(); | ||||||
|  | 		double const squaredError = | ||||||
|  | 			(inputLength - deletedGeneCount) * expectedValue * expectedValue + | ||||||
|  | 			deletedGeneCount * (1 - expectedValue) * (1 - expectedValue); | ||||||
|  | 
 | ||||||
|  | 		BOOST_TEST(abs(deletedGeneCount / inputLength - expectedValue) < tolerance); | ||||||
|  | 		BOOST_TEST(abs(squaredError / inputLength - variance) < tolerance); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneDeletion_should_return_identical_chromosome_if_probability_is_zero) | BOOST_AUTO_TEST_CASE(geneDeletion_should_return_identical_chromosome_if_probability_is_zero) | ||||||
| @ -97,17 +128,37 @@ BOOST_AUTO_TEST_CASE(geneDeletion_should_delete_all_genes_if_probability_is_one) | |||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_new_genes_with_given_probability) | BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_new_genes_with_given_probability) | ||||||
| { | { | ||||||
| 	Chromosome chromosome("fcCUnDvejs"); | 	size_t constexpr inputLength = 1000; | ||||||
| 	function<Mutation> mutation01 = geneAddition(0.1); | 	double constexpr tolerance = 0.05; | ||||||
| 	function<Mutation> mutation05 = geneAddition(0.5); | 	size_t constexpr maxAdditions = inputLength + 1; | ||||||
|  | 
 | ||||||
|  | 	// Use genes that do not represent valid step abbreviations to be able to easily spot added steps.
 | ||||||
|  | 	assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); | ||||||
|  | 	Chromosome input = Chromosome(string(inputLength, '.')); | ||||||
| 
 | 
 | ||||||
| 	SimulationRNG::reset(1); | 	SimulationRNG::reset(1); | ||||||
| 	//                                                                 f  c  C  U  n  D  v  e  j  s
 | 	for (size_t additionChancePercent = 20; additionChancePercent < 100; additionChancePercent += 20) | ||||||
| 	BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace("  f  c  C  UC n  D  v  e  jx s")));  //  20% more
 | 	{ | ||||||
| 	BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("s f  cu C  U  nj D  v  eO j  sf"))); //  50% more
 | 		double const additionChance = (additionChancePercent / 100.0); | ||||||
| 	SimulationRNG::reset(2); | 
 | ||||||
| 	BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace("  f  cp C  U  n  D  v  e  j  s")));  //  10% more
 | 		Chromosome output = geneAddition(additionChance)(input); | ||||||
| 	BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("M f  ce Ce U  n  D  v  e  jo s")));  //  40% more
 | 		BOOST_REQUIRE(output.length() >= input.length()); | ||||||
|  | 		BOOST_REQUIRE(output.length() <= inputLength + maxAdditions); | ||||||
|  | 
 | ||||||
|  | 		string_view outputGenes = output.genes(); | ||||||
|  | 		size_t preservedGeneCount = static_cast<size_t>(count(outputGenes.begin(), outputGenes.end(), '.')); | ||||||
|  | 		BOOST_REQUIRE(preservedGeneCount == input.length()); | ||||||
|  | 
 | ||||||
|  | 		double const expectedValue = additionChance; | ||||||
|  | 		double const variance = additionChance * (1 - additionChance); | ||||||
|  | 		double const addedGeneCount = (output.length() - preservedGeneCount); | ||||||
|  | 		double const squaredError = | ||||||
|  | 			(maxAdditions - addedGeneCount) * expectedValue * expectedValue + | ||||||
|  | 			addedGeneCount * (1 - expectedValue) * (1 - expectedValue); | ||||||
|  | 
 | ||||||
|  | 		BOOST_TEST(abs(addedGeneCount / maxAdditions - expectedValue) < tolerance); | ||||||
|  | 		BOOST_TEST(abs(squaredError / maxAdditions - variance) < tolerance); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position) | BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user