66import java .io .FileWriter ;
77import java .io .IOException ;
88import java .io .InputStreamReader ;
9+ import java .util .ArrayList ;
910import java .util .HashMap ;
1011import java .util .List ;
1112import java .util .Set ;
@@ -39,15 +40,17 @@ public static void main(String[] args) {
3940 // System.out.println(finalTime);
4041 // System.out.println(finalTime-initialTime);
4142
43+ } catch (NumberFormatException e ) {
44+ System .out .println ("Amount of mutants parameter is not a number!" );
4245 } catch (Exception e ) {
4346 // TODO Auto-generated catch block
4447 e .printStackTrace ();
4548 }
4649 }
4750
48- public static void runMutAPK (String [] args ) throws Exception {
51+ public static void runMutAPK (String [] args ) throws NumberFormatException , Exception {
4952 //Usage Error
50- if (args .length != 6 ) {
53+ if (args .length < 6 ) {
5154 System .out .println ("******* ERROR: INCORRECT USAGE *******" );
5255 System .out .println ("Argument List:" );
5356 System .out .println ("1. APK path" );
@@ -56,9 +59,10 @@ public static void runMutAPK(String[] args) throws Exception {
5659 System .out .println ("4. Binaries path" );
5760 System .out .println ("5. Directory containing the operator.properties file" );
5861 System .out .println ("6. Multithread generation (true/false)" );
62+ System .out .println ("7. OPTIONAL Amount of mutants" );
5963 return ;
6064 }
61-
65+
6266 //Getting arguments
6367 String apkName ;
6468 String apkPath = args [0 ];
@@ -67,8 +71,12 @@ public static void runMutAPK(String[] args) throws Exception {
6771 String extraPath = args [3 ];
6872 String operatorsDir = args [4 ];
6973 boolean multithread = Boolean .parseBoolean (args [5 ]);
74+ int amountMutants = -1 ;
75+ if (args .length >6 ) {
76+ amountMutants = Integer .parseInt (args [6 ]);
77+ }
78+
7079
71-
7280 // Fix params based in OS
7381 String os = System .getProperty ("os.name" ).toLowerCase ();
7482 if (os .indexOf ("win" ) >= 0 ) {
@@ -79,21 +87,26 @@ public static void runMutAPK(String[] args) throws Exception {
7987 } else {
8088 apkName = apkPath .substring (apkPath .lastIndexOf ("/" ));
8189 }
90+ //Read selected operators
91+ OperatorBundle operatorBundle = new OperatorBundle (operatorsDir );
92+ System .out .println (operatorBundle .printSelectedOperators ());
93+
94+ if (amountMutants >0 && operatorBundle .getAmountOfSelectedOperators ()>amountMutants ) {
95+ throw new Exception ("You must select as many mutants as selected operators, right now you select " +operatorBundle .getAmountOfSelectedOperators ()+" operators but only ask for " +amountMutants +" mutants" );
96+ }
97+
8298 Helper .getInstance ();
8399 Helper .setPackageName (appName );
84100 // Decode the APK
85101 APKToolWrapper .openAPK (apkPath , extraPath );
86102
87- //Read selected operators
88- OperatorBundle operatorBundle = new OperatorBundle (operatorsDir );
89- System .out .println (operatorBundle .printSelectedOperators ());
90103
91104 //Text-Based operators selected
92105 List <MutationLocationDetector > textBasedDetectors = operatorBundle .getTextBasedDetectors ();
93-
106+
94107 //1. Run detection phase for Text-based detectors
95108 HashMap <MutationType , List <MutationLocation >> locations = TextBasedDetectionsProcessor .process ("temp" , textBasedDetectors );
96-
109+
97110
98111 // //2. Run detection phase for AST-based detectors
99112 // //2.1 Preprocessing: Find locations to target API calls (including calls to constructors)
@@ -102,24 +115,30 @@ public static void runMutAPK(String[] args) throws Exception {
102115 locations .putAll ( scp .processFolder ("temp" , extraPath , appName ));
103116
104117 // //2.2. Call the detectors on each location in order to find any extra information required for each case.
105- // locations = scp.findExtraInfoRequired(locations);
118+ // locations = scp.findExtraInfoRequired(locations);
106119
107120 Set <MutationType > keys = locations .keySet ();
108121 List <MutationLocation > list = null ;
109122 System .out .println ("Amount Mutants Mutation Operator" );
110123 for (MutationType mutationType : keys ) {
111124 list = locations .get (mutationType );
112125 System .out .println (list .size ()+" " +mutationType );
113- // for (MutationLocation mutationLocation : list) {
114- // System.out.println("File: "+mutationLocation.getFilePath()+", start line:" + mutationLocation.getStartLine()+", end line: "+mutationLocation.getEndLine()+", start column"+mutationLocation.getStartColumn());
115- // }
126+ // for (MutationLocation mutationLocation : list) {
127+ // System.out.println("File: "+mutationLocation.getFilePath()+", start line:" + mutationLocation.getStartLine()+", end line: "+mutationLocation.getEndLine()+", start column"+mutationLocation.getStartColumn());
128+ // }
116129 }
117-
130+
118131 //3. Build MutationLocation List
119132 List <MutationLocation > mutationLocationList = MutationLocationListBuilder .buildList (locations );
120133 printLocationList (mutationLocationList , mutantsFolder , appName );
121134 System .out .println ("Total Locations: " +mutationLocationList .size ());
122135
136+ if (amountMutants >0 ) {
137+ System .out .println ("We have found: " +mutationLocationList .size ()+" possible mutation points, we are going to select " +amountMutants +" of those" );
138+ mutationLocationList = selectMutants (amountMutants , locations );
139+ System .out .println (mutationLocationList .size ());
140+ }
141+
123142 //3. Run mutation phase
124143 MutationsProcessor mProcessor = new MutationsProcessor ("temp" , appName , mutantsFolder );
125144
@@ -131,8 +150,37 @@ public static void runMutAPK(String[] args) throws Exception {
131150
132151 }
133152
153+ private static List <MutationLocation > selectMutants (int amountMutants , HashMap <MutationType , List <MutationLocation >> locations ) {
154+
155+ HashMap <MutationType , List <MutationLocation >> newLocations = new HashMap <MutationType , List <MutationLocation >>();
156+ HashMap <MutationType , List <MutationLocation >> tempLocations = locations ;
157+ int newAmountMutants = amountMutants ;
158+
159+ for (MutationType key : tempLocations .keySet ()) {
160+ if (tempLocations .get (key ).size ()>0 ) {
161+ int selectedMutantNumber = (int )Math .random ()*tempLocations .get (key ).size ();
162+ MutationLocation selectedMutant = tempLocations .get (key ).get (selectedMutantNumber );
163+ ArrayList temp = new ArrayList <MutationLocation >();
164+ temp .add (selectedMutant );
165+ newLocations .put (key , temp );
166+ tempLocations .get (key ).remove (selectedMutantNumber );
167+ newAmountMutants --;
168+ }
169+ }
170+ List <MutationLocation > mutationLocationList = MutationLocationListBuilder .buildList (tempLocations );
171+ List <MutationLocation > newMutationLocationList = MutationLocationListBuilder .buildList (newLocations );
172+
173+ for (int i = 0 ; i < newAmountMutants ; i ++) {
174+ int selectedMutantNumber = (int )Math .random ()*mutationLocationList .size ();
175+ MutationLocation selectedMutant = mutationLocationList .get (selectedMutantNumber );
176+ newMutationLocationList .add (selectedMutant );
177+ mutationLocationList .remove (selectedMutantNumber );
178+ }
179+ return newMutationLocationList ;
180+ }
181+
134182 private static void printLocationList (List <MutationLocation > mutationLocationList , String mutantsFolder , String appName ) {
135-
183+
136184 try {
137185 BufferedWriter writer = new BufferedWriter (
138186 new FileWriter (mutantsFolder + File .separator + appName + "-locations.json" ));
@@ -173,7 +221,7 @@ private static void printLocationList(List<MutationLocation> mutationLocationLis
173221 // TODO Auto-generated catch block
174222 e .printStackTrace ();
175223 }
176-
224+
177225 }
178226
179227}
0 commit comments