public IEnumerable <RequestSequence> Generate(List <KnownEndpoint> endpoints, RequestSequence sequence, List <TokenCollection> sequenceResults) { // Only build off sequences that have an actual result. if (sequence.GetLastResponse() == null || (int)sequence.GetLastResponse().Status < 300) { // Search for an endpoint that we can append to the end of this request sequence. foreach (KnownEndpoint endpoint in endpoints) { bool foundMatch = true; TokenCollection requirements = endpoint.InputTokens; Stage candidateStage = new Stage(endpoint.Request.Clone()); foreach (IToken token in requirements) { int matchIndex = 0; IToken?matchToken = null; // Substituting a token with the same name is usually a good bet, but sometimes gets stuck if there is a false positive. // Add some level of randomness to keep things working. int skip = Rand.Next(0, 2); if (skip >= 2 && GetRandomNameMatch(sequenceResults, token.Name, out matchToken, out matchIndex)) { // Find a token that has the same name as this one. candidateStage.Substitutions.Add(new SubstituteNamedToken(token, matchToken, matchIndex)); } else if (skip >= 1 && GetRandomTypeMatch(sequenceResults, token.SupportedTypes, out matchToken, out matchIndex)) { // Find a token that has the same type as this one. candidateStage.Substitutions.Add(new SubstituteNamedToken(token, matchToken, matchIndex)); } else { // Use the original value from the example request. candidateStage.Substitutions.Add(new SubstituteConstant(token, token.Value)); } } if (foundMatch) { RequestSequence newSequence = sequence.Copy(); newSequence.Add(candidateStage); yield return(newSequence); } } } }
public IEnumerable <RequestSequence> Generate(List <KnownEndpoint> endpoints, RequestSequence sequence, List <TokenCollection> sequenceResults) { if (dictionary.Count == 0) { yield break; } for (int i = 0; i < MaxSubstitutions; ++i) { if (sequence.StageCount() == 0) { continue; } RequestSequence newSequence = sequence.Copy(); int selectedStage = rand.Next(0, newSequence.StageCount()); Stage stage = newSequence.Get(selectedStage); if (stage.Substitutions.Count == 0) { continue; } int subIndex = rand.Next(0, newSequence.Get(selectedStage).Substitutions.Count); ISubstitution sub = newSequence.Get(selectedStage).Substitutions[subIndex]; newSequence.Get(selectedStage).Substitutions.RemoveAt(subIndex); string replacement = dictionary[rand.Next(0, dictionary.Count)]; SubstituteConstant substituteConstant = new SubstituteConstant(sub.GetTarget(), replacement); newSequence.Get(selectedStage).Substitutions.Add(substituteConstant); yield return(newSequence); } yield break; }