// For methods, it only picks receiver of type m.methodInfo.DeclaringType. private Type[] GetParameterTypeSuggestions(MemberInfo m, PlanManager planManager) { if (m is ConstructorInfo) { ConstructorInfo constructor = m as ConstructorInfo; ParameterInfo[] constructorParameters = constructor.GetParameters(); Type[] constructorArgumentTypes = new Type[constructorParameters.Length]; for (int i = 0; i < constructorParameters.Length; i++) { constructorArgumentTypes[i] = constructorParameters[i].ParameterType; } return(constructorArgumentTypes); } else { Util.Assert(m is MethodInfo); MethodInfo method = m as MethodInfo; ParameterInfo[] methodParameters = method.GetParameters(); Type[] methodArgumentTypes = new Type[methodParameters.Length]; for (int i = 0; i < methodParameters.Length; i++) { methodArgumentTypes[i] = methodParameters[i].ParameterType; } Type[] oneResult = new Type[methodArgumentTypes.Length + 1]; oneResult[0] = method.DeclaringType; Array.Copy(methodArgumentTypes, 0, oneResult, 1, methodArgumentTypes.Length); return(oneResult); } }
/// <summary> /// Tries to construct a new plan that sets a field for a /// receiver of the type given. May fail if there are no /// applicable receivers. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewFieldSettingPlan(FieldInfo field, PlanManager planManager, bool forbidNull) { this.stats.Selected(FieldSettingTransformer.Get(field).ToString()); Type[] parameterTypes = new Type[2]; parameterTypes[0] = field.DeclaringType; parameterTypes[1] = field.FieldType; RandomPlansResult r; if (!RandomPlans(out r, parameterTypes, delegate(Plan p, int i) { if (i == 0 && p.transformer is PrimitiveValueTransformer) { return(false); } return(true); }, planManager.builderPlans, forbidNull, null)) { stats.CreatedNew(CreationResult.NoInputs); return; } Plan plan = new Plan(FieldSettingTransformer.Get(field), r.fplans, r.fparameterChoosers); planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
/// <summary> /// Tries to construct a new plan that calls a method on a /// receiver of the type given. May fail if there are no /// applicable methods or receivers available. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewMethodPlan(Type type, MethodInfo method, PlanManager planManager, bool forbidNull, Type[] methodArgumentTypes) { this.stats.Selected(MethodCall.Get(method).ToString()); PlanFilter f; if (forbidNull) { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) { return(false); } // Non-null heuristic if (!methodArgumentTypes[i].IsValueType && (p.transformer is PrimitiveValueTransformer)) { return(false); } return(true); }; } else { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) { return(false); } return(true); }; } RandomPlansResult r; if (!RandomPlans(out r, methodArgumentTypes, f, planManager.builderPlans, forbidNull, method)) { stats.CreatedNew(CreationResult.NoInputs); return; } //Console.WriteLine("\t\t A plan has been created"); Plan plan = new Plan(MethodCall.Get(method), r.fplans, r.fparameterChoosers); planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
/// <summary> /// Tries to construct a new plan that calls a method on a /// receiver of the type given. May fail if there are no /// applicable methods or receivers available. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewMethodPlan(Type type, MethodInfo method, PlanManager planManager, bool forbidNull, Type[] methodArgumentTypes) { stats.Selected(MethodCall.Get(method).ToString()); PlanFilter f; if (forbidNull) { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) { return(false); } //// Non-null heuristic [email protected] //if (!methodArgumentTypes[i].IsValueType && (p.transformer is PrimitiveValueTransformer)) // return false; return(true); }; } else { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) { return(false); } return(true); }; } if (!RandomPlans(out RandomPlansResult randomPlansResult, methodArgumentTypes, f, planManager.builderPlans, forbidNull, method)) { stats.CreatedNew(CreationResult.NoInputs); return; } //Logger.Debug("\t\t A plan has been created"); Plan plan = new Plan(MethodCall.Get(method), randomPlansResult.fplans, randomPlansResult.fparameterChoosers); plan.ClassName = method.DeclaringType.Name; planManager.AddMaybeExecutingIfNeeded(plan, stats); }
private void ExploreMemberInternal(ITimer timer, PlanManager planManager, bool forbidNull, MemberInfo m) { Type[] sugg = GetParameterTypeSuggestions(m, planManager); if (m is ConstructorInfo) { NewConstructorPlan((m as ConstructorInfo).DeclaringType, m as ConstructorInfo, planManager, forbidNull, sugg); } else { Util.Assert(m is MethodInfo); NewMethodPlan((m as MethodInfo).DeclaringType, m as MethodInfo, planManager, forbidNull, sugg); } }
/// <summary> /// Tries to construct a new plan that calls a constructor /// of the type given. May fail if there are no /// applicable constructors. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewConstructorPlan(Type type, ConstructorInfo constructor, PlanManager planManager, bool forbidNull, Type[] constructorArgumentTypes) { this.stats.Selected(ConstructorCallTransformer.Get(constructor).ToString()); PlanFilter f; if (forbidNull) { f = delegate(Plan p, int i) { // Non-null heuristic if (!constructorArgumentTypes[i].IsValueType && (p.transformer is PrimitiveValueTransformer)) { return(false); } return(true); }; } else { f = delegate(Plan p, int i) { return(true); }; } RandomPlansResult r; if (!RandomPlans(out r, constructorArgumentTypes, f, planManager.builderPlans, forbidNull, null)) { stats.CreatedNew(CreationResult.NoInputs); return; } Plan plan = new Plan(ConstructorCallTransformer.Get(constructor), r.fplans, r.fparameterChoosers); plan.ClassName = constructor.DeclaringType.Name; planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
/// <summary> /// Note that Explore can silently fail (exits with 1), if a second chance AV happens /// </summary> /// <param name="timer"></param> /// <param name="planManager"></param> /// <param name="methodWeigthing"></param> /// <param name="forbidNull"></param> /// <param name="mutateFields"></param> public void Explore(ITimer timer, PlanManager planManager, MethodWeighing methodWeigthing, bool forbidNull, bool mutateFields, bool fairOpt) { int currentPlans = planManager.Plans; int currentRedundantAdds = planManager.RedundantAdds; // Start timing test generation. Timer.QueryPerformanceCounter(ref TimeTracking.generationStartTime); //exercise the fair option if (fairOpt) { Console.WriteLine("Using the fair option ...."); //fairOptLog = new StreamWriter("Randoop.fairopt.log"); //compute the initial working set and the active methods for each class InitializeActiveMemberAndDependency(planManager); for (; ;) { //field setting if (mutateFields && this.actions.fieldList.Count > 0 && Common.Enviroment.Random.Next(2) == 0) { NewFieldSettingPlan(this.actions.RandomField(), planManager, forbidNull); } //If the active set is recomputed from scratch //InitializeActiveMemberAndDependency(planManager); //copy the keys Dictionary <Type, bool> .KeyCollection keys = new Dictionary <Type, bool> .KeyCollection(activeTypes); List <Type> activeList = new List <Type>(); foreach (Type t in keys) { activeList.Add(t); } RandoopPrintFairStats("Randoop.RandomExplore::Explore", "Starting a round of the fair workset algorithm with " + activeTypes.Count + "activeTypes"); foreach (Type t in activeList) { //pick up an active method of the type MemberInfo m; try { m = this.actions.RandomActiveMethodorConstructor(activeMembers, t); } catch (Exception e) { Console.WriteLine("Exception raised from RandomActiveMethodorConstructor is {0}", e.ToString()); continue; } //Console.WriteLine("Picked up method {0}::{1}", m.DeclaringType,m.Name ); int prevBuilderPlanCnt = planManager.builderPlans.NumPlans; //Randoop step ExploreMemberInternal(timer, planManager, forbidNull, m); //need to know if the object creation was succesful, since we know the type //we do it indirectly by looking at the builder plans if (planManager.builderPlans.NumPlans > prevBuilderPlanCnt) { Type retType; if (m is MethodInfo) { retType = (m as MethodInfo).ReturnType; } else if (m is ConstructorInfo) { retType = (m as ConstructorInfo).DeclaringType; } else { throw new RandoopBug("Constructor or Method expected"); } //use the return type of the method/constructor to incrementally activate more methods/classes try { UpdateActiveMethodsAndClasses(retType); } catch (Exception e) // had a nasty bug in the updateActiveMethodsAndClasses, so using try-catch { Console.WriteLine("Exception raised from UpdateActiveMethodsAndClasses is {0}", e.ToString()); } } if (timer.TimeToStop()) { //get the size of # of active members int size = 0; foreach (KeyValuePair <Type, List <MemberInfo> > kv in activeMembers) { List <MemberInfo> l = kv.Value; size = size + l.Count; } //stats printing Console.WriteLine("Finishing the fair exploration...printing activity stats"); Console.WriteLine("Stats: <#ActiveTypes, #ActiveMembers, #BuilderPlans, #typesWithObjs> = <{0},{1},{2},{3}>", activeTypes.Count, size, planManager.builderPlans.NumPlans, typesWithObjects.Count); //fairOptLog.Close(); return; } } } } else { #region Old code for the Randoop exploration for (; ;) { //field setting if (mutateFields && this.actions.fieldList.Count > 0 && Common.Enviroment.Random.Next(2) == 0) { NewFieldSettingPlan(this.actions.RandomField(), planManager, forbidNull); } MemberInfo m; if (methodWeigthing == MethodWeighing.RoundRobin) { m = this.actions.RandomMethodOrConstructorRoundRobin(); } else if (methodWeigthing == MethodWeighing.Uniform) { m = this.actions.RandomMethodOrConstructorUniform(); } else { throw new RandoopBug("Unrecognized method weighting option."); } ExploreMemberInternal(timer, planManager, forbidNull, m); if (timer.TimeToStop()) { // this computation gives us the activity stats for the non-fair option InitializeActiveMemberAndDependency(planManager); //get the size of # of active members int size = 0; foreach (KeyValuePair <Type, List <MemberInfo> > kv in activeMembers) { List <MemberInfo> l = kv.Value; size = size + l.Count; } //stats printing Console.WriteLine("Finishing the non-fair exploration...printing activity stats"); Console.WriteLine("Stats: <#ActiveTypes, #ActiveMembers, #BuilderPlans, #typesWithObjs> = <{0},{1},{2},{3}>", activeTypes.Count, size, planManager.builderPlans.NumPlans, typesWithObjects.Count); //fairOptLog.Close(); return; } } #endregion } }
/// <summary> /// Initializes the data structures for Active members, types, and the dependency of methods on types /// </summary> /// <param name="planManager"></param> /// /// private void InitializeActiveMemberAndDependency(PlanManager planManager) { //reset all the maps activeMembers.Clear(); activeTypes.Clear(); typesWithObjects.Clear(); member2pendingTypes.Clear(); type2pendingMembers.Clear(); //get the set of types for which the builderPlans can create an object Dictionary <Plan, bool> .KeyCollection plans = planManager.builderPlans.planSet.Keys; //we simply look at the return type of the last method of each builder plan. This is sufficient //because any intermediate method in a plan will appear as the last method of some prefix plan //in the builder plan database foreach (Plan plan in plans) { Transformer tr = plan.transformer; Type t; if (tr is MethodCall) { t = (tr as MethodCall).method.ReturnType; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Method]" + t.ToString() + " class is ACTIVE"); } else if (tr is ConstructorCallTransformer) { t = (tr as ConstructorCallTransformer).fconstructor.DeclaringType; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Constructor]" + t.ToString() + " class is ACTIVE"); } else if (tr is PrimitiveValueTransformer) //for primitive values and string { t = (tr as PrimitiveValueTransformer).ftype; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Constant]" + t.ToString() + " class is ACTIVE"); } else { //TODO: ignoring field setters and Array constructors } } //we are only going to try to activate the non-filtered types/methods only foreach (ConstructorInfo ci in actions.GetConstructors()) { bool activeMember = true; ParameterInfo[] args = ci.GetParameters(); //check if all the arguments can be provided an object for (int i = 0; i < args.Length; ++i) { ParameterInfo pi = args[i]; if (!typesWithObjects.ContainsKey(pi.ParameterType)) { RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + pi.ParameterType + "for constructor <" + ci.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List <Type> output; member2pendingTypes.TryGetValue(ci, out output); if (output == null) { List <Type> l = new List <Type>(); l.Add(pi.ParameterType); member2pendingTypes[ci] = l; } else if (!output.Contains(pi.ParameterType)) { member2pendingTypes[ci].Add(pi.ParameterType); } //compute the dependency of type --> methods List <MemberInfo> members; type2pendingMembers.TryGetValue(pi.ParameterType, out members); if (members == null) { List <MemberInfo> l = new List <MemberInfo>(); l.Add(ci); type2pendingMembers[pi.ParameterType] = l; } else if (!members.Contains(ci)) { type2pendingMembers[pi.ParameterType].Add(ci); } } } if (activeMember) // add it to the active member set and update active types { Type ti = ci.DeclaringType; List <MemberInfo> memberList; activeMembers.TryGetValue(ti, out memberList); if (memberList == null) { memberList = new List <MemberInfo>(); memberList.Add(ci); activeMembers[ti] = memberList; } else { //there can't be any repeats activeMembers[ti].Add(ci); } //activate the type activeTypes[ti] = true; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Adding <ActiveType, ActiveMember>: <" + ti.ToString() + "," + ci.ToString() + ">"); } } foreach (MethodInfo mi in actions.GetMethods()) { bool activeMember = true; //receiver is treated separately if (!typesWithObjects.ContainsKey(mi.DeclaringType)) { Type ti = mi.DeclaringType; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + ti + "for method <" + mi.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List <Type> output; member2pendingTypes.TryGetValue(mi, out output); if (output == null) { List <Type> l = new List <Type>(); l.Add(ti); member2pendingTypes[mi] = l; } else if (!output.Contains(ti)) { member2pendingTypes[mi].Add(ti); } //compute the dependency of type --> methods List <MemberInfo> memberList; type2pendingMembers.TryGetValue(ti, out memberList); if (memberList == null) { List <MemberInfo> l = new List <MemberInfo>(); l.Add(mi); type2pendingMembers[ti] = l; } else if (!memberList.Contains(mi)) { type2pendingMembers[ti].Add(mi); } } //check if all the arguments can be provided an object ParameterInfo[] args = mi.GetParameters(); for (int i = 0; i < args.Length; ++i) { ParameterInfo pi = args[i]; if (!typesWithObjects.ContainsKey(pi.ParameterType)) { RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + pi.ParameterType + "for method <" + mi.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List <Type> output; member2pendingTypes.TryGetValue(mi, out output); if (output == null) { List <Type> l = new List <Type>(); l.Add(pi.ParameterType); member2pendingTypes[mi] = l; } else if (!output.Contains(pi.ParameterType)) { member2pendingTypes[mi].Add(pi.ParameterType); } //compute the dependency of type --> methods List <MemberInfo> members; type2pendingMembers.TryGetValue(pi.ParameterType, out members); if (members == null) { List <MemberInfo> l = new List <MemberInfo>(); l.Add(mi); type2pendingMembers[pi.ParameterType] = l; } else if (!members.Contains(mi)) { type2pendingMembers[pi.ParameterType].Add(mi); } } } if (activeMember) { Type ti = mi.DeclaringType; List <MemberInfo> memberList; activeMembers.TryGetValue(ti, out memberList); if (memberList == null) { memberList = new List <MemberInfo>(); memberList.Add(mi); activeMembers[ti] = memberList; } else { //there can't be any repeats activeMembers[ti].Add(mi); } //activate the type activeTypes[ti] = true; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Adding <ActiveType, ActiveMember>: <" + ti.ToString() + "," + mi.ToString() + ">"); } } }
private static void Main2(string[] args) { if (args.Length != 1) { throw new InvalidUserParamsException( "RandoopBare takes exactly one argument but was " + "given the following arguments:" + System.Environment.NewLine + Util.PrintArray(args));; } // Parse XML file with generation parameters. String configFileName = Common.ConfigFileName.Parse(args[0]); RandoopConfiguration config = LoadConfigFile(configFileName); // Set the random number generator. if (config.randomSource == RandomSource.SystemRandom) { Console.WriteLine("Randoom seed = " + config.randomseed); Common.SystemRandom random = new Common.SystemRandom(); random.Init(config.randomseed); Common.Enviroment.Random = random; } else { Util.Assert(config.randomSource == RandomSource.Crypto); Console.WriteLine("Randoom seed = new System.Security.Cryptography.RNGCryptoServiceProvider()"); Common.Enviroment.Random = new CryptoRandom(); } if (!Directory.Exists(config.outputdir)) throw new Common.RandoopBareExceptions.InvalidUserParamsException("output directory does not exist: " + config.outputdir); Collection<Assembly> assemblies = Common.Misc.LoadAssemblies(config.assemblies); ////[email protected] for substituting MessageBox.Show() - start ////Instrument instrumentor = new Instrument(); //foreach (FileName asm in config.assemblies) //{ // Instrument.MethodInstrument(asm.fileName, "System.Windows.Forms.MessageBox::Show", "System.Console.Writeline"); //} ////[email protected] for substituting MessageBox.Show() - end IReflectionFilter filter1 = new VisibilityFilter(config); ConfigFilesFilter filter2 = new ConfigFilesFilter(config); Console.WriteLine("========== REFLECTION PATTERNS:"); filter2.PrintFilter(Console.Out); IReflectionFilter filter = new ComposableFilter(filter1, filter2); Collection<Type> typesToExplore = ReflectionUtils.GetExplorableTypes(assemblies); PlanManager planManager = new PlanManager(config); planManager.builderPlans.AddEnumConstantsToPlanDB(typesToExplore); planManager.builderPlans.AddConstantsToTDB(config); Console.WriteLine("========== INITIAL PRIMITIVE VALUES:"); planManager.builderPlans.PrintPrimitives(Console.Out); StatsManager stats = new StatsManager(config); Console.WriteLine("Analyzing assembly."); ActionSet actions = null; try { actions = new ActionSet(typesToExplore, filter); } catch (EmpytActionSetException) { string msg = "After filtering based on configuration files, no remaining methods or constructors to explore."; throw new Common.RandoopBareExceptions.InvalidUserParamsException(msg); } Console.WriteLine(); Console.WriteLine("Generating tests."); RandomExplorer explorer = new RandomExplorer(typesToExplore, filter, true, config.randomseed, config.arraymaxsize, stats, actions); ITimer t = new Timer(config.timelimit); try { explorer.Explore(t, planManager, config.methodweighing, config.forbidnull, true, config.fairOpt); } catch (Exception e) { Console.WriteLine("Explorer raised exception {0}", e.ToString()); } //Mono.Cecil.Cil. }
/// <summary> /// Note that Explore can silently fail (exits with 1), if a second chance AV happens /// </summary> /// <param name="timer"></param> /// <param name="planManager"></param> /// <param name="methodWeigthing"></param> /// <param name="forbidNull"></param> /// <param name="mutateFields"></param> public void Explore(ITimer timer, PlanManager planManager, MethodWeighing methodWeigthing, bool forbidNull, bool mutateFields, bool fairOpt) { int currentPlans = planManager.Plans; int currentRedundantAdds = planManager.RedundantAdds; // Start timing test generation. Timer.QueryPerformanceCounter(ref TimeTracking.generationStartTime); //exercise the fair option if (fairOpt) { Console.WriteLine("Using the fair option ...."); //fairOptLog = new StreamWriter("Randoop.fairopt.log"); //compute the initial working set and the active methods for each class InitializeActiveMemberAndDependency(planManager); for (; ; ) { //field setting if (mutateFields && this.actions.fieldList.Count > 0 && Common.Enviroment.Random.Next(2) == 0) NewFieldSettingPlan(this.actions.RandomField(), planManager, forbidNull); //If the active set is recomputed from scratch //InitializeActiveMemberAndDependency(planManager); //copy the keys Dictionary<Type, bool>.KeyCollection keys = new Dictionary<Type, bool>.KeyCollection(activeTypes); List<Type> activeList = new List<Type>(); foreach (Type t in keys) activeList.Add(t); RandoopPrintFairStats("Randoop.RandomExplore::Explore", "Starting a round of the fair workset algorithm with " + activeTypes.Count + "activeTypes"); foreach (Type t in activeList) { //pick up an active method of the type MemberInfo m; try { m = this.actions.RandomActiveMethodorConstructor(activeMembers, t); } catch (Exception e) { Console.WriteLine("Exception raised from RandomActiveMethodorConstructor is {0}", e.ToString()); continue; } //Console.WriteLine("Picked up method {0}::{1}", m.DeclaringType,m.Name ); int prevBuilderPlanCnt = planManager.builderPlans.NumPlans; //Randoop step ExploreMemberInternal(timer, planManager, forbidNull, m); //need to know if the object creation was succesful, since we know the type //we do it indirectly by looking at the builder plans if (planManager.builderPlans.NumPlans > prevBuilderPlanCnt) { Type retType; if (m is MethodInfo) { retType = (m as MethodInfo).ReturnType; } else if (m is ConstructorInfo) { retType = (m as ConstructorInfo).DeclaringType; } else { throw new RandoopBug("Constructor or Method expected"); } //use the return type of the method/constructor to incrementally activate more methods/classes try { UpdateActiveMethodsAndClasses(retType); } catch (Exception e) // had a nasty bug in the updateActiveMethodsAndClasses, so using try-catch { Console.WriteLine("Exception raised from UpdateActiveMethodsAndClasses is {0}", e.ToString()); } } if (timer.TimeToStop()) { //get the size of # of active members int size = 0; foreach (KeyValuePair<Type, List<MemberInfo>> kv in activeMembers) { List<MemberInfo> l = kv.Value; size = size + l.Count; } //stats printing Console.WriteLine("Finishing the fair exploration...printing activity stats"); Console.WriteLine("Stats: <#ActiveTypes, #ActiveMembers, #BuilderPlans, #typesWithObjs> = <{0},{1},{2},{3}>", activeTypes.Count, size, planManager.builderPlans.NumPlans, typesWithObjects.Count); //fairOptLog.Close(); return; } } } } else { #region Old code for the Randoop exploration for (; ; ) { //field setting if (mutateFields && this.actions.fieldList.Count > 0 && Common.Enviroment.Random.Next(2) == 0) NewFieldSettingPlan(this.actions.RandomField(), planManager, forbidNull); MemberInfo m; if (methodWeigthing == MethodWeighing.RoundRobin) { m = this.actions.RandomMethodOrConstructorRoundRobin(); } else if (methodWeigthing == MethodWeighing.Uniform) { m = this.actions.RandomMethodOrConstructorUniform(); } else throw new RandoopBug("Unrecognized method weighting option."); ExploreMemberInternal(timer, planManager, forbidNull, m); if (timer.TimeToStop()) { // this computation gives us the activity stats for the non-fair option InitializeActiveMemberAndDependency(planManager); //get the size of # of active members int size = 0; foreach (KeyValuePair<Type, List<MemberInfo>> kv in activeMembers) { List<MemberInfo> l = kv.Value; size = size + l.Count; } //stats printing Console.WriteLine("Finishing the non-fair exploration...printing activity stats"); Console.WriteLine("Stats: <#ActiveTypes, #ActiveMembers, #BuilderPlans, #typesWithObjs> = <{0},{1},{2},{3}>", activeTypes.Count, size, planManager.builderPlans.NumPlans, typesWithObjects.Count); //fairOptLog.Close(); return; } } #endregion } }
/// <summary> /// Tries to construct a new plan that sets a field for a /// receiver of the type given. May fail if there are no /// applicable receivers. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewFieldSettingPlan(FieldInfo field, PlanManager planManager, bool forbidNull) { this.stats.Selected(FieldSettingTransformer.Get(field).ToString()); Type[] parameterTypes = new Type[2]; parameterTypes[0] = field.DeclaringType; parameterTypes[1] = field.FieldType; RandomPlansResult r; if (!RandomPlans(out r, parameterTypes, delegate(Plan p, int i) { if (i == 0 && p.transformer is PrimitiveValueTransformer) return false; return true; }, planManager.builderPlans, forbidNull, null)) { stats.CreatedNew(CreationResult.NoInputs); return; } Plan plan = new Plan(FieldSettingTransformer.Get(field), r.fplans, r.fparameterChoosers); planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
/// <summary> /// Tries to construct a new plan that calls a constructor /// of the type given. May fail if there are no /// applicable constructors. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewConstructorPlan(Type type, ConstructorInfo constructor, PlanManager planManager, bool forbidNull, Type[] constructorArgumentTypes) { this.stats.Selected(ConstructorCallTransformer.Get(constructor).ToString()); PlanFilter f; if (forbidNull) { f = delegate(Plan p, int i) { // Non-null heuristic if (!constructorArgumentTypes[i].IsValueType && (p.transformer is PrimitiveValueTransformer)) return false; return true; }; } else { f = delegate(Plan p, int i) { return true; }; } RandomPlansResult r; if (!RandomPlans(out r, constructorArgumentTypes, f, planManager.builderPlans, forbidNull, null)) { stats.CreatedNew(CreationResult.NoInputs); return; } Plan plan = new Plan(ConstructorCallTransformer.Get(constructor), r.fplans, r.fparameterChoosers); planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
/// <summary> /// Tries to construct a new plan that calls a method on a /// receiver of the type given. May fail if there are no /// applicable methods or receivers available. /// </summary> /// <param name="type"></param> /// <param name="plan"></param> /// <returns></returns> private void NewMethodPlan(Type type, MethodInfo method, PlanManager planManager, bool forbidNull, Type[] methodArgumentTypes) { this.stats.Selected(MethodCall.Get(method).ToString()); PlanFilter f; if (forbidNull) { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) return false; // Non-null heuristic if (!methodArgumentTypes[i].IsValueType && (p.transformer is PrimitiveValueTransformer)) return false; return true; }; } else { f = delegate(Plan p, int i) { if (!method.IsStatic && i == 0 && p.transformer is PrimitiveValueTransformer) return false; return true; }; } RandomPlansResult r; if (!RandomPlans(out r, methodArgumentTypes, f, planManager.builderPlans, forbidNull, method)) { stats.CreatedNew(CreationResult.NoInputs); return; } //Console.WriteLine("\t\t A plan has been created"); Plan plan = new Plan(MethodCall.Get(method), r.fplans, r.fparameterChoosers); planManager.AddMaybeExecutingIfNeeded(plan, this.stats); }
// For methods, it only picks receiver of type m.methodInfo.DeclaringType. private Type[] GetParameterTypeSuggestions(MemberInfo m, PlanManager planManager) { if (m is ConstructorInfo) { ConstructorInfo constructor = m as ConstructorInfo; ParameterInfo[] constructorParameters = constructor.GetParameters(); Type[] constructorArgumentTypes = new Type[constructorParameters.Length]; for (int i = 0; i < constructorParameters.Length; i++) constructorArgumentTypes[i] = constructorParameters[i].ParameterType; return constructorArgumentTypes; } else { Util.Assert(m is MethodInfo); MethodInfo method = m as MethodInfo; ParameterInfo[] methodParameters = method.GetParameters(); Type[] methodArgumentTypes = new Type[methodParameters.Length]; for (int i = 0; i < methodParameters.Length; i++) methodArgumentTypes[i] = methodParameters[i].ParameterType; Type[] oneResult = new Type[methodArgumentTypes.Length + 1]; oneResult[0] = method.DeclaringType; Array.Copy(methodArgumentTypes, 0, oneResult, 1, methodArgumentTypes.Length); return oneResult; } }
/// <summary> /// Initializes the data structures for Active members, types, and the dependency of methods on types /// </summary> /// <param name="planManager"></param> /// /// private void InitializeActiveMemberAndDependency(PlanManager planManager) { //reset all the maps activeMembers.Clear(); activeTypes.Clear(); typesWithObjects.Clear(); member2pendingTypes.Clear(); type2pendingMembers.Clear(); //get the set of types for which the builderPlans can create an object Dictionary<Plan, bool>.KeyCollection plans = planManager.builderPlans.planSet.Keys; //we simply look at the return type of the last method of each builder plan. This is sufficient //because any intermediate method in a plan will appear as the last method of some prefix plan //in the builder plan database foreach (Plan plan in plans) { Transformer tr = plan.transformer; Type t; if (tr is MethodCall) { t = (tr as MethodCall).method.ReturnType; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Method]" + t.ToString() + " class is ACTIVE"); } else if (tr is ConstructorCallTransformer) { t = (tr as ConstructorCallTransformer).fconstructor.DeclaringType; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Constructor]" + t.ToString() + " class is ACTIVE"); } else if (tr is PrimitiveValueTransformer) //for primitive values and string { t = (tr as PrimitiveValueTransformer).ftype; typesWithObjects[t] = true; RandoopPrintFairStats("InitializeActiveMemberDependency", "[Constant]" + t.ToString() + " class is ACTIVE"); } else { //TODO: ignoring field setters and Array constructors } } //we are only going to try to activate the non-filtered types/methods only foreach (ConstructorInfo ci in actions.GetConstructors()) { bool activeMember = true; ParameterInfo[] args = ci.GetParameters(); //check if all the arguments can be provided an object for (int i = 0; i < args.Length; ++i) { ParameterInfo pi = args[i]; if (!typesWithObjects.ContainsKey(pi.ParameterType)) { RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + pi.ParameterType + "for constructor <" + ci.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List<Type> output; member2pendingTypes.TryGetValue(ci, out output); if (output == null) { List<Type> l = new List<Type>(); l.Add(pi.ParameterType); member2pendingTypes[ci] = l; } else if (!output.Contains(pi.ParameterType)) { member2pendingTypes[ci].Add(pi.ParameterType); } //compute the dependency of type --> methods List<MemberInfo> members; type2pendingMembers.TryGetValue(pi.ParameterType, out members); if (members == null) { List<MemberInfo> l = new List<MemberInfo>(); l.Add(ci); type2pendingMembers[pi.ParameterType] = l; } else if (!members.Contains(ci)) { type2pendingMembers[pi.ParameterType].Add(ci); } } } if (activeMember) // add it to the active member set and update active types { Type ti = ci.DeclaringType; List<MemberInfo> memberList; activeMembers.TryGetValue(ti, out memberList); if (memberList == null) { memberList = new List<MemberInfo>(); memberList.Add(ci); activeMembers[ti] = memberList; } else { //there can't be any repeats activeMembers[ti].Add(ci); } //activate the type activeTypes[ti] = true; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Adding <ActiveType, ActiveMember>: <" + ti.ToString() + "," + ci.ToString() + ">"); } } foreach (MethodInfo mi in actions.GetMethods()) { bool activeMember = true; //receiver is treated separately if (!typesWithObjects.ContainsKey(mi.DeclaringType)) { Type ti = mi.DeclaringType; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + ti + "for method <" + mi.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List<Type> output; member2pendingTypes.TryGetValue(mi, out output); if (output == null) { List<Type> l = new List<Type>(); l.Add(ti); member2pendingTypes[mi] = l; } else if (!output.Contains(ti)) { member2pendingTypes[mi].Add(ti); } //compute the dependency of type --> methods List<MemberInfo> memberList; type2pendingMembers.TryGetValue(ti, out memberList); if (memberList == null) { List<MemberInfo> l = new List<MemberInfo>(); l.Add(mi); type2pendingMembers[ti] = l; } else if (!memberList.Contains(mi)) { type2pendingMembers[ti].Add(mi); } } //check if all the arguments can be provided an object ParameterInfo[] args = mi.GetParameters(); for (int i = 0; i < args.Length; ++i) { ParameterInfo pi = args[i]; if (!typesWithObjects.ContainsKey(pi.ParameterType)) { RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Can't find argument of type" + pi.ParameterType + "for method <" + mi.ToString() + ">"); activeMember = false; //compute the dependency of method --> pending types List<Type> output; member2pendingTypes.TryGetValue(mi, out output); if (output == null) { List<Type> l = new List<Type>(); l.Add(pi.ParameterType); member2pendingTypes[mi] = l; } else if (!output.Contains(pi.ParameterType)) { member2pendingTypes[mi].Add(pi.ParameterType); } //compute the dependency of type --> methods List<MemberInfo> members; type2pendingMembers.TryGetValue(pi.ParameterType, out members); if (members == null) { List<MemberInfo> l = new List<MemberInfo>(); l.Add(mi); type2pendingMembers[pi.ParameterType] = l; } else if (!members.Contains(mi)) { type2pendingMembers[pi.ParameterType].Add(mi); } } } if (activeMember) { Type ti = mi.DeclaringType; List<MemberInfo> memberList; activeMembers.TryGetValue(ti, out memberList); if (memberList == null) { memberList = new List<MemberInfo>(); memberList.Add(mi); activeMembers[ti] = memberList; } else { //there can't be any repeats activeMembers[ti].Add(mi); } //activate the type activeTypes[ti] = true; RandoopPrintFairStats("InitializeActiveMemberAndDependency", "Adding <ActiveType, ActiveMember>: <" + ti.ToString() + "," + mi.ToString() + ">"); } } }