1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VARIATIONS_VARIATIONS_TEST_UTILS_H_
#define COMPONENTS_VARIATIONS_VARIATIONS_TEST_UTILS_H_
#include <set>
#include <string>
#include "base/containers/span.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/field_trial.h"
#include "base/test/mock_entropy_provider.h"
#include "components/variations/active_field_trials.h"
#include "components/variations/client_filterable_state.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/field_trial_config/fieldtrial_testing_config.h"
#include "components/variations/proto/variations_seed.pb.h"
#include "components/variations/seed_reader_writer.h"
#include "components/variations/synthetic_trial_registry.h"
#include "components/variations/variations_associated_data.h"
class PrefService;
namespace variations {
struct ClientFilterableState;
// Packages signed variations seed data into a tuple for use with
// WriteSeedData(). This allows for encapsulated seed information to be created
// below for generic test seeds as well as seeds which cause crashes.
struct SignedSeedData {
// TODO(367764863) Rewrite to base::raw_span.
RAW_PTR_EXCLUSION base::span<const char*>
study_names; // Names of all studies in the seed.
const char* base64_uncompressed_data;
const char* base64_compressed_data;
const char* base64_signature;
const uint8_t* compressed_data;
size_t compressed_data_size;
// Out-of-line constructor/destructor/copy/move required for 'complex'
// classes.
SignedSeedData(base::span<const char*> in_study_names,
const char* in_base64_uncompressed_data,
const char* in_base64_compressed_data,
const char* in_base64_signature,
const uint8_t* in_compressed_data,
size_t in_compressed_data_size);
~SignedSeedData();
SignedSeedData(const SignedSeedData&);
SignedSeedData(SignedSeedData&&);
SignedSeedData& operator=(const SignedSeedData&);
SignedSeedData& operator=(SignedSeedData&&);
// Converts SignedSeedData's compressed data to a string.
std::string_view GetCompressedData() const;
};
// Packages variations seed pref keys into a tuple for use with StoreSeedInfo().
// This allow easily writing signed seed data into either the safe seed or
// regular seed locations in Local State.
struct SignedSeedPrefKeys {
const char* base64_compressed_data_key;
const char* base64_signature_key;
};
// The test seed data is associated with a VariationsSeed with one study,
// "UMA-Uniformity-Trial-10-Percent", and ten equally weighted groups: "default"
// and "group_01" through "group_09". The study is not associated with channels,
// platforms, or features.
extern const SignedSeedData kTestSeedData;
// The crashing seed data contains a CrashingStudy that enables the
// variations::kForceFieldTrialSetupCrashForTesting feature at 100% on all
// platforms and on all channels except Unknown.
extern const SignedSeedData kCrashingSeedData;
// The pref keys used to store safe signed variations seed data.
extern const SignedSeedPrefKeys kSafeSeedPrefKeys;
// The pref keys used to store regular signed variations seed data.
extern const SignedSeedPrefKeys kRegularSeedPrefKeys;
// Mock field trial testing config.
extern const FieldTrialTestingConfig kTestingConfig;
// Disables the use of the field trial testing config to exercise
// VariationsFieldTrialCreator::CreateTrialsFromSeed().
void DisableTestingConfig();
// Enables the use of the field trial testing config.
void EnableTestingConfig();
// Decodes the variations header and extracts the variation ids.
bool ExtractVariationIds(const std::string& variations,
std::set<VariationID>* variation_ids,
std::set<VariationID>* trigger_ids);
// Creates FieldTrial from given |key| and |id|.
scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId(
const std::string& trial_name,
const std::string& default_group_name,
IDCollectionKey key,
VariationID id);
// Simulates a crash by setting the clean exit pref to false and disabling
// the steps to update the pref on clean shutdown.
void SimulateCrash(PrefService* local_state);
// Writes |seed_info| into |local_state| using the given seed |pref_keys|.
void WriteSeedData(PrefService* local_state,
const SignedSeedData& seed_data,
const SignedSeedPrefKeys& pref_keys);
// Returns true if all of the study_names listed in |seed_data| exist in the
// (global) field trial list.
bool FieldTrialListHasAllStudiesFrom(const SignedSeedData& seed_data);
// Resets variations. Ensures that maps can be cleared between tests since they
// are stored as process singleton.
void ResetVariations();
// A no-op UIStringOverrideCallback implementation.
inline void NoopUIStringOverrideCallback(uint32_t hash,
const std::u16string& string) {}
// Create a ClientFilterableState with valid, but unimportant values.
// Tests that actually expect specific values should set them on the result.
std::unique_ptr<ClientFilterableState> CreateDummyClientFilterableState();
// An mock entropy result that will always pick the first non-zero weight group.
constexpr double kAlwaysUseFirstGroup = 0;
// An mock entropy result that will always pick the last non-zero weight group.
constexpr double kAlwaysUseLastGroup = 1.0 - 1e-8;
// EntropyProviders that return known values.
class MockEntropyProviders : public EntropyProviders {
public:
struct Results {
double low_entropy = kAlwaysUseLastGroup;
std::optional<double> high_entropy = std::nullopt;
std::optional<double> limited_entropy = std::nullopt;
};
explicit MockEntropyProviders(Results results,
uint32_t low_entropy_domain = 8000);
~MockEntropyProviders() override;
const base::FieldTrial::EntropyProvider& low_entropy() const override;
const base::FieldTrial::EntropyProvider& default_entropy() const override;
const base::FieldTrial::EntropyProvider& limited_entropy() const override;
private:
base::MockEntropyProvider low_provider_;
base::MockEntropyProvider high_provider_;
base::MockEntropyProvider limited_provider_;
};
// Returns a hex string of the GZipped, base64 encoded, and serialized seed.
std::string GZipAndB64EncodeToHexString(const VariationsSeed& seed);
// Returns whether the active group ids includes the given trial name.
bool ContainsTrialName(const std::vector<ActiveGroupId>& active_group_ids,
std::string_view trial_name);
// Returns whether the active group ids includes the given trial name with the
// given group name.
bool ContainsTrialAndGroupName(
const std::vector<ActiveGroupId>& active_group_ids,
std::string_view trial_name,
std::string_view group_name);
// Sets up the seed file experiment where `group_name` is the active group.
void SetUpSeedFileTrial(std::string group_name);
} // namespace variations
#endif // COMPONENTS_VARIATIONS_VARIATIONS_TEST_UTILS_H_
|