├── VERSION ├── src ├── dist │ └── template │ │ ├── project │ │ ├── APP_TYPE │ │ ├── FRAMES_COUNT │ │ ├── settings.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── increment-deployment.sh │ │ ├── build.gradle │ │ ├── src │ │ │ └── main │ │ │ │ ├── resources │ │ │ │ └── logback.xml │ │ │ │ └── java │ │ │ │ └── helpers │ │ │ │ ├── BullshifierException.java │ │ │ │ ├── StickyPathHelper.java │ │ │ │ ├── Context.java │ │ │ │ ├── EventsSpot.java │ │ │ │ ├── Config.java │ │ │ │ ├── StatsReporter.java │ │ │ │ ├── MyServlet.java │ │ │ │ └── Main.java │ │ ├── gradlew.bat │ │ ├── params.sh │ │ ├── run.sh │ │ └── gradlew │ │ └── multiproject │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── build.gradle │ │ ├── gradlew.bat │ │ ├── gradlew │ │ └── root │ │ └── src │ │ └── main │ │ └── java │ │ └── helpers │ │ └── MultiMain.java └── main │ ├── groovy │ └── generator │ │ ├── GradleGenerator.groovy │ │ ├── GradleSettingsGenerator.groovy │ │ ├── BashRunnerGenerator.groovy │ │ ├── MultiSwitcherGenerator.groovy │ │ ├── Config.groovy │ │ ├── LoaderMultiSwitcherGenerator.groovy │ │ ├── SpecialLogic.groovy │ │ ├── MethodGenerator.groovy │ │ ├── EventGenerator.groovy │ │ ├── BridgeGenerator.groovy │ │ ├── SwitcherGenerator.groovy │ │ ├── ClassGenerator.groovy │ │ ├── LoaderSwitcherGenerator.groovy │ │ ├── Utils.groovy │ │ ├── EntryPointGenerator.groovy │ │ ├── IoCpuIntensiveLogicGenerator.groovy │ │ ├── LocalsGenerator.groovy │ │ ├── AppGenerator.groovy │ │ └── LogicGenerator.groovy │ └── resources │ └── predefined-names.txt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── examples ├── README ├── colors.bat ├── red.sh ├── black.sh ├── white.sh ├── yellow.sh ├── killer.sh ├── colors.sh ├── white.bat ├── red.bat ├── black.bat ├── yellow.bat └── killer.bat ├── scripts ├── start.sh ├── start-run.sh └── version-support.py ├── LICENSE ├── csv-script.sh ├── Dockerfile ├── gradlew.bat ├── Jenkinsfile ├── README.md └── gradlew /VERSION: -------------------------------------------------------------------------------- 1 | 3.1.0 2 | -------------------------------------------------------------------------------- /src/dist/template/project/APP_TYPE: -------------------------------------------------------------------------------- 1 | Undefined -------------------------------------------------------------------------------- /src/dist/template/project/FRAMES_COUNT: -------------------------------------------------------------------------------- 1 | 134 -------------------------------------------------------------------------------- /src/dist/template/project/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'tester' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/takipi/java-bullshifier/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/dist/template/project/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/takipi/java-bullshifier/HEAD/src/dist/template/project/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | build 4 | black 5 | big 6 | small 7 | white 8 | sticky-path 9 | myApp.log 10 | output 11 | report-stats.csv 12 | yellow 13 | red 14 | killer 15 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/takipi/java-bullshifier/HEAD/src/dist/template/multiproject/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Nov 08 17:24:50 IST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip 7 | -------------------------------------------------------------------------------- /src/dist/template/project/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jun 08 12:10:04 IDT 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip 7 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jun 08 12:10:04 IDT 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip 7 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | Generates an example applications using the bullshifier. 2 | 3 | Run the various colors scripts in this directory, to get an example app: 4 | white.sh = a light application 5 | yellow.sh = a little bit stronger application 6 | red.sh = a medium application 7 | black.sh = an heavy application 8 | killer.sh = an extraordinary heavy application 9 | -------------------------------------------------------------------------------- /scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Rebuild Build Color - If SEED is passed in 4 | if [[ -n "${GEN_SEED}" ]]; then 5 | rm -rf $COLOR 6 | buildCommand="./examples/$COLOR.sh" 7 | if ! $buildCommand ; then 8 | echo "Failed to run java bullshifier (command: $buildCommand)" 9 | exit 1 10 | fi 11 | fi 12 | 13 | runCommand="./start-run.sh" 14 | if ! $runCommand ; then 15 | echo "Failed to run generated application (command: $runCommand)" 16 | exit 1 17 | fi -------------------------------------------------------------------------------- /src/main/groovy/generator/GradleGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class GradleGenerator { 4 | private static write(outputDirectory, subProjects, mainClass) { 5 | def settingsGradleFile = new File("$outputDirectory/build.gradle") 6 | 7 | def subProjectsDeps = subProjects.collect({ "project(':$it')" }).join(",\n\t") 8 | 9 | settingsGradleFile.write(""" // Generated by App Generator 10 | apply plugin: 'java' 11 | 12 | project.ext.set(\"mainClass\", \"$mainClass\") 13 | 14 | dependencies 15 | { 16 | compile $subProjectsDeps 17 | } 18 | """) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/groovy/generator/GradleSettingsGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class GradleSettingsGenerator { 4 | private static write(outputDirectory, projectName, subProjects) { 5 | def gradleProjectName = (projectName != "" ? projectName : "tester") 6 | 7 | def settingsGradleFile = new File("$outputDirectory/settings.gradle") 8 | 9 | def subProjectsIncludes = subProjects.collect({ "include '$it'" }).join("\n") 10 | 11 | settingsGradleFile.write(""" // Generated by GradleSettingsGenerator 12 | rootProject.name=\"$gradleProjectName\" 13 | 14 | $subProjectsIncludes 15 | """) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/colors.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming this script is inside "java-bullshifier\examples" directory 3 | 4 | set bullshifier_name=%~1 5 | echo. 6 | echo Done! 7 | echo. 8 | echo To execute the bullshifier run: 9 | echo. 10 | echo "java -cp output\%bullshifier_name%\build\libs\%bullshifier_name%.jar helpers.Main " 11 | echo. 12 | echo Run with --help for a list of command line arguments 13 | echo. 14 | echo Example args: 15 | echo. 16 | echo Throws an exception every minute for a year 17 | echo. 18 | echo "-ec 1440 -im 60000 -rc 365 -wm 0 -st -hs -sp -fc -aa " 19 | echo. 20 | -------------------------------------------------------------------------------- /examples/red.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | source examples/colors.sh 4 | 5 | declare bullshifier_name="red" 6 | 7 | ./gradlew run -Pskip-logic-code \ 8 | -Pname=$bullshifier_name \ 9 | -Poutput-directory=$bullshifier_name \ 10 | -Psubprojects=1 \ 11 | -Pio-cpu-intensive-matrix-size=0 \ 12 | -Pmethods-per-class=1 \ 13 | -Plog-info-per-method=1 \ 14 | -Plog-warn-per-method=0 \ 15 | -Plog-error-per-method=0 \ 16 | -Pbridge-switch-size=3 \ 17 | -Pswitcher-max-routes=200 \ 18 | -Pentry-points=20 \ 19 | -Pclasses=500 \ 20 | $seedParameter || exit 1 21 | 22 | finish_bullshifier $bullshifier_name 23 | -------------------------------------------------------------------------------- /examples/black.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | source examples/colors.sh 4 | 5 | declare bullshifier_name="black" 6 | 7 | ./gradlew run -Pskip-logic-code \ 8 | -Pname=$bullshifier_name \ 9 | -Poutput-directory=$bullshifier_name \ 10 | -Psubprojects=1 \ 11 | -Pio-cpu-intensive-matrix-size=0 \ 12 | -Pmethods-per-class=1 \ 13 | -Plog-info-per-method=1 \ 14 | -Plog-warn-per-method=0 \ 15 | -Plog-error-per-method=0 \ 16 | -Pbridge-switch-size=4 \ 17 | -Pswitcher-max-routes=200 \ 18 | -Pentry-points=50 \ 19 | -Pclasses=1000 \ 20 | $seedParameter || exit 1 21 | 22 | finish_bullshifier $bullshifier_name 23 | -------------------------------------------------------------------------------- /examples/white.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | source examples/colors.sh 4 | 5 | declare bullshifier_name="white" 6 | 7 | ./gradlew run -Pskip-logic-code \ 8 | -Pname=$bullshifier_name \ 9 | -Poutput-directory=$bullshifier_name \ 10 | -Psubprojects=1 \ 11 | -Pio-cpu-intensive-matrix-size=0 \ 12 | -Pmethods-per-class=5 \ 13 | -Plog-info-per-method=1 \ 14 | -Plog-warn-per-method=0 \ 15 | -Plog-error-per-method=1 \ 16 | -Pbridge-switch-size=2 \ 17 | -Pswitcher-max-routes=10 \ 18 | -Pentry-points=1 \ 19 | -Pclasses=10 \ 20 | $seedParameter || exit 1 21 | 22 | finish_bullshifier $bullshifier_name 23 | -------------------------------------------------------------------------------- /examples/yellow.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | source examples/colors.sh 4 | 5 | declare bullshifier_name="yellow" 6 | 7 | ./gradlew run -Pskip-logic-code \ 8 | -Pname=$bullshifier_name \ 9 | -Poutput-directory=$bullshifier_name \ 10 | -Psubprojects=1 \ 11 | -Pio-cpu-intensive-matrix-size=0 \ 12 | -Pmethods-per-class=1 \ 13 | -Plog-info-per-method=1 \ 14 | -Plog-warn-per-method=0 \ 15 | -Plog-error-per-method=0 \ 16 | -Pbridge-switch-size=2 \ 17 | -Pswitcher-max-routes=50 \ 18 | -Pentry-points=5 \ 19 | -Pclasses=100 \ 20 | $seedParameter || exit 1 21 | 22 | finish_bullshifier $bullshifier_name 23 | -------------------------------------------------------------------------------- /examples/killer.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | source examples/colors.sh 4 | 5 | declare bullshifier_name="killer" 6 | 7 | ./gradlew run -Pskip-logic-code \ 8 | -Pname=$bullshifier_name \ 9 | -Poutput-directory=$bullshifier_name \ 10 | -Psubprojects=1 \ 11 | -Pio-cpu-intensive-matrix-size=0 \ 12 | -Pmethods-per-class=1 \ 13 | -Plog-info-per-method=1 \ 14 | -Plog-warn-per-method=0 \ 15 | -Plog-error-per-method=0 \ 16 | -Pbridge-switch-size=10 \ 17 | -Pswitcher-max-routes=2000 \ 18 | -Pentry-points=400 \ 19 | -Pclasses=10000 \ 20 | $seedParameter || exit 1 21 | 22 | finish_bullshifier $bullshifier_name 23 | -------------------------------------------------------------------------------- /src/dist/template/project/increment-deployment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -r script_dir=`cd "$( dirname "$0" )" && pwd` 4 | cd $script_dir 5 | 6 | declare -r emulatorDataDir=emulator-data 7 | 8 | mkdir -p $emulatorDataDir 9 | 10 | function increment_seed() 11 | { 12 | for appName in `ls $emulatorDataDir`; do 13 | local appDataDir="$emulatorDataDir/$appName" 14 | 15 | if [ ! -d "$appDataDir" ]; then 16 | continue 17 | fi 18 | 19 | local deploymentSeedFile="$appDataDir/DEPLOYMENT_SEED" 20 | local currentSeed=0 21 | 22 | if [ -r "$deploymentSeedFile" ]; then 23 | let currentSeed=$(cat $deploymentSeedFile) 24 | fi 25 | 26 | let newSeed="$currentSeed+1" 27 | echo $newSeed > $deploymentSeedFile 28 | done 29 | } 30 | 31 | increment_seed 32 | -------------------------------------------------------------------------------- /src/main/groovy/generator/BashRunnerGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class BashRunnerGenerator { 4 | private static write(outputDirectory, projectName) { 5 | def appUuidFile = new File("$outputDirectory/APP_UUID") 6 | def appTypeFile = new File("$outputDirectory/APP_TYPE") 7 | 8 | appUuidFile.write(UUID.randomUUID().toString()) 9 | appTypeFile.write(projectName) 10 | 11 | Utils.ant.chmod(file:"$outputDirectory/run.sh", perm:"+x") 12 | Utils.ant.chmod(file:"$outputDirectory/increment-deployment.sh", perm:"+x") 13 | 14 | // Informational file; just to know what seed was used if you want to share the application 15 | if(Config.seed != null){ 16 | def seedFile = new File("$outputDirectory/SEED") 17 | seedFile.write("Seed: "+Config.seed) 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scripts/start-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export JAVA_TOOL_OPTIONS=-agentpath:/opt/overops/takipi/lib/libTakipiAgent.so=takipi.debug.logconsole 4 | command="/opt/overops/$COLOR/run.sh --run-in-container " 5 | 6 | if [[ -n "${RUNNING_DURATION_HOURS}" ]]; then 7 | command+="--running-hours $RUNNING_DURATION_HOURS " 8 | fi 9 | 10 | if [[ -n "${RUNNING_DURATION_MINUTES}" ]]; then 11 | command+="--running-minutes $RUNNING_DURATION_MINUTES " 12 | fi 13 | 14 | if [[ -n "${INERVAL_MILLIS}" ]]; then 15 | command+="--interval-millis $INERVAL_MILLIS " 16 | fi 17 | 18 | if [[ -n "${APP_SEED}" ]]; then 19 | command+="--seed $APP_SEED " 20 | fi 21 | 22 | echo "About to run:" 23 | echo "$command" 24 | 25 | if ! $command ; then 26 | echo "Failed to run java bullshifier (command: $command)" 27 | exit 1 28 | fi 29 | -------------------------------------------------------------------------------- /examples/colors.sh: -------------------------------------------------------------------------------- 1 | 2 | declare current_dir=`pwd` 3 | 4 | seedParameter="" 5 | if [[ -n "${GEN_SEED}" ]]; then 6 | seedParameter+="-Pseed=$GEN_SEED " 7 | fi 8 | 9 | function finish_bullshifier() { 10 | local bullshifier_name=$1 11 | 12 | echo "Compiling" 13 | cd $bullshifier_name && ./gradlew fatJar 14 | 15 | echo "" 16 | echo "Done" 17 | echo "" 18 | echo "To execute the new tester run:" 19 | echo "" 20 | echo "java -cp $bullshifier_name/build/libs/$bullshifier_name.jar helpers.Main " 21 | echo "" 22 | echo " Run with --help for a list of command line arguments" 23 | echo "" 24 | echo " Example args:" 25 | echo "" 26 | echo " Throws an exception every minute for a year" 27 | echo "" 28 | echo " -ec 1440 -im 60000 -rc 365 -wm 0 -st -hs -sp -fc -aa " 29 | echo "" 30 | echo "" 31 | } 32 | -------------------------------------------------------------------------------- /examples/white.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming we're at "java-bullshifier\examples" and output to "java-bullshifier\output" 3 | 4 | set bullshifier_name=white 5 | set output_directory=output\%bullshifier_name% 6 | cd .. 7 | echo Generating %bullshifier_name% bullshifier... 8 | call gradlew run -Pskip-logic-code ^ 9 | -Pname=%bullshifier_name% ^ 10 | -Poutput-directory=%output_directory% ^ 11 | -Psubprojects=1 ^ 12 | -Pio-cpu-intensive-matrix-size=0 ^ 13 | -Pmethods-per-class=1 ^ 14 | -Plog-info-per-method=1 ^ 15 | -Plog-warn-per-method=0 ^ 16 | -Plog-error-per-method=0 ^ 17 | -Pbridge-switch-size=2 ^ 18 | -Pswitcher-max-routes=10 ^ 19 | -Pentry-points=1 ^ 20 | -Pclasses=10 21 | echo Compiling %bullshifier_name% bullshifier... 22 | cd %output_directory% 23 | call gradlew fatJar 24 | cd ..\..\examples 25 | call colors.bat %bullshifier_name% 26 | pause 27 | -------------------------------------------------------------------------------- /examples/red.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming we're at "java-bullshifier\examples" and output to "java-bullshifier\output" 3 | 4 | set bullshifier_name=red 5 | set output_directory=output\%bullshifier_name% 6 | cd .. 7 | echo Generating %bullshifier_name% bullshifier... 8 | call gradlew run -Pskip-logic-code ^ 9 | -Pname=%bullshifier_name% ^ 10 | -Poutput-directory=%output_directory% ^ 11 | -Psubprojects=1 ^ 12 | -Pio-cpu-intensive-matrix-size=0 ^ 13 | -Pconfig-class=SimpleConfig ^ 14 | -Pmethods-per-class=1 ^ 15 | -Plog-info-per-method=1 ^ 16 | -Plog-warn-per-method=0 ^ 17 | -Plog-error-per-method=0 ^ 18 | -Pbridge-switch-size=3 ^ 19 | -Pswitcher-max-routes=200 ^ 20 | -Pentry-points=20 ^ 21 | -Pclasses=500 22 | echo Compiling %bullshifier_name% bullshifier... 23 | cd %output_directory% 24 | call gradlew fatJar 25 | cd ..\..\examples 26 | call colors.bat %bullshifier_name% 27 | pause 28 | -------------------------------------------------------------------------------- /examples/black.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming we're at "java-bullshifier\examples" and output to "java-bullshifier\output" 3 | 4 | set bullshifier_name=black 5 | set output_directory=output\%bullshifier_name% 6 | cd .. 7 | echo Generating %bullshifier_name% bullshifier... 8 | call gradlew run -Pskip-logic-code ^ 9 | -Pname=%bullshifier_name% ^ 10 | -Poutput-directory=%output_directory% ^ 11 | -Psubprojects=1 ^ 12 | -Pio-cpu-intensive-matrix-size=0 ^ 13 | -Pconfig-class=SimpleConfig ^ 14 | -Pmethods-per-class=1 ^ 15 | -Plog-info-per-method=1 ^ 16 | -Plog-warn-per-method=0 ^ 17 | -Plog-error-per-method=0 ^ 18 | -Pbridge-switch-size=4 ^ 19 | -Pswitcher-max-routes=200 ^ 20 | -Pentry-points=50 ^ 21 | -Pclasses=1000 22 | echo Compiling %bullshifier_name% bullshifier... 23 | cd %output_directory% 24 | call gradlew fatJar 25 | cd ..\..\examples 26 | call colors.bat %bullshifier_name% 27 | pause 28 | -------------------------------------------------------------------------------- /examples/yellow.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming we're at "java-bullshifier\examples" and output to "java-bullshifier\output" 3 | 4 | set bullshifier_name=yellow 5 | set output_directory=output\%bullshifier_name% 6 | cd .. 7 | echo Generating %bullshifier_name% bullshifier... 8 | call gradlew run -Pskip-logic-code ^ 9 | -Pname=%bullshifier_name% ^ 10 | -Poutput-directory=%output_directory% ^ 11 | -Psubprojects=1 ^ 12 | -Pio-cpu-intensive-matrix-size=0 ^ 13 | -Pconfig-class=SimpleConfig ^ 14 | -Pmethods-per-class=1 ^ 15 | -Plog-info-per-method=1 ^ 16 | -Plog-warn-per-method=0 ^ 17 | -Plog-error-per-method=0 ^ 18 | -Pbridge-switch-size=2 ^ 19 | -Pswitcher-max-routes=50 ^ 20 | -Pentry-points=5 ^ 21 | -Pclasses=100 22 | echo Compiling %bullshifier_name% bullshifier... 23 | cd %output_directory% 24 | call gradlew fatJar 25 | cd ..\..\examples 26 | call colors.bat %bullshifier_name% 27 | pause 28 | -------------------------------------------------------------------------------- /examples/killer.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM assuming we're at "java-bullshifier\examples" and output to "java-bullshifier\output" 3 | 4 | set bullshifier_name=killer 5 | set output_directory=output\%bullshifier_name% 6 | cd .. 7 | echo Generating %bullshifier_name% bullshifier... 8 | call gradlew run -Pskip-logic-code ^ 9 | -Pname=%bullshifier_name% ^ 10 | -Poutput-directory=%output_directory% ^ 11 | -Psubprojects=1 ^ 12 | -Pio-cpu-intensive-matrix-size=0 ^ 13 | -Pconfig-class=SimpleConfig ^ 14 | -Pmethods-per-class=1 ^ 15 | -Plog-info-per-method=1 ^ 16 | -Plog-warn-per-method=0 ^ 17 | -Plog-error-per-method=0 ^ 18 | -Pbridge-switch-size=10 ^ 19 | -Pswitcher-max-routes=2000 ^ 20 | -Pentry-points=400 ^ 21 | -Pclasses=10000 22 | echo Compiling %bullshifier_name% bullshifier... 23 | cd %output_directory% 24 | call gradlew fatJar 25 | cd ..\..\examples 26 | call colors.bat %bullshifier_name% 27 | pause 28 | -------------------------------------------------------------------------------- /src/dist/template/project/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java" 2 | apply plugin: "war" 3 | apply plugin: 'eu.appsatori.fatjar' 4 | apply plugin: "application" 5 | 6 | mainClassName = "helpers.Main" 7 | 8 | buildscript { 9 | repositories { 10 | jcenter() 11 | } 12 | 13 | dependencies { 14 | classpath 'eu.appsatori:gradle-fatjar-plugin:0.3' 15 | } 16 | } 17 | 18 | repositories 19 | { 20 | mavenCentral() 21 | } 22 | 23 | dependencies 24 | { 25 | providedCompile 'javax.servlet:javax.servlet-api:3.1.0' 26 | compile 'ch.qos.logback:logback-classic:1.1.7' 27 | compile 'org.slf4j:slf4j-api:1.7.10' 28 | compile 'commons-cli:commons-cli:1.4' 29 | } 30 | 31 | compileJava { 32 | options.fork = true 33 | options.forkOptions.setMemoryMaximumSize("4g") 34 | } 35 | 36 | fatJar { 37 | zip64 = true 38 | manifest { 39 | attributes 'Main-Class': 'helpers.Main' 40 | } 41 | } 42 | 43 | project.ext.set("mainClass", "helpers.Main") 44 | 45 | build.dependsOn(fatJar) 46 | -------------------------------------------------------------------------------- /src/main/groovy/generator/MultiSwitcherGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class MultiSwitcherGenerator { 4 | private static write(outputDir, projectNames) { 5 | def switcherClassFile = new File("$outputDir/generated/MultiSwitcher.java") 6 | 7 | switcherClassFile.parentFile.mkdirs() 8 | 9 | def counter = 0 10 | 11 | def cases = projectNames.collect({ 12 | def projectName = it 13 | 14 | return "case ${counter++}: generated.Switcher${projectName}.call(); return;" 15 | }).join("\n\t\t\t") 16 | 17 | switcherClassFile.write("""package generated; 18 | 19 | import helpers.Config; 20 | import helpers.Context; 21 | import java.util.Random; 22 | 23 | public class MultiSwitcher 24 | { 25 | private static final Random rand = Config.get.getRandom(); 26 | 27 | public static void call() throws Exception 28 | { 29 | int switcherToCall = rand.nextInt(${projectNames.size()}); 30 | 31 | switch (switcherToCall) 32 | { 33 | $cases 34 | default: return; 35 | } 36 | } 37 | } 38 | """) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Takipi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/groovy/generator/Config.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class Config { 4 | public static rootDirectory 5 | public static generatedPackage = "generated" 6 | public static templateDirectory = "template" 7 | 8 | public static classesCount = 10 9 | public static methodsPerClass = 5 10 | public static maxPackageLength = 4 11 | public static bridgeSwitchSize = 4 12 | public static switcherMaxRoutes = Integer.MAX_VALUE 13 | 14 | public static subprojectsCount = 1 15 | 16 | public static minBlocksPerMethod = 2 17 | public static maxBlocksPerMethod = 4 18 | public static maxBlocksDepth = 2 19 | public static maxLoopStart = 0 20 | public static maxLoopEnd = 10000 21 | public static maxElseIfBlocks = 2 22 | public static maxExpressionLength = 2 23 | 24 | public static entryPointNum = 20 25 | 26 | public static logInfoPerMethod = 5 27 | public static logWarnPerMethod = 5 28 | public static logErrorPerMethod = 5 29 | 30 | public static ioCpuIntensiveMatrixSize = 300 31 | public static ioCpuIntensiveFileLimit = 100 32 | public static shouldGenerateLogicCode = true 33 | 34 | public static seed = null; 35 | } 36 | -------------------------------------------------------------------------------- /csv-script.sh: -------------------------------------------------------------------------------- 1 | # first version 2 | file=$1 #filename 3 | outputFile=$file.output 4 | startReadingLine=${2:-0} # if you want to skip the first 5 minutes, for example, pass 5 * 6 5 | 6 | lines=`cat $file | wc -l` 7 | numOfFunctions=4 8 | offset=`echo $startReadingLine + $numOfFunctions + 2 | bc` 9 | lines=`echo $lines + $numOfFunctions | bc` 10 | 11 | cp $file $outputFile 12 | file=$outputFile 13 | 14 | # When you add a new function, inc numOfFunctions 15 | echo "MEDIAN,\"=MEDIAN(B$offset:B$lines)\",\"=MEDIAN(C$offset:C$lines)\",\"=MEDIAN(D$offset:D$lines)\",\"=MEDIAN(E$offset:E$lines)\"," | cat - $file > $file.tmp ; 16 | mv $file.tmp $file; 17 | echo "MAX,\"=MAX(B$offset:B$lines)\",\"=MAX(C$offset:C$lines)\",\"=MAX(D$offset:D$lines)\",\"=MAX(E$offset:E$lines)\"," | cat - $file > $file.tmp ; 18 | mv $file.tmp $file; 19 | echo "AVERAGE,\"=AVERAGE(B$offset:B$lines)\",\"=AVERAGE(C$offset:C$lines)\",\"=AVERAGE(D$offset:D$lines)\",\"=AVERAGE(E$offset:E$lines)\"," | cat - $file > $file.tmp ; 20 | mv $file.tmp $file; 21 | echo "95 percentile,\"=PERCENTILE(B$offset:B$lines, 0.95)\",\"=PERCENTILE(C$offset:C$lines, 0.95)\",\"=PERCENTILE(D$offset:D$lines, 0.95)\",\"=PERCENTILE(E$offset:E$lines, 0.95)\"," | cat - $file > $file.tmp ; 22 | mv $file.tmp $file; -------------------------------------------------------------------------------- /src/main/groovy/generator/LoaderMultiSwitcherGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class LoaderMultiSwitcherGenerator { 4 | private static write(outputDir, projectNames) { 5 | def switcherClassFile = new File("$outputDir/generated/LoaderMultiSwitcher.java") 6 | 7 | switcherClassFile.parentFile.mkdirs() 8 | 9 | def counter = 0 10 | 11 | def cases = projectNames.collect({ 12 | def projectName = it 13 | 14 | return "case ${counter++}: generated.LoaderSwitcher${projectName}.call(); return;" 15 | }).join("\n\t\t\t") 16 | 17 | def resetLoadersStatements = projectNames.collect({ 18 | def projectName = it 19 | 20 | return "generated.LoaderSwitcher${projectName}.resetLoaders();" 21 | }).join("\n\t\t") 22 | 23 | switcherClassFile.write("""package generated; 24 | 25 | import helpers.Config; 26 | import helpers.Context; 27 | import java.util.Random; 28 | 29 | public class LoaderMultiSwitcher 30 | { 31 | private static final Random rand = Config.get.getRandom(); 32 | 33 | public static void call() throws Exception 34 | { 35 | int switcherToCall = rand.nextInt(${projectNames.size()}); 36 | 37 | switch (switcherToCall) 38 | { 39 | $cases 40 | default: return; 41 | } 42 | } 43 | 44 | public static void resetLoaders() { 45 | $resetLoadersStatements 46 | } 47 | } 48 | """) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/groovy/generator/SpecialLogic.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class SpecialLogic { 4 | private static generateSpecial() { 5 | switch (Utils.rand.nextInt(3)) { 6 | case (0): return parseIntBlock() 7 | case (1): return synchronizedBlock() 8 | case (2): return newFileBlock() 9 | } 10 | 11 | return [] 12 | } 13 | 14 | private static parseIntBlock() { 15 | def num = Utils.generateName("num") 16 | 17 | return [ 18 | "try", 19 | "{", 20 | "\tInteger.parseInt(\"$num\");", 21 | "}", 22 | "catch(NumberFormatException e) ", 23 | "{", 24 | "\te.printStackTrace();", 25 | "}" 26 | ] 27 | } 28 | 29 | private static synchronizedBlock() { 30 | return [ 31 | "Object locker = new Object();", 32 | "", 33 | "synchronized (locker)", 34 | "{", 35 | "\tSystem.out.println(\"synchronized block\");", 36 | "}" 37 | ] 38 | } 39 | 40 | private static newFileBlock() { 41 | def path = [] 42 | def len = Utils.rand.nextInt(10) 43 | 44 | for (def i = 0; i < len; i++) { 45 | if (i - 1 == len) { 46 | path += Utils.generateName("file") 47 | } else { 48 | path += Utils.generateName("dir") 49 | } 50 | } 51 | 52 | def pathStr = path.join("/") 53 | 54 | return [ 55 | "java.io.File file = new java.io.File(\"/$pathStr\");", 56 | "", 57 | "if (file.canRead())", 58 | "{", 59 | "\tSystem.out.println(\"File exists\");", 60 | "}", 61 | "else", 62 | "{", 63 | "\tSystem.out.println(\"File not exists\");", 64 | "}" 65 | ] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bullshifier.log 5 | 6 | bullshifier.%i.log 7 | 1 8 | 1 9 | 10 | 11 | 1000MB 12 | 13 | 14 | [%d{dd-MM HH:mm:ss}][%-12.-12X{server}-%-10.10X{agent}-%-30.30X{deployment}] %-5level - %msg {%logger{0}} [%thread] %n 15 | 16 | 17 | 18 | 19 | System.out 20 | 21 | [%d{dd-MM HH:mm:ss}][%-12.-12X{server}-%-10.10X{agent}-%-30.30X{deployment}] %-5level - %msg {%logger{0}} [%thread] %n 22 | 23 | 24 | 25 | 26 | System.err 27 | 28 | [%d{dd-MM HH:mm:ss}][%-12.-12X{server}-%-10.10X{agent}-%-30.30X{deployment}] %-5level - %msg {%logger{0}} [%thread] %n 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-slim 2 | LABEL maintainer="support@overops.com" 3 | 4 | # Install curl 5 | RUN apt-get update && apt-get -y install curl 6 | 7 | RUN groupadd --gid 1000 overops 8 | RUN adduser --home /opt/overops --uid 1000 --gid 1000 overops 9 | 10 | # Run as overops user 11 | USER 1000:1000 12 | 13 | # Copy bullshier atrifacts 14 | WORKDIR /opt/overops 15 | 16 | # Download agent 17 | ARG AGENT_VERSION=latest 18 | ARG AGENT_URL=https://s3.amazonaws.com/app-takipi-com/deploy/linux/takipi-agent 19 | RUN curl -sL ${AGENT_URL}-${AGENT_VERSION}.tar.gz | tar -xvzf - 20 | 21 | # Copy source code to container 22 | COPY --chown=1000:1000 ./gradle ./gradle.sh 23 | COPY --chown=1000:1000 ./src ./src 24 | COPY --chown=1000:1000 ./gradlew ./gradlew 25 | COPY --chown=1000:1000 ./gradle ./gradle 26 | COPY --chown=1000:1000 ./build.gradle ./build.gradle 27 | COPY --chown=1000:1000 ./examples/*.sh ./examples/ 28 | COPY --chown=1000:1000 ./scripts/*.sh ./ 29 | 30 | # Precompile Colors 31 | RUN ["/bin/bash", "./examples/white.sh"] 32 | RUN ["/bin/bash", "./examples/yellow.sh"] 33 | RUN ["/bin/bash", "./examples/red.sh"] 34 | RUN ["/bin/bash", "./examples/black.sh"] 35 | 36 | # Change Permissions (Windows Build Support) 37 | RUN chmod u+x *.sh 38 | RUN chmod u+x examples/*.sh 39 | 40 | # Default Environmental Variables 41 | ENV INERVAL_MILLIS=300 42 | ENV RUNNING_DURATION_HOURS=0 43 | ENV RUNNING_DURATION_MINUTES=5 44 | ENV COLOR=white 45 | ENV TAKIPI_COLLECTOR_HOST=collector 46 | ENV TAKIPI_COLLECTOR_PORT=6060 47 | ENV IS_DAEMON=true 48 | 49 | ENTRYPOINT ["/bin/bash", "./start.sh"] 50 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/build.gradle: -------------------------------------------------------------------------------- 1 | subprojects 2 | { 3 | apply plugin: "java" 4 | 5 | repositories 6 | { 7 | mavenCentral() 8 | } 9 | 10 | task generateScripts(dependsOn:"jar") << 11 | { 12 | if (!project.ext.has("mainClass")) 13 | { 14 | return 15 | } 16 | 17 | def binDir = new File("$rootDir/bin") 18 | binDir.mkdirs(); 19 | 20 | def scriptFile = new File("$binDir/${projectDir.name}.sh") 21 | def nodepsScriptFile = new File("$binDir/${projectDir.name}-nodeps.sh") 22 | 23 | def classPath = configurations.runtime.resolve() 24 | 25 | def dependentProjects = project.configurations.compile.dependencies 26 | .grep({ it instanceof ProjectDependency }) 27 | .collect({ it.dependencyProject.configurations.compile.dependencies }) 28 | .plus(project.configurations.compile.dependencies) 29 | .flatten() 30 | .grep({ it instanceof ProjectDependency }) 31 | .unique() 32 | .collect({ "${it.name}.jar".toString() }) 33 | 34 | def classPathWithoutProjects = classPath.grep({ !(it.name in dependentProjects) }) 35 | 36 | classPath += jar.archivePath 37 | classPathWithoutProjects += jar.archivePath 38 | 39 | def classPathStr = classPath.join(File.pathSeparator) 40 | def classPathWithoutProjectsStr = classPathWithoutProjects.join(File.pathSeparator) 41 | 42 | def lines = 43 | [ 44 | "#!/bin/bash", 45 | "", 46 | "java -cp $classPathStr $mainClass \$@", 47 | "" 48 | ] 49 | 50 | scriptFile.write(lines.join("\n")) 51 | scriptFile.setExecutable(true) 52 | 53 | def nodepsLines = 54 | [ 55 | "#!/bin/bash", 56 | "", 57 | "export ROOT_PROJECT_DIR=$rootDir", 58 | "", 59 | "java -cp $classPathWithoutProjectsStr $mainClass \$@", 60 | "" 61 | ] 62 | 63 | nodepsScriptFile.write(nodepsLines.join("\n")) 64 | nodepsScriptFile.setExecutable(true) 65 | } 66 | 67 | build.dependsOn("generateScripts") 68 | } 69 | -------------------------------------------------------------------------------- /src/main/groovy/generator/MethodGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class MethodGenerator { 4 | private def owner 5 | private def name 6 | private def code = new StringBuilder() 7 | 8 | private def MethodGenerator(owner, methodId) { 9 | this.owner = owner 10 | def paddedMethodId = String.format("%03d", methodId); 11 | this.name = "method$paddedMethodId" 12 | } 13 | 14 | public def addClassAndMethodId(classId, methodId) { 15 | code.append("\t\tint methodId = $methodId;\n") 16 | code.append("\t\tInteger entryPointNum = Config.get().entryPointIndex.get();") 17 | code.append("\t\tConfig.get().updateContext(context, entryPointNum, $classId, $methodId);\n\n") 18 | } 19 | 20 | private def addLocals() { 21 | def locals = LocalsGenerator.generateLocals() 22 | def lines = locals.collect({ "\t\t$it" }) 23 | 24 | code.append("\t\t// Start of fake locals generator\n") 25 | code.append(lines.join("\n")) 26 | code.append("// End of fake locals generator\n") 27 | code.append("\n") 28 | } 29 | 30 | private def addLogic() { 31 | def logic = LogicGenerator.generateBlocks([:]) 32 | def lines = logic.print("\t\t") 33 | 34 | code.append(lines.join("\n")) 35 | } 36 | 37 | private def addBridge(classes) { 38 | def lines = BridgeGenerator.generate(name, classes).collect({ "\t\t$it" }) 39 | 40 | code.append(lines.join("\n")) 41 | } 42 | 43 | private def addEvents() { 44 | def lines = EventGenerator.addEvent(owner.name, name) 45 | 46 | code.append(lines.join("\n")) 47 | code.append("\n") 48 | } 49 | 50 | private def generate() { 51 | def codeStr = code.toString() 52 | 53 | def methodToCallVariableName = BridgeGenerator.getMethodToCallVariableName(name) 54 | 55 | return new StringBuilder() 56 | .append("\tpublic static void $name(Context context) throws Exception\n") 57 | .append("\t{\n") 58 | .append(codeStr) 59 | .append("\n") 60 | .append("\t}\n").toString() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/groovy/generator/EventGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | import static generator.Utils.* 4 | import static generator.Config.* 5 | 6 | class EventGenerator { 7 | static addEvent(className, methodName) { 8 | return [ 9 | "String currentTime = dateFormat.format(new Date());", 10 | "long currentTimeMillis = System.currentTimeMillis();", 11 | "", 12 | "if (Config.get().shouldWriteLogInfo(context))", 13 | "{", 14 | " logger.info(\"${className}.${methodName} called at {} (millis: {}) (stack-depth: {}) (prev method fail rate is: {})\",", 15 | " currentTime, System.currentTimeMillis(), context.framesDepth, context.lastSpotPrecentage);", 16 | "}", 17 | "", 18 | "if (Config.get().shouldWriteLogWarn(context))", 19 | "{", 20 | " logger.warn(\"${className}.${methodName} called at {} (millis: {}) (stack-depth: {}) (prev method fail rate is: {})\",", 21 | " currentTime, System.currentTimeMillis(), context.framesDepth, context.lastSpotPrecentage);", 22 | "}", 23 | "", 24 | "context.instructionIndex = 1;", 25 | "", 26 | "if (Config.get().shouldFireEvent(context))", 27 | "{", 28 | " BullshifierException.incHitsCount(context);", 29 | " throw BullshifierException.build(context);\n", 30 | "}", 31 | "", 32 | "context.instructionIndex = 2;", 33 | "", 34 | "if (Config.get().shouldFireEvent(context))", 35 | "{", 36 | " BullshifierException.incHitsCount(context);", 37 | " throw BullshifierException.build(context);\n", 38 | "}", 39 | "", 40 | "context.instructionIndex = 3;", 41 | "", 42 | "if (Config.get().shouldFireEvent(context))", 43 | "{", 44 | " BullshifierException.incHitsCount(context);", 45 | " throw BullshifierException.build(context);\n", 46 | "}", 47 | "", 48 | "if (Config.get().shouldSuicide())", 49 | "{", 50 | " System.exit(0);", 51 | "}", 52 | "", 53 | "if (Config.get().shouldRunAway(context))", 54 | "{", 55 | " return;", 56 | "}" 57 | ].collect({ "\t\t$it" }) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/BullshifierException.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import helpers.Config; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | import java.util.concurrent.ConcurrentMap; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | public class BullshifierException extends Exception { 9 | private static final ConcurrentMap hitsCounterMap = 10 | new ConcurrentHashMap(); 11 | 12 | private final Context context; 13 | private final int totalUniqueEvents; 14 | 15 | public static BullshifierException build(Context context) 16 | { 17 | int hits = BullshifierException.getHitCount(context); 18 | int invs = Context.getInvCount(context); 19 | double failRate = (double) hits / (double) invs * 100; 20 | int failRateInt = (int)failRate; 21 | 22 | String message = String.format("(Event: %s) (Hits: %d) (Invs: %d) (Fail Rate: %d%%)", 23 | context.getRequestId(), hits, invs, failRateInt); 24 | 25 | return new BullshifierException(context, message); 26 | } 27 | 28 | public BullshifierException(Context context, String message) { 29 | super(message); 30 | this.context = context; 31 | this.totalUniqueEvents = hitsCounterMap.size(); 32 | } 33 | 34 | public Context getContext() 35 | { 36 | return context; 37 | } 38 | 39 | public static void incHitsCount(Context context) 40 | { 41 | String requestId = context.getRequestId(); 42 | 43 | if (!hitsCounterMap.containsKey(requestId)) { 44 | hitsCounterMap.putIfAbsent(requestId, new AtomicInteger()); 45 | } 46 | 47 | AtomicInteger hitsCounter = hitsCounterMap.get(requestId); 48 | hitsCounter.addAndGet(1); 49 | } 50 | 51 | public static int getHitCount(Context context) 52 | { 53 | AtomicInteger hitsCounter = hitsCounterMap.get(context.getRequestId()); 54 | Integer hits = hitsCounter.get(); 55 | return hits == null ? -1 : hits; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | 61 | return getMessage(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/groovy/generator/BridgeGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class BridgeGenerator { 4 | public static generate(methodName, classes) { 5 | def lines = [] 6 | 7 | def methodToCallVariableName = getMethodToCallVariableName(methodName) 8 | def swtichMethods = randomMethods(classes, Config.bridgeSwitchSize) 9 | 10 | lines += "" 11 | lines += "try" 12 | lines += "{" 13 | lines += " int $methodToCallVariableName = Config.get().getStickyPath(classId, methodId, ${swtichMethods.size()});" 14 | lines += "" 15 | lines += addSwitch(methodName, swtichMethods) 16 | lines += "}" 17 | lines += "catch (Exception e)" 18 | lines += "{" 19 | lines += " if (Config.get().shouldWriteLogError(context))" 20 | lines += " {" 21 | lines += " String serverName = System.getProperty(\"takipi.server.name\");" 22 | lines += " String agentName = System.getProperty(\"takipi.name\");" 23 | lines += " String deploymentName = System.getProperty(\"takipi.deployment.name\");" 24 | lines += " logger.error(\"An error from ({}/{}/{})\", serverName, agentName, deploymentName, e);" 25 | lines += " }" 26 | lines += "}" 27 | lines += "" 28 | lines += "if (Boolean.parseBoolean(\"true\")) { return; }" 29 | 30 | return lines 31 | } 32 | 33 | public static getMethodToCallVariableName(methodName) { 34 | return "${methodName}MethodToCall" 35 | } 36 | 37 | private static randomMethods(classes, bridgeSwitchSize) { 38 | return (1..bridgeSwitchSize).collect({ 39 | def classIndex = Utils.rand.nextInt(classes.size()) 40 | return classes[classIndex].randomMethod() 41 | }) 42 | } 43 | 44 | private static addSwitch(methodName, swtichMethods) { 45 | def methodToCallVariableName = getMethodToCallVariableName(methodName) 46 | 47 | def switcher = [ 48 | "\tswitch ($methodToCallVariableName)", 49 | "\t{" 50 | ] 51 | 52 | int counter = 0 53 | 54 | swtichMethods.each({ 55 | switcher += "\t\tcase (${counter++}): ${it.owner.qualifyName()}.${it.name}(context); return;" 56 | }) 57 | 58 | switcher += "\t}" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/groovy/generator/SwitcherGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | import generator.Config 4 | 5 | public class SwitcherGenerator { 6 | private static write(classes, outputDir, projectName) { 7 | def switcherClassName = "Switcher$projectName" 8 | 9 | def counter = 0 10 | 11 | def switchStatements = classes.collect({ 12 | def clazz = it 13 | 14 | return clazz.methods.collect({ 15 | return ["case ${counter++}: ${clazz.qualifyName()}.$it.name(new Context()); return;"] 16 | }) 17 | }).flatten() 18 | 19 | def maxCasesPerClass = 1000 20 | def subClassesCount = (switchStatements.size() / maxCasesPerClass) 21 | def mainMethodIfs = [] 22 | 23 | (0..(subClassesCount - 1)).each { 24 | def start = it * maxCasesPerClass 25 | def end = Math.min(start + maxCasesPerClass, switchStatements.size() - 1) 26 | def subClassesCases = switchStatements[start..end] 27 | 28 | def CasesStr = subClassesCases.join("\n\t\t\t") 29 | 30 | def switcherSubClassFile = new File("$outputDir/generated/${switcherClassName}${it}.java") 31 | 32 | switcherSubClassFile.write("""package generated; 33 | import helpers.Config; 34 | import helpers.Context; 35 | public class $switcherClassName$it 36 | { 37 | public static void call(int number) throws Exception 38 | { 39 | switch (number) 40 | { 41 | $CasesStr 42 | default: return; 43 | } 44 | } 45 | } 46 | """ 47 | ) 48 | 49 | mainMethodIfs += """ 50 | if (number >= $start && number <= $end) 51 | { 52 | $switcherClassName${it}.call(number); 53 | return; 54 | } 55 | """ 56 | } 57 | 58 | def switcherClassFile = new File("$outputDir/generated/${switcherClassName}.java") 59 | def maxRoutes = Math.min(Config.switcherMaxRoutes, switchStatements.size()) 60 | 61 | switcherClassFile.write("""package generated; 62 | import helpers.Config; 63 | import helpers.Context; 64 | public class $switcherClassName 65 | { 66 | public static void call() throws Exception 67 | { 68 | call(Config.get().getRandom().nextInt($maxRoutes)); 69 | } 70 | public static void call(int number) throws Exception 71 | { 72 | ${mainMethodIfs.join("\n\t\t\t")} 73 | } 74 | } 75 | """) 76 | 77 | return switcherClassName 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/StickyPathHelper.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import java.io.File; 4 | import java.io.FileReader; 5 | import java.io.FileOutputStream; 6 | import java.io.BufferedReader; 7 | 8 | public class StickyPathHelper { 9 | public static int getMethodToCall(File stickyPathDir, int classId, int methodId) { 10 | File methodToCallFile = getMethodToCallFile(stickyPathDir, classId, methodId); 11 | 12 | if (methodToCallFile == null) { 13 | return -1; 14 | } 15 | 16 | if (!methodToCallFile.canRead()) { 17 | return -1; 18 | } 19 | 20 | FileReader fileReader = null; 21 | BufferedReader bufferedReader = null; 22 | 23 | try { 24 | fileReader = new FileReader(methodToCallFile); 25 | bufferedReader = new BufferedReader(fileReader); 26 | 27 | String methodToCallLine = bufferedReader.readLine(); 28 | 29 | if (methodToCallLine == null) { 30 | return -1; 31 | } 32 | 33 | return Integer.parseInt(methodToCallLine); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | return -1; 37 | } finally { 38 | try { 39 | if (bufferedReader != null) { 40 | bufferedReader.close(); 41 | } 42 | if (fileReader != null) { 43 | fileReader.close(); 44 | } 45 | } catch (Exception e) { } 46 | } 47 | } 48 | 49 | public static boolean persistMethodToCall(File stickyPathDir, 50 | int classId, int methodId, int methodToCall) { 51 | File methodToCallFile = getMethodToCallFile(stickyPathDir, classId, methodId); 52 | 53 | if (methodToCallFile == null) { 54 | return false; 55 | } 56 | 57 | FileOutputStream out = null; 58 | 59 | try { 60 | out = new FileOutputStream(methodToCallFile); 61 | out.write(Integer.toString(methodToCall).getBytes()); 62 | return true; 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | return false; 66 | } finally { 67 | try { 68 | if (out != null) { 69 | out.close(); 70 | } 71 | } catch (Exception e) { } 72 | } 73 | } 74 | 75 | public static File getMethodToCallFile(File stickyPathDir, 76 | int classId, int methodId) { 77 | stickyPathDir.mkdirs(); 78 | 79 | if (!stickyPathDir.isDirectory()) { 80 | System.out.println("Sticky path dir is not a directory " + stickyPathDir); 81 | return null; 82 | } 83 | 84 | return new File(stickyPathDir, classId + ":" + methodId); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/dist/template/project/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/main/groovy/generator/ClassGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | class ClassGenerator { 4 | private def name 5 | private def classPackage 6 | private def methods = [] 7 | private def classId 8 | 9 | private def ClassGenerator(classId) { 10 | def packageParts = 4 11 | this.classId = classId 12 | def paddedClassId = String.format("%06d", classId); 13 | this.name = "Class$paddedClassId" 14 | this.classPackage = "generated." + (0..packageParts).collect( 15 | { 16 | return Utils.generateName("", "", 4, false, true) 17 | }).join(".") 18 | } 19 | 20 | private def addMethod(methodId) { 21 | def method = new MethodGenerator(this, methodId) 22 | 23 | methods += method 24 | } 25 | 26 | private def randomMethod() { 27 | return methods[Utils.rand.nextInt(methods.size())] 28 | } 29 | 30 | private def qualifyName() { 31 | return "${classPackage}.$name" 32 | } 33 | 34 | private def generateMethods(classes, withLogic, withBridge, withLocals, withEvent) { 35 | def methodCounter = 0 36 | 37 | methods.each { 38 | it.addClassAndMethodId(classId, methodCounter++) 39 | 40 | if (withLocals) { 41 | it.addLocals() 42 | } 43 | 44 | if (withEvent) { 45 | it.addEvents() 46 | } 47 | 48 | if (withBridge) { 49 | it.addBridge(classes) 50 | } 51 | 52 | if (withLogic) { 53 | it.addLogic() 54 | } 55 | } 56 | } 57 | 58 | private def toPath() { 59 | def packagePath = classPackage.replace(".", "/") 60 | 61 | return "$packagePath/${name}.java" 62 | } 63 | 64 | private def write(outputDir) { 65 | def code = new StringBuilder() 66 | code.append(classHeader()) 67 | 68 | methods.each { 69 | code.append(it.generate()); 70 | code.append("\n") 71 | } 72 | 73 | code.append("}\n") 74 | 75 | def classFile = new File("$outputDir/${toPath()}") 76 | classFile.parentFile.mkdirs() 77 | classFile.write(code.toString()) 78 | } 79 | 80 | private def classHeader() { 81 | return """package $classPackage; 82 | 83 | import helpers.Config; 84 | import helpers.Context; 85 | import helpers.BullshifierException; 86 | import java.util.*; 87 | import java.util.logging.*; 88 | import org.slf4j.Logger; 89 | import org.slf4j.LoggerFactory; 90 | import java.io.IOException; 91 | import java.text.SimpleDateFormat; 92 | 93 | public class $name 94 | { 95 | public static final Logger logger = LoggerFactory.getLogger(${name}.class); 96 | 97 | public static final int classId = $classId; 98 | public static final SimpleDateFormat dateFormat = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ssZ\"); 99 | 100 | """ 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/groovy/generator/LoaderSwitcherGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class LoaderSwitcherGenerator { 4 | private static write(generatedDir, projectName) { 5 | def outputFile = new File(generatedDir, "LoaderSwitcher${projectName}.java"); 6 | outputFile.write(template.replace("@PROJECT_NAME@", projectName)) 7 | } 8 | 9 | static template = """ 10 | package generated; 11 | 12 | import java.lang.reflect.Method; 13 | import java.net.URL; 14 | import java.net.URLClassLoader; 15 | import java.io.File; 16 | import java.util.Random; 17 | 18 | public class LoaderSwitcher@PROJECT_NAME@ extends ClassLoader { 19 | private static int loadersCount; 20 | private static URLClassLoader[] loaders; 21 | private static final Random rand = Config.get.getRandom(); 22 | 23 | static { 24 | String loadersPerProjectStr = System.getenv(\"LOADERS_PER_PROJECT\"); 25 | 26 | if (loadersPerProjectStr == null) { 27 | loadersCount = 5; 28 | } else { 29 | try { 30 | loadersCount = Integer.parseInt(loadersPerProjectStr); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | loadersCount = 5; 34 | } 35 | } 36 | 37 | loaders = new URLClassLoader[loadersCount]; 38 | } 39 | 40 | private static URLClassLoader getLoader() throws Exception { 41 | int loaderIndex = rand.nextInt(loadersCount); 42 | 43 | if (loaders[loaderIndex] != null) { 44 | return loaders[loaderIndex]; 45 | } 46 | 47 | synchronized (LoaderSwitcher@PROJECT_NAME@.class) { 48 | if (loaders[loaderIndex] != null) { 49 | return loaders[loaderIndex]; 50 | } 51 | 52 | String rootProjectDir = System.getenv(\"ROOT_PROJECT_DIR\"); 53 | 54 | if (rootProjectDir == null) { 55 | System.out.println(\"ROOT_PROJECT_DIR environment variable is not defined\"); 56 | System.exit(1); 57 | return null; 58 | } 59 | 60 | String projectName = \"@PROJECT_NAME@\"; 61 | String projectJar = String.format(\"%s/%s/build/libs/%s.jar\", 62 | rootProjectDir, projectName, projectName); 63 | File projectJarFile = new File(projectJar); 64 | 65 | if (!projectJarFile.canRead()) { 66 | System.out.println(\"Missing project jar: \" + projectJarFile); 67 | System.exit(1); 68 | return null; 69 | } 70 | 71 | URL url = new URL(\"file://\" + projectJar); 72 | loaders[loaderIndex] = new URLClassLoader(new URL[] { url }); 73 | 74 | return loaders[loaderIndex]; 75 | } 76 | } 77 | 78 | public static void resetLoaders() { 79 | for (int i = 0; i < loaders.length; i++) { 80 | loaders[i] = null; 81 | } 82 | } 83 | 84 | public static void call() throws Exception { 85 | String projectName = \"@PROJECT_NAME@\"; 86 | Class switcherClass = Class.forName(\"generated.Switcher\" + projectName, true, getLoader()); 87 | Method callMethod = switcherClass.getMethod(\"call\"); 88 | callMethod.invoke(null); 89 | } 90 | } 91 | 92 | """ 93 | } 94 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/Context.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | import java.util.concurrent.ConcurrentMap; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.atomic.AtomicInteger; 8 | 9 | public class Context 10 | { 11 | private static final ConcurrentMap invsCounterMap = 12 | new ConcurrentHashMap(); 13 | 14 | public int framesDepth = 0; 15 | public List path = new ArrayList(); 16 | public int classId = 0; 17 | public int methodId = 0; 18 | public int entryPointId = 0; 19 | public int instructionIndex = 0; 20 | public int lastSpotPrecentage; 21 | 22 | public Context() { } 23 | 24 | public String getRequestId() 25 | { 26 | return String.format("%d:%d:%d:%d", entryPointId, classId, methodId, instructionIndex); 27 | } 28 | 29 | public String getLocationId() 30 | { 31 | return String.format("%d:%d", classId, methodId); 32 | } 33 | 34 | public static void incInvCount(Context context) 35 | { 36 | String locationId = context.getLocationId(); 37 | 38 | if (!invsCounterMap.containsKey(locationId)) { 39 | invsCounterMap.putIfAbsent(locationId, new AtomicInteger()); 40 | } 41 | 42 | AtomicInteger invsCounter = invsCounterMap.get(locationId); 43 | invsCounter.addAndGet(1); 44 | } 45 | 46 | public static int getInvCount(Context context) 47 | { 48 | AtomicInteger invsCounter = invsCounterMap.get(context.getLocationId()); 49 | Integer invs = invsCounter.get(); 50 | return invs == null ? -1 : invs; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | StringBuilder result = new StringBuilder(); 56 | 57 | result.append("(fail-rate: "); 58 | result.append(lastSpotPrecentage); 59 | result.append("%) (frames: "); 60 | result.append(framesDepth); 61 | result.append(", path: ["); 62 | 63 | for (int i = 0; i < path.size(); i++) { 64 | int classId = path.get(i)[0]; 65 | int methodId = path.get(i)[1]; 66 | 67 | result.append(classId); 68 | 69 | if (methodId != 0) 70 | { 71 | result.append(":"); 72 | result.append(methodId); 73 | } 74 | 75 | if ((i + 1) < path.size()) { 76 | result.append(", "); 77 | } 78 | } 79 | 80 | result.append("])"); 81 | 82 | return result.toString(); 83 | } 84 | 85 | public void addPath(int classId, int methodId) 86 | { 87 | this.classId = classId; 88 | this.methodId = methodId; 89 | 90 | int[] classAndMethodId = new int[2]; 91 | 92 | classAndMethodId[0] = classId; 93 | classAndMethodId[1] = methodId; 94 | 95 | path.add(classAndMethodId); 96 | } 97 | 98 | public String toPathString() { 99 | StringBuilder sb = new StringBuilder(); 100 | 101 | for (int i = 0; i < path.size(); i++) { 102 | int[] current = path.get(i); 103 | sb.append(">"); 104 | sb.append(current[0]); 105 | sb.append(":"); 106 | sb.append(current[1]); 107 | } 108 | 109 | return sb.toString(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/dist/template/project/params.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -A params_list 4 | declare -A params_var 5 | declare -A params_desc 6 | declare -A params_short_to_long 7 | declare -A params_short 8 | declare -A params_type 9 | declare -A params_default 10 | declare -A params_skipped_list 11 | 12 | declare -rA params_types=([boolean]="boolean" [expect_value]="expectValue") 13 | 14 | function params_add() 15 | { 16 | local long_name=$1 17 | local short_name=$2 18 | local default_value=$3 19 | local variable_name=$4 20 | local param_type=$5 21 | local description=$6 22 | 23 | [ -z "$short_name" ] && $short_name=$long_name 24 | [ -z "$long_name" ] && $long_name=$short_name 25 | 26 | if [ -z "$long_name" ]; then 27 | echo "Parameter name name is missing" 28 | return 1 29 | fi 30 | 31 | if [ -z "$variable_name" ]; then 32 | echo "Variable name is missing" 33 | return 1 34 | fi 35 | 36 | params_list[$long_name]="exists" 37 | params_var[$long_name]=$variable_name 38 | params_desc[$long_name]=$description 39 | params_type[$long_name]=$param_type 40 | params_short[$long_name]=$short_name 41 | params_default[$long_name]=$default_value 42 | 43 | params_short_to_long[$short_name]=$long_name 44 | 45 | declare -g $variable_name="$default_value" 46 | 47 | return 0 48 | } 49 | 50 | function params_parse_command_line() 51 | { 52 | # return 0 upon success, 1 if help 53 | 54 | while true; do 55 | if [ -z "$1" ]; then 56 | break 57 | fi 58 | 59 | if [ "$1" == "--help" -o "$1" == "-h" ]; then 60 | return 1 61 | fi 62 | 63 | local param_name 64 | 65 | if [[ $1 == --* ]]; then 66 | param_name=${1/--/} 67 | [ -n ${params_list[$param_name]} ] || param_name=${params_short_to_long[$param_name]} 68 | shift 1 69 | elif [[ $1 == -* ]]; then 70 | local param_short_name=${1/-/} 71 | param_name=${params_short_to_long[$param_short_name]} 72 | [ -n "$param_name" ] || param_name=$param_short_name 73 | shift 1 74 | else 75 | params_skipped_list[$1]="skipped" 76 | shift 1 77 | continue 78 | fi 79 | 80 | local param_type=${params_type[$param_name]} 81 | 82 | if [ -z $param_type ]; then 83 | echo "Skipping parameter: $param_name, no such option" 84 | continue 85 | fi 86 | 87 | local variable_name=${params_var[$param_name]} 88 | 89 | if [ -n "$variable_name" ]; then 90 | case $param_type in 91 | ${params_types[boolean]}) 92 | declare -g $variable_name="true" 93 | ;; 94 | expect_value) 95 | echo "Param: $param_name = $1" 96 | declare -g $variable_name=$1 97 | shift 1 98 | ;; 99 | *) 100 | ;; 101 | esac 102 | fi 103 | done 104 | } 105 | 106 | function params_usage() 107 | { 108 | local name 109 | local short_form 110 | local initial_line=$1 111 | 112 | if [ -n "$initial_line" ]; then 113 | printf "\n" 114 | printf "$initial_line\n" 115 | printf "\n" 116 | fi 117 | 118 | printf "\t %-20s %-6s %-10s %s\n" \ 119 | "Name" " " "Default" "Description" 120 | 121 | printf "\t %-20s %-6s %-10s %s\n" \ 122 | "¯¯¯¯ " " " "¯¯¯¯¯¯¯ " "¯¯¯¯¯¯¯¯¯¯¯" 123 | 124 | for name in "${!params_list[@]}"; do 125 | short_form=${params_short[$name]} 126 | 127 | printf "\t--%-20s -%-6s %-10s %s\n" \ 128 | "${name}" "${short_form}" "${params_default[$name]}" "${params_desc[$name]}" 129 | done 130 | 131 | printf "\n" 132 | } 133 | -------------------------------------------------------------------------------- /src/main/groovy/generator/Utils.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class Utils { 4 | private static ant = new AntBuilder() 5 | private static rand = (Config.seed == null ? new Random() : new Random(Config.seed)); 6 | private static predefinedNames 7 | 8 | private static loadNamesFromFile() { 9 | try { 10 | def url = Utils.class.getResource("/predefined-names.txt") 11 | 12 | if (url == null) { 13 | println "Unable to find predefined-names.txt" 14 | return 15 | } 16 | 17 | def file = new File(url.toURI()) 18 | 19 | if (!file.canRead()) { 20 | println "Unable to read %file, from url: $url" 21 | return 22 | } 23 | 24 | predefinedNames = file.text.readLines() 25 | } 26 | catch(Exception e) { 27 | println "Error reading predefined-names.txt" 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | private static namesOfJavaStuff = [ 33 | "Strategy", "Factory", "Singletone", "Builder", "Aadapter", 34 | "Bridge", "Manager", "Util", "Helper", "Resource", 35 | "Data", "Entity", "Convertor", "Compressor", "Handler", 36 | "Facade", "Composite", "Concurrent", "Optimizer", "Syncer", 37 | "Runner", "Composer", "Navigator", "Worker", "Migrator", 38 | "Generator", "Compiler", "Destroyer", "Executor", "Thread", 39 | "Switcher", "Loader", "Dumper", "Initializer", "Interface", 40 | "Delegator", "Logger", "Monitor", "Reporter", "Killer" 41 | ] 42 | 43 | private static generateName(prefix = "", suffix = "", length = 10, capital = true, random = false) { 44 | def preserveWord = ["new", "else", "try", "if", "for", "do", "while", "return", "private", "package", "import", "false", "null", 45 | "int", "double", "bool", "short", "char", "long", "case", "static", "public", "class", "switch", "true", "byte", "enum"] 46 | 47 | def generate = { 48 | def randomChars 49 | 50 | if (predefinedNames == null || random) 51 | { 52 | randomChars = generateRandomChars(length) 53 | } 54 | else 55 | { 56 | randomChars = generateFunnyName(length) 57 | } 58 | 59 | if (capital) { 60 | randomChars[0] = Character.toUpperCase(randomChars[0]) 61 | } else { 62 | randomChars[0] = Character.toLowerCase(randomChars[0]) 63 | } 64 | 65 | def randomString = randomChars.join("") 66 | } 67 | 68 | def randomString = generate() 69 | 70 | while (randomString in preserveWord) { 71 | randomString = generate() 72 | } 73 | 74 | return "$prefix$randomString$suffix" 75 | } 76 | 77 | private static generateRandomChars(length) 78 | { 79 | return (0..length).collect { 80 | return (char)(rand.nextInt(26) + 97) 81 | } 82 | } 83 | 84 | private static usedNames = [].toSet() 85 | 86 | private static generateFunnyName(length) { 87 | def availableNamesSize = predefinedNames.size() * namesOfJavaStuff.size() 88 | 89 | while (true) { 90 | if (usedNames.size() >= (availableNamesSize - 1000)) { 91 | return generateRandomChars(length) 92 | } 93 | 94 | def randomNameIndex = rand.nextInt(predefinedNames.size()) 95 | def javaStuffIndex = rand.nextInt(namesOfJavaStuff.size()) 96 | def predefinedName = predefinedNames[randomNameIndex] 97 | def javaStuff = namesOfJavaStuff[javaStuffIndex] 98 | 99 | def generatedName = predefinedName + javaStuff 100 | 101 | if (usedNames.contains(generatedName)) { 102 | continue 103 | } 104 | 105 | usedNames.add(generatedName) 106 | 107 | return generatedName.toCharArray() 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/groovy/generator/EntryPointGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class EntryPointGenerator { 4 | private static write(outputDir, switcherClassName) { 5 | writeEntrypointSwitcher(outputDir) 6 | writeEntrypointsCallable(outputDir, switcherClassName) 7 | } 8 | 9 | private static writeEntrypointSwitcher(outputDir) { 10 | def entrypointSwitcherFile = new File("$outputDir/generated/EntrypointSwitcher.java") 11 | entrypointSwitcherFile.write(generateEntrypointSwitcher()) 12 | } 13 | 14 | private static generateEntrypointSwitcher() { 15 | def lines = ""; 16 | 17 | lines += "package generated;\n" 18 | lines += "\n" 19 | lines += "import helpers.Config;\n" 20 | lines += "import helpers.Context;\n" 21 | lines += "import java.util.concurrent.Callable;\n" 22 | lines += "\n" 23 | lines += "public class EntrypointSwitcher\n" 24 | lines += "{\n" 25 | lines += " public static Callable randomCallable() throws Exception\n" 26 | lines += " {\n" 27 | lines += " int entrypointIndex = Config.get().getRandom().nextInt(${Config.entryPointNum}) + 1;\n" 28 | lines += "\n" 29 | lines += " switch (entrypointIndex)\n" 30 | lines += " {\n" 31 | lines += addCases() 32 | lines += " }\n" 33 | lines += " return null;\n" 34 | lines += " }\n" 35 | lines += "}\n" 36 | 37 | return lines 38 | } 39 | 40 | private static writeEntrypointsCallable(outputDir, switcherClassName) { 41 | for (int i = 1; i <= Config.entryPointNum; i++) { 42 | def entrypointCallableFile = new File("$outputDir/generated/EntrypointCallable${i}.java") 43 | 44 | entrypointCallableFile.write(generateEntrypointsCallable(i, switcherClassName)) 45 | } 46 | } 47 | 48 | private static addCallToSwitcher(i, switcherClassName) { 49 | def lines = ""; 50 | 51 | // if (i % 2 == 0) { 52 | // lines += " try\n" 53 | // lines += " {\n" 54 | // lines += " ${switcherClassName}.call();\n" 55 | // lines += " }\n" 56 | // lines += " catch (Exception e) \n" 57 | // lines += " {\n" 58 | // lines += " //e.printStackTrace();\n" 59 | // lines += " }\n" 60 | // } else { 61 | lines += " ${switcherClassName}.call();\n" 62 | // } 63 | 64 | return lines 65 | } 66 | 67 | private static generateEntrypointsCallable(i, switcherClassName) { 68 | return """ 69 | package generated; 70 | 71 | import helpers.Config; 72 | import helpers.Context; 73 | import java.util.concurrent.Callable; 74 | import org.slf4j.MDC; 75 | 76 | public class EntrypointCallable${i} implements Callable { 77 | public Object call() throws Exception { 78 | String serverName = System.getProperty("takipi.server.name"); 79 | String agentName = System.getProperty("takipi.name"); 80 | String deploymentName = System.getProperty("takipi.deployment.name"); 81 | 82 | MDC.put("server", serverName); 83 | MDC.put("agent", agentName); 84 | MDC.put("deployment", deploymentName); 85 | 86 | long startTime = System.currentTimeMillis(); 87 | try { 88 | Config.get().entryPointIndex.set($i); 89 | ${addCallToSwitcher(i, switcherClassName)} 90 | } 91 | finally { 92 | helpers.StatsReporter.get().reportLatency(System.currentTimeMillis() - startTime); 93 | } 94 | return null; 95 | } 96 | } 97 | 98 | """; 99 | } 100 | 101 | private static addCases() { 102 | def lines = ""; 103 | 104 | for (int i = 1; i <= Config.entryPointNum; i++) { 105 | lines += " case ${i}: return new EntrypointCallable${i}();\n" 106 | } 107 | 108 | return lines 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/EventsSpot.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import java.io.File; 4 | import java.util.Random; 5 | import java.io.FileReader; 6 | import java.io.FileOutputStream; 7 | import java.io.BufferedReader; 8 | 9 | public class EventsSpot { 10 | public static Random rand = Config.get().getRandom(); 11 | 12 | public static boolean shouldFireEvent(File spotDataDir, Context context) { 13 | int currentLuck = Math.abs(rand.nextInt() % 100); 14 | Integer spotPrecentage = loadSpotData(spotDataDir, 15 | context.entryPointId, context.classId, context.methodId, context.instructionIndex); 16 | 17 | if (spotPrecentage == null) 18 | { 19 | spotPrecentage = generateSpotData(); 20 | saveSpotData(spotDataDir, context.entryPointId, context.classId, context.methodId, context.instructionIndex, spotPrecentage); 21 | } 22 | 23 | context.lastSpotPrecentage = spotPrecentage; 24 | 25 | return currentLuck < spotPrecentage; 26 | } 27 | 28 | private static int generateSpotData() 29 | { 30 | int spotPurpose = Math.abs(rand.nextInt() % 100); 31 | 32 | if (spotPurpose < 50) 33 | { 34 | return 0; 35 | } 36 | 37 | if (spotPurpose > 95) 38 | { 39 | return 100; 40 | } 41 | 42 | int spotStrengh = 10 - (spotPurpose % 10); 43 | int spotLuck = Math.abs(rand.nextInt() % 100); 44 | 45 | return Math.abs(spotLuck % (spotPurpose / spotStrengh)); 46 | } 47 | 48 | private static Integer loadSpotData(File spotDataDir, int entryPointId, int classId, int methodId, int instructionIndex) 49 | { 50 | File spotDataFile = getSpotDataFile(spotDataDir, entryPointId, classId, methodId, instructionIndex); 51 | 52 | if (spotDataFile == null) { 53 | return null; 54 | } 55 | 56 | if (!spotDataFile.canRead()) { 57 | return null; 58 | } 59 | 60 | FileReader fileReader = null; 61 | BufferedReader bufferedReader = null; 62 | 63 | try { 64 | fileReader = new FileReader(spotDataFile); 65 | bufferedReader = new BufferedReader(fileReader); 66 | 67 | String spotPrecentageLine = bufferedReader.readLine(); 68 | 69 | if (spotPrecentageLine == null) { 70 | return null; 71 | } 72 | 73 | return Integer.parseInt(spotPrecentageLine); 74 | } catch (Exception e) { 75 | e.printStackTrace(); 76 | return null; 77 | } finally { 78 | try { 79 | if (bufferedReader != null) { 80 | bufferedReader.close(); 81 | } 82 | if (fileReader != null) { 83 | fileReader.close(); 84 | } 85 | } catch (Exception e) { } 86 | } 87 | } 88 | 89 | private static boolean saveSpotData(File spotDataDir, int entryPointId, int classId, int methodId, int instructionIndex, int spotPrecentage) 90 | { 91 | File spotDataFile = getSpotDataFile(spotDataDir, entryPointId, classId, methodId, instructionIndex); 92 | 93 | if (spotDataFile == null) { 94 | return false; 95 | } 96 | 97 | FileOutputStream out = null; 98 | 99 | try { 100 | out = new FileOutputStream(spotDataFile); 101 | out.write(Integer.toString(spotPrecentage).getBytes()); 102 | return true; 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | return false; 106 | } finally { 107 | try { 108 | if (out != null) { 109 | out.close(); 110 | } 111 | } catch (Exception e) { } 112 | } 113 | } 114 | 115 | public static File getSpotDataFile(File spotDataDir, int entryPointId, int classId, int methodId, int instructionIndex) { 116 | spotDataDir.mkdirs(); 117 | 118 | if (!spotDataDir.isDirectory()) { 119 | System.out.println("Spot dir is not a directory " + spotDataDir); 120 | return null; 121 | } 122 | 123 | return new File(spotDataDir, entryPointId + ":" + classId + ":" + methodId + ":" + instructionIndex); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /scripts/version-support.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import sys 6 | import requests 7 | 8 | 9 | class VersionSupportCLI(): 10 | 11 | def __init__(self): 12 | self.parser = argparse.ArgumentParser() 13 | 14 | # Commands: Each will return a value to stdout for JenkinsPipeline 15 | self.parser.add_argument('--get-agent-version', action="store_true", dest="get_agent_version") 16 | self.parser.add_argument('--get-version', action="store_true", dest="get_version") 17 | self.parser.add_argument('--check-docker-tag', action="store_true", dest="check_docker_tag") 18 | 19 | # Additional Options: 20 | self.parser.add_argument('--tag', help='Docker Tag to Check for if exists') 21 | self.parser.add_argument('--registry', default='dockerhub') 22 | self.parser.add_argument('--repository', default='overops-java-bullshifier') 23 | self.parser.add_argument('--username') 24 | self.parser.add_argument('--token') 25 | 26 | 27 | rootdir, _ = os.path.split(os.path.dirname(os.path.realpath(__file__))) 28 | pass 29 | 30 | def run(self): 31 | 32 | args = self.parser.parse_args() 33 | result = "" 34 | 35 | try: 36 | if args.get_version: 37 | result = self.get_version() 38 | pass 39 | elif args.get_agent_version: 40 | result = self.get_latest_hosted_agent_version() 41 | pass 42 | elif args.check_docker_tag: 43 | if args.registry == 'dockerhub': 44 | result = self.check_docker_hub_tags( args.repository, args.tag ) 45 | else: 46 | result = self.check_local_docker_tags( args.registry, args.repository, args.username, 47 | args.token, args.tag) 48 | pass 49 | except Exception as e: 50 | # Whatever went wrong exit with an error code. 51 | sys.exit(1) 52 | 53 | print(result.strip()) 54 | pass 55 | 56 | ''' 57 | Pulls the version from the VERSION. 58 | ''' 59 | def get_version(self): 60 | return open('VERSION',mode='r').read().strip() 61 | ''' 62 | Pulls the latest agent version from public hosted site. 63 | ''' 64 | def get_latest_hosted_agent_version(self): 65 | res = requests.get("https://s3.amazonaws.com/app-takipi-com/deploy/linux/takipi-agent-latest-version") 66 | return res.text 67 | 68 | ''' 69 | Checks a given tag against docker hub using no auth. Based on V1 Docker registry spec. 70 | 71 | returns: true if tag is found. 72 | ''' 73 | def check_docker_hub_tags(self, repository_name, tag): 74 | 75 | r = requests.get(f"https://registry.hub.docker.com/v1/repositories/overops/{repository_name}/tags") 76 | 77 | for info in r.json(): 78 | if info["name"] == tag: 79 | return 'true' 80 | 81 | return 'false' 82 | 83 | ''' 84 | Checks a given tag against a local artifactory registry. Output from this command is described here: 85 | 86 | https://www.jfrog.com/confluence/display/JCR6X/JFrog+Container+Registry+REST+API#JFrogContainerRegistryRESTAPI-ListDockerTags 87 | 88 | returns: true if tag is found. 89 | ''' 90 | def check_local_docker_tags(self, registry_url, repository_name, username, token, tag): 91 | 92 | url = f"{registry_url.rstrip('/')}/v2/{repository_name}/tags/list" 93 | r = requests.get(url, auth=(username, token)) 94 | 95 | for t in r.json()['tags']: 96 | if t == tag: 97 | return 'true' 98 | 99 | return 'false' 100 | 101 | if __name__ == "__main__": 102 | cli = VersionSupportCLI() 103 | cli.run() 104 | pass -------------------------------------------------------------------------------- /src/main/groovy/generator/IoCpuIntensiveLogicGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | import java.util.concurrent.Callable 4 | import java.util.concurrent.Executors 5 | 6 | public class IoCpuIntensiveLogicGenerator { 7 | static generate() { 8 | if (Config.ioCpuIntensiveMatrixSize) { 9 | return ""; 10 | } 11 | 12 | return """ 13 | int maxFiles = $Config.ioCpuIntensiveFileLimit; 14 | int matrixSize = $Config.ioCpuIntensiveMatrixSize; 15 | 16 | // random matrix 17 | int[][] matrix = new int[matrixSize][matrixSize]; 18 | java.util.Random rand = new java.util.Random(); 19 | for (int i = 0; i < matrixSize ; i++) { 20 | for (int j = 0; j < matrixSize ; j++) { 21 | matrix[i][j] = rand.nextInt(); 22 | } 23 | } 24 | 25 | // files 26 | String directoryName = "output"; 27 | java.io.File directory = new java.io.File(directoryName); 28 | directory.mkdirs(); 29 | String filePrefix = "matrix_" + java.lang.Thread.currentThread().currentThread().getId() + "_"; 30 | String pathPrefix = "output/" + filePrefix; 31 | 32 | // find largest file number 33 | int largestFileIndex = -1; 34 | java.io.File[] files = directory.listFiles(); 35 | for (java.io.File file : files) { 36 | if (file.getName().startsWith(filePrefix)) 37 | { 38 | String fileSuffixNumber = file.getName().substring(filePrefix.length()); 39 | int number = Integer.parseInt(fileSuffixNumber); 40 | 41 | if (largestFileIndex < number) { 42 | largestFileIndex = number; 43 | } 44 | } 45 | } 46 | 47 | // init default old matrix 48 | int[][] oldMatrix = new int[matrixSize][matrixSize]; 49 | for (int i = 0; i < matrixSize; i++) { 50 | for (int j = 0 ; j < matrixSize ; j++) { 51 | oldMatrix[i][j] = 0; 52 | 53 | if (i == j) { 54 | oldMatrix[i][j] = 1; 55 | } 56 | } 57 | } 58 | 59 | // read random old matrix 60 | int randomOldFileIndex = 0; 61 | 62 | if (largestFileIndex > 0) { 63 | randomOldFileIndex = rand.nextInt(largestFileIndex); 64 | } 65 | 66 | java.io.File oldFile = new java.io.File(pathPrefix + (randomOldFileIndex)); 67 | 68 | if ((largestFileIndex > 0) && (oldFile.exists())) { 69 | java.io.BufferedReader br = null; 70 | 71 | try { 72 | br = new java.io.BufferedReader(new java.io.FileReader(oldFile)); 73 | String line = br.readLine(); 74 | int lineNumber = 0 ; 75 | 76 | while(line != null) { 77 | String[] splitted = line.split(" "); 78 | 79 | if (splitted.length != matrixSize) { 80 | break; 81 | } 82 | 83 | for (int i = 0 ; i < matrixSize ; i++) { 84 | oldMatrix[i][lineNumber] = java.lang.Integer.parseInt(splitted[i]); 85 | } 86 | 87 | lineNumber++; 88 | if (lineNumber >= matrixSize) { 89 | break; 90 | } 91 | 92 | line = br.readLine(); 93 | } 94 | } 95 | catch (Exception e) { 96 | e.printStackTrace(); 97 | } 98 | finally { 99 | if (br != null) 100 | { 101 | try 102 | { 103 | br.close(); 104 | } 105 | catch (Exception e) 106 | { 107 | e.printStackTrace(); 108 | } 109 | } 110 | } 111 | } 112 | 113 | // multiply matrices 114 | int[][] resultMatrix = new int[matrixSize][matrixSize]; 115 | 116 | for (int i = 0 ; i < matrixSize ; i++) { 117 | for (int j = 0 ; j < matrixSize ; j++) { 118 | int res = 0; 119 | for (int k = 0 ; k < matrixSize ; k++) { 120 | res += oldMatrix[i][k] * matrix[k][j]; 121 | } 122 | 123 | resultMatrix[i][j] = res; 124 | } 125 | } 126 | 127 | // write new matrix 128 | int newIndex = ((largestFileIndex + 1) % maxFiles); 129 | 130 | java.io.File file = new java.io.File(pathPrefix + (newIndex)); 131 | java.io.BufferedWriter bw = null; 132 | 133 | try { 134 | bw = new java.io.BufferedWriter(new java.io.FileWriter(file)); 135 | for (int i = 0; i < matrixSize; i++) { 136 | for (int j = 0; j < matrixSize; j++) { 137 | bw.write(java.lang.Integer.toString(resultMatrix[i][j])); 138 | bw.write(" "); 139 | } 140 | bw.newLine(); 141 | bw.flush(); 142 | } 143 | } 144 | catch (Exception e) { 145 | e.printStackTrace(); 146 | } 147 | finally { 148 | if (bw != null) { 149 | try { 150 | bw.close(); 151 | } 152 | catch (Exception e) { 153 | e.printStackTrace(); 154 | } 155 | } 156 | } 157 | """ 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/Config.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import java.io.File; 4 | import java.util.Random; 5 | import java.util.Arrays; 6 | import java.util.Calendar; 7 | import java.util.Date; 8 | 9 | public class Config 10 | { 11 | public static Random rand = new Random(); 12 | 13 | public static Random getRandom() { 14 | return rand; 15 | } 16 | 17 | private volatile static Config instance; 18 | 19 | public static Config get() { 20 | if (instance != null) { 21 | return instance; 22 | } 23 | 24 | synchronized (Config.class) { 25 | if (instance != null) { 26 | return instance; 27 | } 28 | 29 | instance = new Config(); 30 | 31 | return instance; 32 | } 33 | } 34 | 35 | public int framesRangeFrom = 0; 36 | public int framesRangeTo = 10; 37 | public File stickyPathDir; 38 | public File eventSpotDir; 39 | public ThreadLocal entryPointIndex = new ThreadLocal<>(); 40 | 41 | public Config() 42 | { 43 | 44 | } 45 | 46 | public static void setFramesRangeFromCommandLine(int[] framesCountRange) { 47 | if ((framesCountRange == null) || 48 | (framesCountRange.length != 2)) { 49 | System.out.println("Invalid frames range " + Arrays.toString(framesCountRange)); 50 | return; 51 | } 52 | 53 | int from = framesCountRange[0]; 54 | int to = framesCountRange[1]; 55 | 56 | Config.get().setFramesRange(from, to); 57 | } 58 | 59 | public void setFramesRange(int from, int to) { 60 | if (from < 0) { 61 | from = 0; 62 | } 63 | 64 | if (to < from) { 65 | to = from; 66 | } 67 | 68 | this.framesRangeFrom = from; 69 | this.framesRangeTo = to; 70 | } 71 | 72 | public void setStickyPathsDir(String stickyPathDirPath) { 73 | if (stickyPathDirPath == null) { 74 | System.out.println("Invalid stickyPathDirPath, null"); 75 | return; 76 | } 77 | 78 | File stickyPathDir = new File(stickyPathDirPath); 79 | stickyPathDir.mkdirs(); 80 | 81 | if (!stickyPathDir.isDirectory()) { 82 | System.out.println("Provided sticky path dir is not directory: " + stickyPathDir); 83 | return; 84 | } 85 | 86 | this.stickyPathDir = stickyPathDir; 87 | } 88 | 89 | public File getStickyPathsDir() { 90 | return stickyPathDir; 91 | } 92 | 93 | public int getStickyPath(int classId, int methodId, int maxNumber) { 94 | if (stickyPathDir == null) { 95 | return rand.nextInt(maxNumber); 96 | } 97 | 98 | int result = StickyPathHelper.getMethodToCall(stickyPathDir, classId, methodId); 99 | 100 | if (result == -1) { 101 | int randomNumber = rand.nextInt(maxNumber); 102 | 103 | if (!StickyPathHelper.persistMethodToCall( 104 | stickyPathDir, classId, methodId, randomNumber)) { 105 | System.out.println("Error persisiting sticky path"); 106 | } 107 | 108 | result = randomNumber; 109 | } 110 | 111 | return result; 112 | } 113 | 114 | public void setEventSpotDir(String eventSpotDirPath) { 115 | if (eventSpotDirPath == null) { 116 | System.out.println("Invalid eventSpotDirPath, null"); 117 | return; 118 | } 119 | 120 | File eventSpotDir = new File(eventSpotDirPath); 121 | eventSpotDir.mkdirs(); 122 | 123 | if (!eventSpotDir.isDirectory()) { 124 | System.out.println("Provided event spot dir is not directory: " + eventSpotDir); 125 | return; 126 | } 127 | 128 | this.eventSpotDir = eventSpotDir; 129 | } 130 | 131 | public File getEventSpotDir() { 132 | return eventSpotDir; 133 | } 134 | 135 | public boolean shouldFireEvent(Context context) { 136 | if (eventSpotDir == null) { 137 | return context.framesDepth > framesRangeTo; 138 | } 139 | 140 | return EventsSpot.shouldFireEvent(eventSpotDir, context); 141 | } 142 | 143 | public boolean shouldRunAway(Context context) { 144 | return context.framesDepth > framesRangeTo; 145 | } 146 | 147 | public void updateContext(Context context, int entryPointId, int classId, int methodId) { 148 | context.framesDepth++; 149 | context.entryPointId = entryPointId; 150 | context.classId = classId; 151 | context.methodId = methodId; 152 | context.addPath(classId, methodId); 153 | Context.incInvCount(context); 154 | } 155 | 156 | public boolean shouldWriteLogInfo(Context context) { 157 | return true; 158 | } 159 | 160 | public boolean shouldWriteLogWarn(Context context) { 161 | return false; 162 | } 163 | 164 | public boolean shouldWriteLogError(Context context) { 165 | return true; 166 | } 167 | 168 | public boolean shouldSuicide() { 169 | return false; 170 | } 171 | 172 | public boolean shouldDoIoCpuIntensiveLogic(Context context) { 173 | return false; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/main/groovy/generator/LocalsGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class LocalsGenerator 4 | { 5 | private static deepConf=2; 6 | private static tabs = " "; 7 | 8 | private static generateLocals() { 9 | def result = []; 10 | result += generateLocalsInternal("root", 2); 11 | return result; 12 | } 13 | 14 | private static generateLocalsInternal(name, deep) { 15 | def num = Utils.rand.nextInt(4) 16 | 17 | if (deep <= deepConf) { 18 | switch (num) { 19 | case (0): return generateSet(name ,deep); 20 | case (1): return generateList(name ,deep); 21 | case (2): return generateArray(name ,deep); 22 | case (3): return generateMap(name ,deep); 23 | } 24 | } else { 25 | num = Utils.rand.nextInt(4) 26 | 27 | switch (num) { 28 | case (0): return generateString(name); 29 | case (1): return generateInt(name); 30 | case (2): return generateLong(name); 31 | case (3): return generateBoolean(name); 32 | } 33 | } 34 | 35 | return []; 36 | } 37 | 38 | private static generateSet(setName ,deep) { 39 | def result = ["Set $setName = new HashSet();"] 40 | result += generateSetInternal("${setName}", deep) 41 | return result; 42 | } 43 | 44 | private static generateSetInternal(name, deep) { 45 | def result = []; 46 | def limit = Utils.rand.nextInt(2)+1; 47 | 48 | for (int i = 0; i < limit; i++) { 49 | def localValueName = Utils.generateName("val", "", 10, true, true); 50 | result += generateLocalsInternal(localValueName, deep + 1); 51 | result += "${name}.add($localValueName);" 52 | } 53 | 54 | result += "" 55 | return result; 56 | } 57 | 58 | private static generateList(listName, deep) { 59 | def result = ["List $listName = new LinkedList();"] 60 | result += generateListInternal("${listName}", deep) 61 | return result; 62 | } 63 | 64 | private static generateListInternal(name, deep) { 65 | def result = []; 66 | def limit = Utils.rand.nextInt(2)+1; 67 | 68 | for (int i = 0; i < limit; i++) { 69 | def localValueName = Utils.generateName("val", "", 10, true, true); 70 | result += generateLocalsInternal(localValueName, deep + 1); 71 | result += "${name}.add($localValueName);" 72 | } 73 | 74 | result += "" 75 | return result; 76 | } 77 | 78 | private static generateArray(arrName, deep) { 79 | def size = Utils.rand.nextInt(10)+2; 80 | def result = ["Object[] $arrName = new Object[$size];"] 81 | result += generateArrayInternal("${arrName}","${size}", deep) 82 | return result; 83 | } 84 | 85 | private static generateArrayInternal(arrName ,size ,deep) { 86 | def localValueName = Utils.generateName("val", "", 10, true, true); 87 | 88 | def result = []; 89 | 90 | result += generateLocalsInternal(localValueName, deep + 1); 91 | result += "${tabs}$arrName[0] = $localValueName;" 92 | result += "for (int i = 1; i < $size; i++)" 93 | result += "{" 94 | result += "${tabs}$arrName[i] = Config.get().getRandom().nextInt(1000);" 95 | result += "}" 96 | result += "" 97 | 98 | return result; 99 | } 100 | 101 | private static generateMap(mapName , deep) { 102 | def result = ["Map $mapName = new HashMap();"] 103 | result += generateMapInternal("${mapName}", deep) 104 | return result; 105 | } 106 | 107 | private static generateMapInternal(mapName, deep) { 108 | def result = []; 109 | def limit = Utils.rand.nextInt(2)+1; 110 | 111 | for (int i = 0; i < limit; i++) { 112 | def localValueName = Utils.generateName("mapVal", "", 10, true, true) 113 | def localKeyName = Utils.generateName("mapKey", "", 10, true, true) 114 | result += generateLocalsInternal(localValueName, deep + 1); 115 | result += generateLocalsInternal(localKeyName, deep + 1); 116 | result += "${mapName}.put(\"$localValueName\",\"$localKeyName\" );" 117 | } 118 | 119 | result += "" 120 | return result; 121 | } 122 | 123 | private static generateString(stringName) { 124 | def result = []; 125 | def varStrValue = Utils.generateName("Str", "", 10, true, true); 126 | result += "String $stringName = \"$varStrValue\";" 127 | result += "" 128 | return result; 129 | } 130 | 131 | private static generateInt(intName) { 132 | def result = []; 133 | def varIntValue = "${Utils.rand.nextInt(1000)}"; 134 | result += "int $intName = $varIntValue;" 135 | result += "" 136 | return result; 137 | } 138 | 139 | private static generateLong(longName) { 140 | def result = []; 141 | def l = "L" 142 | def varLongValue = "${Utils.rand.nextLong()}"; 143 | result += "long $longName = $varLongValue$l;" 144 | result += "" 145 | return result; 146 | } 147 | 148 | private static generateBoolean(boolName) { 149 | def result = []; 150 | def varBooleanValue = "${Utils.rand.nextBoolean()}" 151 | result += "boolean $boolName = $varBooleanValue;" 152 | result += "" 153 | return result; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | def javaBullshifierVersion = '' 2 | def agentVersion = '' 3 | def fullTag = '' 4 | def tagCheck = '' 5 | def javaBullshifierTags = [] 6 | def dockerOptions= '--network=host' 7 | def imageName = 'overops-java-bullshifier' 8 | def localRepoPath = ('docker/' + imageName) 9 | 10 | pipeline { 11 | 12 | parameters { 13 | booleanParam(name: 'FORCE_PUBLISH', defaultValue: false, description: 'Forces a build and publish') 14 | string(name: 'VERSION', defaultValue: 'latest', description:'Build and publish a specific agent version. Note: Only Full version tag is published if not latest.') 15 | booleanParam(name: 'PUBLISH_TO_AWS', defaultValue: true, description: 'Publish to AWS Registry') 16 | } 17 | 18 | environment { 19 | awsRegCred = 'ecr:us-east-1:aws-takipi-dev-service' 20 | registryCred = 'container-registry-build-guy' 21 | gitCred = 'build-guy' 22 | } 23 | 24 | agent any 25 | stages { 26 | stage('Cloning Git') { 27 | steps { 28 | git([url: 'https://github.com/takipi/java-bullshifier.git', branch: 'master', credentialsId: gitCred ]) 29 | } 30 | } 31 | 32 | stage('Determine versions and tags') { 33 | environment { 34 | LOCAL_REGISTRY_CREDS = credentials("${registryCred}") 35 | } 36 | 37 | steps { 38 | script{ 39 | // Determine the Java Bullshifier Version (Reads local VERSION file) 40 | javaBullshifierVersion = sh(returnStdout: true, script: 'python3 ./scripts/version-support.py --get-version').trim() 41 | 42 | // Determine the latest agent version and add latest tags. otherwise only use the agent parameter. 43 | // Note: When setting the Agent Version as param only the full tag is pushed. 44 | if ( params.AGENT_VERSION == 'latest' ) { 45 | agentVersion = sh(returnStdout: true, script: 'python3 ./scripts/version-support.py --get-agent-version').trim() 46 | javaBullshifierTags.add('latest') 47 | javaBullshifierTags.add(javaBullshifierVersion) 48 | } else { 49 | agentVersion = params.AGENT_VERSION 50 | } 51 | 52 | // Add full unique tag i.e. 2.13-agent-4.54.0 53 | fullTag = (javaBullshifierVersion + '-agent-' + agentVersion) 54 | javaBullshifierTags.add(fullTag) 55 | 56 | // Determine if the tag doesn't exists if not we should build and publish. 57 | registryAPIEndpoint = (env.LOCAL_DOCKER_REGISTRY_URL + '/artifactory/api/docker/docker') 58 | tagCheck = sh(returnStdout: true, script:"python3 ./scripts/version-support.py --check-docker-tag --tag ${fullTag} --repository ${imageName} --registry ${registryAPIEndpoint} --username \$LOCAL_REGISTRY_CREDS_USR --token \$LOCAL_REGISTRY_CREDS_PSW").trim() 59 | } 60 | } 61 | } 62 | 63 | stage('Build') { 64 | when { 65 | anyOf { 66 | // Run Build if forced or if the tag does not exists. 67 | expression { return params.FORCE_PUBLISH } 68 | expression { tagCheck == 'false' } 69 | } 70 | } 71 | 72 | steps { 73 | script { 74 | options = '' 75 | 76 | // Build using the latest agent or one passed in as a parameter. 77 | if ( params.AGENT_VERSION == 'latest' ) { 78 | options = (dockerOptions + ' .') 79 | } else { 80 | options = ( dockerOptions + ' --build-arg VERSION=' + params.AGENT_VERSION + ' .') 81 | } 82 | 83 | // Note: "building" two images in order to have correct image name for each registry 84 | // Second call is no-op but is done this way based on the docker plugin api limitations. 85 | dockerImage = docker.build( localRepoPath, options ) 86 | awsDockerImage = docker.build( imageName, options ) 87 | } 88 | } 89 | } 90 | 91 | stage('Publish Image') { 92 | when { 93 | anyOf { 94 | // Run Build if forced or if the tag does not exists. 95 | expression { return params.FORCE_PUBLISH } 96 | expression { tagCheck == 'false' } 97 | } 98 | } 99 | 100 | steps { 101 | script { 102 | docker.withRegistry(env.LOCAL_DOCKER_REGISTRY_URL, registryCred ) { 103 | for(String tag in javaBullshifierTags) { 104 | echo(tag) 105 | dockerImage.push(tag) 106 | } 107 | } 108 | 109 | // Publish image to private ECR 110 | if (params.PUBLISH_TO_AWS) { 111 | docker.withRegistry(env.AWS_TAKIPI_DEV_REGISTRY_URI, awsRegCred ) { 112 | for(String tag in javaBullshifierTags) { 113 | awsDockerImage.push(tag) 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | ![alt 'Java Bullishifier'](http://blog.takipi.com/wp-content/uploads/2016/11/bullishifier.png) 4 | 5 | An open source project by [OverOps](https://www.overops.com). 6 | 7 | [Visit the site to download a sample result](https://takipi.github.io/java-bullshifier) or [read more on the blog](http://blog.takipi.com/java-bullshifier-generate-massive-random-code-bases) 8 | 9 | ## Requirements 10 | * Groovy installed 11 | * Gradle installed 12 | * Java installed 13 | 14 | 15 | ## Installation 16 | * Download, unzip, and you’re ready to go 17 | 18 | 19 | ## Run settings 20 | * `./gradlew run` (default parameters, generates one jar with 10 classes) 21 | * `cd output && gradle fatJar` to build the generated project 22 | * `java -cp output/build/libs/tester.jar helpers.Main` to run it 23 | 24 | Or, you can simply run `./scripts/small.sh`, or `./scripts/big.sh`, with preconfigured run settings. 25 | 26 | 27 | ## Flags 28 | * `-Poutput-directory` (relative path to output directory) 29 | * `-Poutput-classes` (number of classes to generate) 30 | * `-Psubprojects` (number of jars to generate) 31 | 32 | Keep in mind that generating over 500 classes will take quite some time. Our biggest run had 20,000 classes, but it's better to keep this under 5,000. 33 | 34 | ## Running sub projects 35 | * `gradle build` (get a WAR file) 36 | * Go to `bin` 37 | * A shell script is created per project, root will run them all 38 | 39 | 40 | ## Advanced config 41 | There are some additional options that give you fine grained control over the generated code, but might mess it up, use at your own risk: 42 | * Low level config: `src/main/groovy/generator/Config.groovy` 43 | * Higher level config is available in the output folder. There are more options to add logging, and fine tune the behavior of the application but it’s experimental at the moment. 44 | 45 | 46 | 47 | If you’d like to learn more, feel free to reach out for a deeper walkthrough (hello@overops.com). Default settings are no logs, and an exception on every 10th frame in the call stack. 48 | 49 | 50 | ## Docker Quick start 51 | In simple cases the following command will allow for local execution of the image. If running backend and collector also in docker see "advance" networking section. 52 | 53 | ```console 54 | docker run -d --rm -e TAKIPI_COLLECTOR_HOST= -e TAKIPI_COLLECTOR_PORT=6060 -e TAKIPI_APPLICATION_NAME=java-bullshifier -e TAKIPI_DEPLOYMENT_NAME=deployment1 -e TAKIPI_SERVER_NAME=DEV -e COLOR=white/yellow/red/black overops-java-bullshifier:latest 55 | ``` 56 | Note: Depending if you built or pulled the image your Image name may vary! 57 | 58 | ## Docker: Advance Networking 59 | If running multiple components in separate docker images (i.e. Backend and collector), it is recommend running with a docker network to allow for communications: 60 | 61 | If not already created, create a docker network and start the image on the network: 62 | 63 | ```console 64 | docker network create --driver bridge overops 65 | 66 | docker run -d --rm --network overops -e TAKIPI_COLLECTOR_HOST= -e TAKIPI_COLLECTOR_PORT=6060 -e TAKIPI_APPLICATION_NAME=java-bullshifier -e TAKIPI_DEPLOYMENT_NAME=deployment1 -e TAKIPI_SERVER_NAME=DEV -e COLOR= overops-java-bullshifier:latest 67 | ``` 68 | Note: This assumes you have a collector running in docker with `--network overops --name overops-collector` 69 | 70 | The following table lists the configurable ENVS of the Java Bullshifier using `-e`: 71 | 72 | | Parameter | Description | Default | 73 | | -------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------| 74 | | `TAKIPI_COLLECTOR_HOST` | Collector hostname or K8s Service Name | `collector` | 75 | | `TAKIPI_COLLECTOR_PORT` | Collector port | `6060` | 76 | | `COLOR` | The plan of the Bulshifier - affect on how intense will be the load on the application - (Options: white/yellow/red/black) . | `white` | 77 | | `RUNNING_DURATION_HOURS` | The number of hours java-bullshifier app should be running | `0` | 78 | | `RUNNING_DURATION_MINUTES` | The number of minutes java-bullshifier app should be running | `5` | 79 | | `INERVAL_MILLIS` | Interval between events (millis) | `300` | 80 | | `GEN_SEED` | (Optional) Numerical value used to seed random functions when generating Java Application | | 81 | | `APP_SEED` | (Optional) Numerical value used to seed random functions when running the generated application | | 82 | | `TAKIPI_SERVER_NAME` | Override the server name used by the agent | `hostname` joined with index | 83 | | `TAKIPI_APPLICATION_NAME` | Override the application name used by the agent | `tester` or what is provided during gradle run with the `name` option | 84 | | `TAKIPI_DEPLOYMENT_NAME` | Override the deployment name used by the agent | hostname joined with app name and deployment seed/process count | 85 | | `TAKIPI_ENV_ID` | Set the environment name used by the agent | value of `TAKIPI_SERVER_NAME` | 86 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /src/dist/template/project/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -r script_dir=`cd "$( dirname "$0" )" && pwd` 4 | cd $script_dir 5 | 6 | source params.sh 7 | 8 | declare emulatorDataDir=emulator-data 9 | 10 | declare runInContainer="false" 11 | declare runningHours=0 12 | declare runningMinutes=1 13 | declare processesCount=5 14 | declare hostnamePrefix="hostname-" 15 | declare serversCount=5 16 | declare appsCount=2 17 | declare dryRun="false" 18 | declare processHeapSize=10m 19 | declare intervalMillis=5000 20 | declare extraJVMArgs="" 21 | declare sleepSeconds=0 22 | declare appType="Undefined" 23 | declare appUuid="ffffffff-ffff-ffff-ffff-ffffffffffff" 24 | declare seed=0 25 | 26 | function parse_command_line() 27 | { 28 | params_add "run-in-container" "ric" "$runInContainer" "runInContainer" "boolean" \ 29 | "Do not use nohup, and run 1 process always" 30 | 31 | params_add "processes-count" "pc" "$processesCount" "processesCount" "expect_value" \ 32 | "Number of processes to run" 33 | 34 | params_add "process-heap-size" "hs" "$processHeapSize" "processHeapSize" "expect_value" \ 35 | "The heap size of every Java process (both min and max)" 36 | 37 | params_add "interval-millis" "im" "$intervalMillis" "intervalMillis" "expect_value" \ 38 | "Interval between events (millis)" 39 | 40 | params_add "servers-count" "sc" "$serversCount" "serversCount" "expect_value" \ 41 | "Number of servers" 42 | 43 | params_add "apps-count" "ac" "$appsCount" "appsCount" "expect_value" \ 44 | "Number of apps" 45 | 46 | params_add "hostname-prefix" "host" "$hostnamePrefix" "hostnamePrefix" "expect_value" \ 47 | "A prefix to append to all server names" 48 | 49 | params_add "running-hours" "hours" "$runningHours" "runningHours" "expect_value" \ 50 | "The number of hours this app should be running" 51 | 52 | params_add "running-minutes" "min" "$runningMinutes" "runningMinutes" "expect_value" \ 53 | "The number of minutes this app should be running" 54 | 55 | params_add "jvm-args" "jvm" "$extraJVMArgs" "extraJVMArgs" "expect_value" \ 56 | "JVM arguments to be passed to the application" 57 | 58 | params_add "dry" "d" "$dryRun" "dryRun" "boolean" \ 59 | "Print commands to console, instead of actually running the apps" 60 | 61 | params_add "sleep-seconds" "ss" "$sleepSeconds" "sleepSeconds" "expect_value" \ 62 | "Seconds to wait before starting a new app" 63 | 64 | params_add "seed" "s" "$seed" "seed" "expect_value" \ 65 | "Seed for randomization within the app" 66 | 67 | if ! params_parse_command_line $@; then 68 | params_usage "Bullshifier run usage:" 69 | exit 0 70 | fi 71 | } 72 | 73 | function get_deployment_name() 74 | { 75 | local appName=$1 76 | local appDataDir=$2 77 | local deploymentSeed="0" 78 | 79 | if [ -r "$appDataDir/DEPLOYMENT_SEED" ]; then 80 | deploymentSeed=$(cat $appDataDir/DEPLOYMENT_SEED) 81 | fi 82 | 83 | echo "`hostname`-$appName-$deploymentSeed" 84 | } 85 | 86 | function run_bullshifiers() 87 | { 88 | parse_command_line $@ 89 | 90 | local millisInMinute=60000 91 | 92 | if [ -r "APP_TYPE" ]; then 93 | appType=$(cat APP_TYPE) 94 | fi 95 | 96 | if [ -r "APP_UUID" ]; then 97 | appUuid=$(cat APP_UUID) 98 | fi 99 | 100 | if [ "$runInContainer" == "true" ]; then 101 | processesCount=1 102 | fi 103 | 104 | if [[ "$intervalMillis" -lt "$millisInMinute" ]]; then 105 | let exceptionCount="$millisInMinute/$intervalMillis" 106 | let runningCount="($runningHours*60)+($runningMinutes%60)" 107 | else 108 | let exceptionCount="1" 109 | let MinutesCount="$intervalMillis/$millisInMinute" 110 | let runningCount="(($runningHours*60)+($runningMinutes%60))/$MinutesCount" 111 | fi 112 | 113 | if [ "$runningMinutes" == "0" -a "$runningHours" == "0" ];then 114 | runningCount=1 115 | exceptionCount=0 116 | fi 117 | 118 | for ((i=1;i<=$processesCount;i++)); do 119 | local serverIndex=$(($i%$serversCount)) 120 | local serverName="${hostnamePrefix}$serverIndex" 121 | if [ ! -z ${TAKIPI_SERVER_NAME} ]; then 122 | serverName=${TAKIPI_SERVER_NAME} 123 | fi 124 | 125 | local environmentName="" 126 | if [ ! -z ${TAKIPI_ENV_ID} ]; then 127 | environmentName=${TAKIPI_ENV_ID} 128 | fi 129 | 130 | local appIndex=$(($i%$appsCount)) 131 | local appName="$appType-$appIndex" 132 | if [ ! -z ${TAKIPI_APPLICATION_NAME} ]; then 133 | appName=${TAKIPI_APPLICATION_NAME} 134 | fi 135 | 136 | local appDataDir="$emulatorDataDir/$appName" 137 | mkdir -p "$appDataDir" 138 | 139 | local deploymentName=$(get_deployment_name $appName $appDataDir) 140 | if [ ! -z ${TAKIPI_DEPLOYMENT_NAME} ]; then 141 | deploymentName=${TAKIPI_DEPLOYMENT_NAME} 142 | fi 143 | 144 | appDataDir="$appDataDir/$deploymentName" 145 | 146 | local nameParams="-Dtakipi.server.name=$serverName -Dtakipi.application.name=$appName -Dtakipi.deployment.name=$deploymentName -Dtakipi.env.id=$environmentName" 147 | local javaHeapSize="-Xmx$processHeapSize -Xms$processHeapSize" 148 | local jarName="$script_dir/build/libs/${appType}.jar" 149 | local durationPlan="--run-count $runningCount --exceptions-count $exceptionCount --interval-millis $intervalMillis" 150 | local behaviourPlan="--sticky-path $appDataDir/stack-traces --events-spot $appDataDir/errors" 151 | local appConfig="--single-thread --hide-stacktraces --warmup-millis 0 --frames-range 50" 152 | if [ "$seed" != "0" ];then 153 | appConfig+=" --seed $seed" 154 | fi 155 | local jvmInternalParams="-XX:CICompilerCount=2 -XX:ParallelGCThreads=1" 156 | local command="$JAVA_HOME/bin/java $jvmInternalParams -Dapp.uuid=$appUuid $nameParams $javaHeapSize -jar $jarName $durationPlan $behaviourPlan $appConfig" 157 | 158 | if [ "$dryRun" == "false" ]; then 159 | if [ "$runInContainer" == "true" ]; then 160 | $command 161 | else 162 | nohup $command & 163 | sleep $sleepSeconds 164 | fi 165 | else 166 | echo "nohup $command &" 167 | echo "sleep $sleepSeconds" 168 | fi 169 | done 170 | } 171 | 172 | run_bullshifiers $@ 173 | -------------------------------------------------------------------------------- /src/dist/template/project/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save ( ) { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save ( ) { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/StatsReporter.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.lang.management.ManagementFactory; 7 | import java.lang.management.OperatingSystemMXBean; 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Modifier; 10 | import java.util.Arrays; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | import java.util.concurrent.atomic.AtomicInteger; 14 | import java.util.concurrent.atomic.AtomicLong; 15 | import java.util.concurrent.locks.Lock; 16 | import java.util.concurrent.locks.ReentrantReadWriteLock; 17 | 18 | public class StatsReporter { 19 | private static final long REPORT_INTERVAL_MILLIS = 10000l; 20 | private static final String REPORT_FILE_NAME = "report-stats.csv"; 21 | 22 | private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); 23 | 24 | // metrics not in use: "OpenFileDescriptorCount", "freeHeap", "FreeSwapSpaceSize", "maxHeap", 25 | // "MaxFileDescriptorCount", "TotalSwapSpaceSize", "heapSize", "ProcessCpuTime", , 26 | // "SystemCpuLoad", "CommittedVirtualMemorySize" 27 | // 28 | private static final String[] keys = { "reportTime", "tasksCount", "latency", "ProcessCpuLoad", "heapSize"}; 29 | 30 | private final File reportFile; 31 | 32 | private final Lock latencyGetLock; 33 | private final Lock latencyUpdateLock; 34 | 35 | private final AtomicLong latencyTotal; 36 | private final AtomicInteger latencyReportsCounter; 37 | 38 | private int taskCounter; 39 | private long lastTimeReported; 40 | 41 | private volatile static StatsReporter instance = null; 42 | 43 | private StatsReporter() 44 | { 45 | this.reportFile = new File(REPORT_FILE_NAME); 46 | 47 | ReentrantReadWriteLock multiReportLock = new ReentrantReadWriteLock(); 48 | this.latencyGetLock = multiReportLock.writeLock(); 49 | this.latencyUpdateLock = multiReportLock.readLock(); 50 | 51 | this.latencyTotal = new AtomicLong(); 52 | this.latencyReportsCounter = new AtomicInteger(); 53 | 54 | this.taskCounter = 0; 55 | this.lastTimeReported = 0; 56 | 57 | writeHeaderToFile(); 58 | } 59 | 60 | public static StatsReporter get() 61 | { 62 | if (instance == null) 63 | { 64 | synchronized (StatsReporter.class) 65 | { 66 | if (instance == null) 67 | { 68 | instance = new StatsReporter(); 69 | } 70 | } 71 | } 72 | 73 | return instance; 74 | } 75 | 76 | public void incTasksCompleted() { 77 | taskCounter++; 78 | } 79 | 80 | public void reportLatency(long latencyMillis) { 81 | latencyUpdateLock.lock(); 82 | 83 | try { 84 | latencyTotal.addAndGet(latencyMillis); 85 | latencyReportsCounter.incrementAndGet(); 86 | } 87 | finally { 88 | latencyUpdateLock.unlock(); 89 | } 90 | } 91 | 92 | public void generateReport() { 93 | long now = System.currentTimeMillis(); 94 | 95 | if (lastTimeReported >= (now - REPORT_INTERVAL_MILLIS)) { 96 | return; 97 | } 98 | 99 | doGenerateReport(); 100 | 101 | lastTimeReported = System.currentTimeMillis(); 102 | } 103 | 104 | private void doGenerateReport() { 105 | Map statMap = new HashMap(); 106 | 107 | statMap.put("reportTime", System.currentTimeMillis()); 108 | statMap.put("tasksCount", taskCounter); 109 | taskCounter = 0; 110 | 111 | statMap.put("latency", doLatency()); 112 | 113 | addHeapStats(statMap); 114 | 115 | // doesn't work well with java9 116 | // addMoreStats(statMap); 117 | 118 | // String jsonReport = toJson(statMap); 119 | String csvReport = toCsv(statMap); 120 | appendToFile(csvReport); 121 | } 122 | 123 | private long doLatency() 124 | { 125 | latencyGetLock.lock(); 126 | 127 | try { 128 | long totalLatency = latencyTotal.getAndSet(0); 129 | int count = latencyReportsCounter.getAndSet(0); 130 | 131 | if (count == 0) { 132 | return 0; 133 | } 134 | 135 | return totalLatency / count; 136 | } 137 | finally { 138 | latencyGetLock.unlock(); 139 | } 140 | } 141 | 142 | private static void addHeapStats(Map map) { 143 | Runtime runtime = Runtime.getRuntime(); 144 | 145 | map.put("heapSize", runtime.totalMemory()); 146 | map.put("maxHeap", runtime.maxMemory()); 147 | map.put("freeHeap", runtime.freeMemory()); 148 | } 149 | 150 | private void addMoreStats(Map map) { 151 | OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); 152 | 153 | String getPrefix = "get"; 154 | 155 | for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) { 156 | method.setAccessible(true); 157 | if (method.getName().startsWith(getPrefix) && Modifier.isPublic(method.getModifiers())) { 158 | Object value; 159 | try { 160 | value = method.invoke(operatingSystemMXBean); 161 | } 162 | catch (Exception e) { 163 | value = e; 164 | } 165 | 166 | String key = method.getName().substring(getPrefix.length()); 167 | map.put(key, value); 168 | } 169 | } 170 | } 171 | 172 | private String toCsv(Map statMap) { 173 | StringBuilder csv = new StringBuilder(""); 174 | 175 | for (String key : keys) { 176 | Object value = statMap.get(key); 177 | 178 | csv.append(value).append(", "); 179 | } 180 | 181 | csv.append(LINE_SEPARATOR); 182 | 183 | return csv.toString(); 184 | } 185 | 186 | private void writeHeaderToFile() 187 | { 188 | String header = Arrays.toString(keys); 189 | header = header.substring(1, header.length() -1) + "," + LINE_SEPARATOR; 190 | 191 | appendToFile(header, false); 192 | } 193 | 194 | private void appendToFile(String reportText) { 195 | appendToFile(reportText, true); 196 | } 197 | 198 | private void appendToFile(String reportText, boolean append) { 199 | FileWriter fw = null; 200 | BufferedWriter bw = null; 201 | 202 | try { 203 | fw = new FileWriter(reportFile, append); 204 | bw = new BufferedWriter(fw); 205 | bw.write(reportText); 206 | bw.flush(); 207 | } 208 | catch (Exception e) { 209 | e.printStackTrace(); 210 | } 211 | finally { 212 | if (bw != null) { 213 | try { 214 | fw.close(); 215 | } 216 | catch (Exception e) { 217 | e.printStackTrace(); 218 | } 219 | } 220 | 221 | if (fw != null) { 222 | try { 223 | fw.close(); 224 | } 225 | catch (Exception e) { 226 | e.printStackTrace(); 227 | } 228 | } 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/MyServlet.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import generated.*; 4 | 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.Future; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | 13 | import javax.servlet.annotation.WebServlet; 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.HttpServlet; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | 19 | @WebServlet("/test") 20 | public class MyServlet extends HttpServlet { 21 | public void doGet(HttpServletRequest request, HttpServletResponse response) 22 | throws ServletException, IOException { 23 | if (hasParameter(request, "cais")) { 24 | try { 25 | Class xhClass = Class.forName("com.sparktale.bugtale.agent.a.h.XH"); 26 | xhClass.getMethod("cs").invoke(null); 27 | xhClass.getMethod("ps").invoke(null); 28 | } catch (Exception e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | 33 | long exceptionsCount = 1; 34 | 35 | if (hasParameter(request, "ec")) { 36 | exceptionsCount = parseLong(getParameter(request, "ec"), exceptionsCount); 37 | } 38 | 39 | long intervalMillis = 1000; 40 | 41 | if (hasParameter(request, "im")) { 42 | intervalMillis = parseLong(getParameter(request, "im"), intervalMillis); 43 | } 44 | 45 | long warmupMillis = 0; 46 | 47 | if (hasParameter(request, "wm")) { 48 | warmupMillis = parseLong(getParameter(request, "wm"), warmupMillis); 49 | } 50 | 51 | int threadCount = 5; 52 | 53 | if (hasParameter(request, "tc")) { 54 | threadCount = parseInt(getParameter(request, "tc"), threadCount); 55 | } 56 | 57 | int printStatusEvery = Integer.MAX_VALUE; 58 | 59 | if (hasParameter(request, "pse")) { 60 | printStatusEvery = parseInt(getParameter(request, "pse"), printStatusEvery); 61 | } 62 | 63 | int runCount = 1; 64 | 65 | if (hasParameter(request, "rc")) { 66 | runCount = parseInt(getParameter(request, "rc"), runCount); 67 | } 68 | 69 | boolean singleThread = false; 70 | 71 | if (hasParameter(request, "st")) { 72 | singleThread = true; 73 | } 74 | 75 | boolean hideStackTraces = false; 76 | 77 | if (hasParameter(request, "hs")) { 78 | hideStackTraces = true; 79 | } 80 | 81 | System.out.println(String.format( 82 | "Throwing %d exceptions every %dms. starting at %dms from the beginning (%d threads) (%s stacktraces)", 83 | exceptionsCount, intervalMillis, warmupMillis, 84 | singleThread ? 1 : threadCount, 85 | hideStackTraces ? "hide" : "show")); 86 | 87 | long startMillis = System.currentTimeMillis(); 88 | long warmupMillisTotal = 0l; 89 | ExecutorService executor = Executors.newFixedThreadPool(threadCount); 90 | long exceptionsCounter = 0l; 91 | 92 | for (int j = 0; j < runCount; j++) { 93 | startMillis = System.currentTimeMillis(); 94 | exceptionsCounter = 0l; 95 | 96 | List calls = new ArrayList(); 97 | 98 | try { 99 | long warmupStartMillis = System.currentTimeMillis(); 100 | 101 | if (warmupMillis > 0) { 102 | Thread.sleep(warmupMillis); 103 | } 104 | 105 | warmupMillisTotal += (System.currentTimeMillis() - warmupStartMillis); 106 | } catch (Exception e) { } 107 | 108 | if (runCount > 1) { 109 | System.out.println("Starting iteration number: " + (j + 1)); 110 | } 111 | 112 | for (long i = 0; i < exceptionsCount; i++) { 113 | try { 114 | if (singleThread) { 115 | EntrypointSwitcher.randomCallable().call(); 116 | } else { 117 | calls.add(executor.submit(EntrypointSwitcher.randomCallable())); 118 | } 119 | } 120 | catch (Exception e) { 121 | if (!hideStackTraces) { 122 | e.printStackTrace(); 123 | } 124 | } 125 | 126 | exceptionsCounter++; 127 | 128 | long intervalStartMillis = System.currentTimeMillis(); 129 | 130 | do { 131 | if (!singleThread && !hideStackTraces) { 132 | List doneCalls = new ArrayList(); 133 | 134 | for (Future call : calls) { 135 | if (call.isCancelled() || call.isDone()) { 136 | try { 137 | call.get(); 138 | } catch (Exception e) { 139 | if (e.getCause() != null) { 140 | e.getCause().printStackTrace(); 141 | } 142 | } 143 | 144 | doneCalls.add(call); 145 | } 146 | } 147 | 148 | for (Future doneCall : doneCalls) { 149 | calls.remove(doneCall); 150 | } 151 | } 152 | 153 | if (intervalMillis > 0l) { 154 | try { 155 | Thread.currentThread().sleep(100); 156 | } catch (Exception e) { } 157 | } 158 | } while ((System.currentTimeMillis() - intervalStartMillis) < intervalMillis); 159 | 160 | if (((i + 1) % printStatusEvery) == 0) { 161 | long endMillis = System.currentTimeMillis(); 162 | long diffMillis = (endMillis - startMillis); 163 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + exceptionsCounter + " exceptions"); 164 | } 165 | } 166 | 167 | for (Future call : calls) { 168 | while (!call.isCancelled() && !call.isDone()) { 169 | try { 170 | Thread.currentThread().sleep(1); 171 | } catch (Exception e) { } 172 | } 173 | 174 | if (!hideStackTraces) { 175 | try { 176 | call.get(); 177 | } catch (Exception e) { 178 | if (e.getCause() != null) { 179 | e.getCause().printStackTrace(); 180 | } 181 | } 182 | } 183 | } 184 | } 185 | 186 | executor.shutdown(); 187 | 188 | long endMillis = System.currentTimeMillis(); 189 | long diffMillis = (endMillis - startMillis); 190 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + exceptionsCount + " exceptions"); 191 | 192 | try { 193 | Thread.currentThread().sleep(1000); 194 | } catch (Exception e) { } 195 | 196 | if (hasParameter(request, "pais")) { 197 | try { 198 | Class xhClass = Class.forName("com.sparktale.bugtale.agent.a.h.XH"); 199 | xhClass.getMethod("ps").invoke(null); 200 | } catch (Exception e) { 201 | e.printStackTrace(); 202 | } 203 | } 204 | } 205 | 206 | private static boolean hasParameter(HttpServletRequest request, String parameter) { 207 | return request.getParameter(parameter) != null; 208 | } 209 | 210 | private static String getParameter(HttpServletRequest request, String parameter) { 211 | return request.getParameter(parameter); 212 | } 213 | 214 | public static long parseLong(String str, long defaultValue) { 215 | try { 216 | return Long.parseLong(str); 217 | } catch (Exception e) { 218 | return defaultValue; 219 | } 220 | } 221 | 222 | public static int parseInt(String str, int defaultValue) { 223 | try { 224 | return Integer.parseInt(str); 225 | } catch (Exception e) { 226 | return defaultValue; 227 | } 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/dist/template/multiproject/root/src/main/java/helpers/MultiMain.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import generated.*; 4 | import java.util.List; 5 | import java.util.ArrayList; 6 | import java.util.concurrent.ExecutorService; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.Future; 9 | import java.util.concurrent.Callable; 10 | import org.apache.commons.cli.Options; 11 | import org.apache.commons.cli.DefaultParser; 12 | import org.apache.commons.cli.CommandLine; 13 | import org.apache.commons.cli.CommandLineParser; 14 | import org.apache.commons.cli.HelpFormatter; 15 | 16 | public class MultiMain 17 | { 18 | public static void main(String[] args) throws Exception { 19 | Options options = createCommandLineOptions(); 20 | CommandLineParser parser = new DefaultParser(); 21 | CommandLine cmd = parser.parse(options, args); 22 | 23 | if (cmd.hasOption("help")) { 24 | HelpFormatter formatter = new HelpFormatter(); 25 | formatter.printHelp("java helpers.MultiMain", options); 26 | return; 27 | } 28 | 29 | long exceptionsCount = Long.MAX_VALUE; 30 | 31 | if (cmd.hasOption("exceptions-count")) { 32 | exceptionsCount = parseLong(cmd.getOptionValue("exceptions-count"), exceptionsCount); 33 | } 34 | 35 | long intervalMillis = 1000; 36 | 37 | if (cmd.hasOption("interval-millis")) { 38 | intervalMillis = parseLong(cmd.getOptionValue("interval-millis"), intervalMillis); 39 | } 40 | 41 | long warmupMillis = 0; 42 | 43 | if (cmd.hasOption("warmup-millis")) { 44 | warmupMillis = parseLong(cmd.getOptionValue("warmup-millis"), warmupMillis); 45 | } 46 | 47 | int threadCount = 5; 48 | 49 | if (cmd.hasOption("thread-count")) { 50 | threadCount = parseInt(cmd.getOptionValue("thread-count"), threadCount); 51 | } 52 | 53 | int printStatusEvery = Integer.MAX_VALUE; 54 | 55 | if (cmd.hasOption("print-status-every")) { 56 | printStatusEvery = parseInt(cmd.getOptionValue("print-status-every"), printStatusEvery); 57 | } 58 | 59 | int runCount = 1; 60 | 61 | if (cmd.hasOption("run-count")) { 62 | runCount = parseInt(cmd.getOptionValue("run-count"), runCount); 63 | } 64 | 65 | boolean singleThread = false; 66 | 67 | if (cmd.hasOption("single-thread")) { 68 | singleThread = true; 69 | } 70 | 71 | boolean singleLoader = false; 72 | 73 | if (cmd.hasOption("single-loader")) { 74 | singleLoader = true; 75 | } 76 | 77 | boolean hideStackTraces = false; 78 | 79 | if (cmd.hasOption("hide-stacktraces")) { 80 | hideStackTraces = true; 81 | } 82 | 83 | System.out.println(String.format( 84 | "Throwing %d exceptions every %dms. starting at %dms from the beginning (%d threads) (%s stacktraces)", 85 | exceptionsCount, intervalMillis, warmupMillis, 86 | singleThread ? 1 : threadCount, 87 | hideStackTraces ? "hide" : "show")); 88 | 89 | long startMillis = System.currentTimeMillis(); 90 | long warmupMillisTotal = 0l; 91 | ExecutorService executor = Executors.newFixedThreadPool(threadCount); 92 | long exceptionsCounter = 0l; 93 | 94 | for (int j = 0; j < runCount; j++) { 95 | List calls = new ArrayList(); 96 | exceptionsCounter = 0l; 97 | startMillis = System.currentTimeMillis(); 98 | 99 | if (!singleLoader) { 100 | LoaderMultiSwitcher.resetLoaders(); 101 | } 102 | 103 | try { 104 | long warmupStartMillis = System.currentTimeMillis(); 105 | 106 | if (warmupMillis > 0) { 107 | Thread.sleep(warmupMillis); 108 | } 109 | 110 | warmupMillisTotal += (System.currentTimeMillis() - warmupStartMillis); 111 | } catch (Exception e) { } 112 | 113 | if (runCount > 1) { 114 | System.out.println("Starting iteration number: " + (j + 1)); 115 | } 116 | 117 | for (long i = 0; i < exceptionsCount; i++) { 118 | try { 119 | if (singleLoader) { 120 | if (singleThread) { 121 | MultiSwitcher.call(); 122 | } else { 123 | calls.add(executor.submit(new Callable() { 124 | @Override 125 | public Object call() throws Exception { 126 | MultiSwitcher.call(); 127 | return null; 128 | } 129 | })); 130 | } 131 | } else { 132 | if (singleThread) { 133 | LoaderMultiSwitcher.call(); 134 | } else { 135 | calls.add(executor.submit(new Callable() { 136 | @Override 137 | public Object call() throws Exception { 138 | LoaderMultiSwitcher.call(); 139 | return null; 140 | } 141 | })); 142 | } 143 | } 144 | } 145 | catch (Exception e) { 146 | if (!hideStackTraces) { 147 | e.printStackTrace(); 148 | } 149 | 150 | if (singleThread) { 151 | exceptionsCounter++; 152 | } 153 | } 154 | 155 | long intervalStartMillis = System.currentTimeMillis(); 156 | 157 | do { 158 | if (!singleThread) { 159 | List doneCalls = new ArrayList(); 160 | 161 | for (Future call : calls) { 162 | if (call.isCancelled() || call.isDone()) { 163 | try { 164 | call.get(); 165 | } catch (Exception e) { 166 | if (!hideStackTraces) { 167 | Throwable cause = e; 168 | 169 | while (cause.getCause() != null) { 170 | cause = cause.getCause(); 171 | } 172 | 173 | cause.printStackTrace(); 174 | } 175 | } 176 | 177 | exceptionsCounter++; 178 | 179 | doneCalls.add(call); 180 | } 181 | } 182 | 183 | for (Future doneCall : doneCalls) { 184 | calls.remove(doneCall); 185 | } 186 | } 187 | 188 | if (intervalMillis > 0l) { 189 | try { 190 | Thread.currentThread().sleep(100); 191 | } catch (Exception e) { } 192 | } 193 | } while ((System.currentTimeMillis() - intervalStartMillis) < intervalMillis); 194 | 195 | if ((exceptionsCounter > 0) && 196 | ((exceptionsCounter % printStatusEvery) == 0)) { 197 | long endMillis = System.currentTimeMillis(); 198 | long diffMillis = (endMillis - startMillis); 199 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + exceptionsCounter + " exceptions"); 200 | } 201 | } 202 | 203 | for (Future call : calls) { 204 | while (!call.isCancelled() && !call.isDone()) { 205 | try { 206 | Thread.currentThread().sleep(1); 207 | } catch (Exception e) { } 208 | } 209 | 210 | exceptionsCounter++; 211 | 212 | if (!hideStackTraces) { 213 | try { 214 | call.get(); 215 | } catch (Exception e) { 216 | Throwable cause = e; 217 | 218 | while (cause.getCause() != null) { 219 | cause = cause.getCause(); 220 | } 221 | 222 | cause.printStackTrace(); 223 | } 224 | } 225 | 226 | if ((exceptionsCounter > 0) && 227 | ((exceptionsCounter % printStatusEvery) == 0)) { 228 | long endMillis = System.currentTimeMillis(); 229 | long diffMillis = (endMillis - startMillis); 230 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + exceptionsCounter + " exceptions"); 231 | } 232 | } 233 | } 234 | 235 | executor.shutdown(); 236 | 237 | long endMillis = System.currentTimeMillis(); 238 | long diffMillis = (endMillis - startMillis); 239 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + exceptionsCounter + " exceptions"); 240 | } 241 | 242 | public static long parseLong(String str, long defaultValue) { 243 | try { 244 | return Long.parseLong(str); 245 | } catch (Exception e) { 246 | return defaultValue; 247 | } 248 | } 249 | 250 | public static int parseInt(String str, int defaultValue) { 251 | try { 252 | return Integer.parseInt(str); 253 | } catch (Exception e) { 254 | return defaultValue; 255 | } 256 | } 257 | 258 | private static Options createCommandLineOptions() { 259 | Options options = new Options(); 260 | 261 | options.addOption("h", "help", false, "Print this help"); 262 | options.addOption("st", "single-thread", false, "Run everything directly from the main thread (default to false)"); 263 | options.addOption("sl", "single-loader", false, "Call subprojects from the main class loader (default to false)"); 264 | options.addOption("hs", "hide-stacktraces", false, "Determine whether to print the stack traces of the exceptions (default to false)"); 265 | options.addOption("pse", "print-status-every", true, "Print to screen every n events (default to Integer.MAX_VALUE)"); 266 | options.addOption("tc", "thread-count", true, "The number of threads (default to 5)"); 267 | options.addOption("ec", "exceptions-count", true, "The number of exceptions to throw (default to 1000)"); 268 | options.addOption("wm", "warmup-millis", true, "Time to wait before starting to throw exceptions (in millis) (default to 0)"); 269 | options.addOption("im", "interval-millis", true, "Time between exceptions (in millis) (default to 1000)"); 270 | options.addOption("rc", "run-count", true, "The number of times to run all (default to 1)"); 271 | 272 | return options; 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /src/main/groovy/generator/AppGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | import java.util.concurrent.Callable 4 | import java.util.concurrent.Executors 5 | 6 | public class AppGenerator { 7 | private static scriptFile 8 | private static commandLineOptions 9 | 10 | public static main(args) { 11 | initialize(); 12 | 13 | def commandLine = commandLineOptions.parse(args) 14 | 15 | if (commandLine.help) { 16 | println commandLineOptions.usage() 17 | System.exit(0) 18 | } 19 | 20 | if (commandLine."output-directory") { 21 | Config.rootDirectory = new File(commandLine."output-directory") 22 | } else { 23 | Config.rootDirectory = new File("output") 24 | } 25 | 26 | if (commandLine."classes") { 27 | Config.classesCount = Integer.parseInt(commandLine."classes") 28 | } 29 | 30 | if (commandLine."subprojects") { 31 | Config.subprojectsCount = Integer.parseInt(commandLine."subprojects") 32 | } 33 | 34 | if (commandLine."methods-per-class") { 35 | Config.methodsPerClass = Integer.parseInt(commandLine."methods-per-class") 36 | } 37 | 38 | if (commandLine."log-info-per-method") { 39 | Config.logInfoPerMethod = Integer.parseInt(commandLine."log-info-per-method") 40 | } 41 | 42 | if (commandLine."log-warn-per-method") { 43 | Config.logWarnPerMethod = Integer.parseInt(commandLine."log-warn-per-method") 44 | } 45 | 46 | if (commandLine."log-error-per-method") { 47 | Config.logErrorPerMethod = Integer.parseInt(commandLine."log-error-per-method") 48 | } 49 | 50 | if (commandLine."bridge-switch-size") { 51 | Config.bridgeSwitchSize = Integer.parseInt(commandLine."bridge-switch-size") 52 | } 53 | 54 | if (commandLine."switcher-max-routes") { 55 | Config.switcherMaxRoutes = Integer.parseInt(commandLine."switcher-max-routes") 56 | } 57 | 58 | if (commandLine."entry-points") { 59 | Config.entryPointNum = Integer.parseInt(commandLine."entry-points") 60 | } 61 | 62 | if (commandLine."seed") { 63 | Config.seed = Integer.parseInt(commandLine."seed") 64 | } 65 | 66 | if (commandLine."template-directory") { 67 | Config.templateDirectory = commandLine."template-directory" 68 | } 69 | 70 | if (commandLine."io-cpu-intensive-matrix-size") { 71 | Config.ioCpuIntensiveMatrixSize = commandLine."io-cpu-intensive-matrix-size" 72 | } 73 | 74 | if (commandLine."skip-logic-code") { 75 | Config.shouldGenerateLogicCode = false 76 | } 77 | 78 | def singleProjectName = "tester" 79 | 80 | if (commandLine."name") 81 | { 82 | singleProjectName = commandLine."name" 83 | } 84 | 85 | if (!Config.rootDirectory.isDirectory()) { 86 | Config.rootDirectory.mkdirs() 87 | } 88 | 89 | if (!Utils.loadNamesFromFile()) { 90 | println "Using random numbers" 91 | } 92 | 93 | def isMultiProject = Config.subprojectsCount > 1 94 | 95 | println "Start generating $Config.subprojectsCount projects" 96 | 97 | if (isMultiProject) { 98 | Utils.ant.delete(dir:Config.rootDirectory) 99 | Config.rootDirectory.mkdirs() 100 | generateSubProjects(Config.rootDirectory, Config.subprojectsCount) 101 | } else { 102 | generateProject(Config.rootDirectory, singleProjectName) 103 | } 104 | 105 | println "Done All!" 106 | } 107 | 108 | private static generateSubProjects(rootDirectory, subprojectsCount) { 109 | def projectNames = [] 110 | def generatedDir = new File("$rootDirectory/root/src/main/java/$Config.generatedPackage") 111 | 112 | if (!generatedDir.exists()) { 113 | generatedDir.mkdirs() 114 | } 115 | 116 | (1..subprojectsCount).each { 117 | def projectName = Utils.generateName("Proj", "", 10, true, true) 118 | def projectDir = "${Config.rootDirectory}/$projectName"; 119 | 120 | generateProject(projectDir, projectName) 121 | projectNames += projectName 122 | 123 | LoaderSwitcherGenerator.write(generatedDir, projectName) 124 | } 125 | 126 | Utils.ant.copy(todir:"$rootDirectory", overwrite:false) { 127 | fileset(dir:"$Config.templateDirectory/multiproject") 128 | } 129 | 130 | Utils.ant.chmod(file:"$rootDirectory/gradlew", perm:"+x") 131 | 132 | GradleSettingsGenerator.write(rootDirectory, "GeneratedAgregator", projectNames + "root") 133 | GradleGenerator.write("$rootDirectory/root", projectNames, "helpers.MultiMain") 134 | MultiSwitcherGenerator.write("$rootDirectory/root/src/main/java", projectNames) 135 | LoaderMultiSwitcherGenerator.write("$rootDirectory/root/src/main/java", projectNames) 136 | } 137 | 138 | private static generateProject(projectDir, projectName) { 139 | def generatedDir = new File("$projectDir/src/main/java/$Config.generatedPackage") 140 | 141 | if (!generatedDir.exists()) { 142 | generatedDir.mkdirs() 143 | } 144 | 145 | println "Generating $projectName to $generatedDir" 146 | 147 | if (generatedDir.exists()) { 148 | Utils.ant.delete(dir:generatedDir) 149 | } 150 | 151 | generatedDir.mkdirs() 152 | 153 | Utils.ant.copy(todir:"$projectDir", overwrite:true) 154 | { 155 | fileset(dir:"$Config.templateDirectory/project") 156 | } 157 | 158 | Utils.ant.chmod(file:"$projectDir/gradlew", perm:"+x") 159 | 160 | if(Config.seed != null){ 161 | println "\tCreating application with seed: $Config.seed" 162 | }else{ 163 | println "\tCreating random application" 164 | } 165 | 166 | println "\tGenerating $Config.classesCount classes" 167 | 168 | def classes = generateClasses() 169 | 170 | println "\tGenerating dynamic code" 171 | 172 | classes.each({ it.generateMethods(classes, Config.shouldGenerateLogicCode, true, true, true)}) 173 | 174 | println "\tWriting ${classes.size()} classes" 175 | 176 | writeClasses(classes, generatedDir) 177 | 178 | println "\tWriting switcher" 179 | 180 | def switcherClassName = SwitcherGenerator.write(classes, generatedDir.parentFile, projectName) 181 | Utils.ant.replace(file:"$projectDir/src/main/java/helpers/MyServlet.java", token:"@SWITCHER_CLASS_NAME@", value:switcherClassName) 182 | 183 | println "\tWriting entrypoints ${Config.entryPointNum}" 184 | EntryPointGenerator.write(generatedDir.parentFile, switcherClassName) 185 | 186 | println "\tWriting gradle configurations" 187 | 188 | GradleSettingsGenerator.write(projectDir, projectName, []) 189 | 190 | println "\tWriting bash runner" 191 | 192 | BashRunnerGenerator.write(projectDir, projectName) 193 | 194 | println "\tDone $projectName" 195 | } 196 | 197 | private static generateClasses() { 198 | return (1..Config.classesCount).collect( 199 | { 200 | def methodsCount = Config.methodsPerClass 201 | def clazz = new ClassGenerator(it) 202 | 203 | def methodCounter = 0 204 | 205 | (1..methodsCount).each { 206 | clazz.addMethod(methodCounter++) 207 | } 208 | 209 | return clazz 210 | }) 211 | } 212 | 213 | private static writeClasses(classes, generatedDir) { 214 | def pool = Executors.newFixedThreadPool(10) 215 | def futures = [] 216 | 217 | classes.each({ 218 | def clazz = it 219 | 220 | futures += pool.submit({ 221 | clazz.write(generatedDir.parentFile) 222 | } as Callable) 223 | }) 224 | 225 | futures.each({ it.get() }) 226 | pool.shutdown() 227 | } 228 | 229 | private static initialize() { 230 | def scriptPath = Config.class.protectionDomain.codeSource.location.path 231 | scriptFile = new File(scriptPath) 232 | 233 | commandLineOptions = new CliBuilder() 234 | 235 | commandLineOptions.width = 130 236 | commandLineOptions.usage = "groovy ${scriptFile.name}.groovy [params]" 237 | commandLineOptions.footer = "" 238 | commandLineOptions.header = "" 239 | 240 | commandLineOptions.h( 241 | longOpt:"help", "Print this usage") 242 | 243 | commandLineOptions._( 244 | longOpt:"output-directory", 245 | args:1, 246 | argName:"dir", 247 | "Output directory for the generated application") 248 | 249 | commandLineOptions._( 250 | longOpt:"name", 251 | args:1, 252 | argName:"str", 253 | "The name of the output jar") 254 | 255 | commandLineOptions._( 256 | longOpt:"seed", 257 | args:1, 258 | argName:"number", 259 | "The seed used to generate the application (If not set a random application is generated every time)") 260 | 261 | commandLineOptions._( 262 | longOpt:"classes", 263 | args:1, 264 | argName:"number", 265 | "The number of generated classes (default to $Config.classesCount)") 266 | 267 | commandLineOptions._( 268 | longOpt:"subprojects", 269 | args:1, 270 | argName:"number", 271 | "The number of generated projects (default to $Config.subprojectsCount)") 272 | 273 | commandLineOptions._( 274 | longOpt:"methods-per-class", 275 | args:1, 276 | argName:"number", 277 | "The number of methods per class (default to $Config.methodsPerClass)") 278 | 279 | commandLineOptions._( 280 | longOpt:"log-info-per-method", 281 | args:1, 282 | argName:"number", 283 | "The number of info statements per method (default to $Config.logInfoPerMethod)") 284 | 285 | commandLineOptions._( 286 | longOpt:"log-warn-per-method", 287 | args:1, 288 | argName:"number", 289 | "The number of warn statements per method (default to $Config.logWarnPerMethod)") 290 | 291 | commandLineOptions._( 292 | longOpt:"log-error-per-method", 293 | args:1, 294 | argName:"number", 295 | "The number of error statements per method (default to $Config.logErrorPerMethod)") 296 | 297 | commandLineOptions._( 298 | longOpt:"bridge-switch-size", 299 | args:1, 300 | argName:"number", 301 | "The number of methods that may be called from each generated method (default to $Config.bridgeSwitchSize)") 302 | 303 | commandLineOptions._( 304 | longOpt:"switcher-max-routes", 305 | args:1, 306 | argName:"number", 307 | "The maximum methods available from switcher (default to $Config.switcherMaxRoutes)") 308 | 309 | commandLineOptions._( 310 | longOpt:"entry-points", 311 | args:1, 312 | argName:"number", 313 | "Number of entry points") 314 | 315 | commandLineOptions._( 316 | longOpt:"template-directory", 317 | args:1, 318 | argName:"template directory", 319 | "The path to the template direcotry (defult to 'template')") 320 | 321 | commandLineOptions._( 322 | longOpt:"io-cpu-intensive-matrix-size", 323 | args:1, 324 | argName:"number", 325 | "matrix size to use for io/cpu intensive logic (defaults to $Config.ioCpuIntensiveMatrixSize") 326 | 327 | commandLineOptions._( 328 | longOpt:"skip-logic-code", 329 | "set for generate without logic code") 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /src/dist/template/project/src/main/java/helpers/Main.java: -------------------------------------------------------------------------------- 1 | package helpers; 2 | 3 | import generated.*; 4 | import java.util.List; 5 | import java.util.Random; 6 | import java.util.ArrayList; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.Future; 10 | import org.apache.commons.cli.Options; 11 | import org.apache.commons.cli.DefaultParser; 12 | import org.apache.commons.cli.CommandLine; 13 | import org.apache.commons.cli.CommandLineParser; 14 | import org.apache.commons.cli.HelpFormatter; 15 | 16 | public class Main 17 | { 18 | public static void main(String[] args) throws Exception { 19 | 20 | Options options = createCommandLineOptions(); 21 | CommandLineParser parser = new DefaultParser(); 22 | CommandLine cmd = parser.parse(options, args); 23 | 24 | if (cmd.hasOption("help")) { 25 | HelpFormatter formatter = new HelpFormatter(); 26 | formatter.printHelp("java helpers.Main", options); 27 | return; 28 | } 29 | 30 | long exceptionsCount = Long.MAX_VALUE; 31 | 32 | if (cmd.hasOption("exceptions-count")) { 33 | exceptionsCount = parseLong(cmd.getOptionValue("exceptions-count"), exceptionsCount); 34 | } 35 | 36 | long intervalMillis = 1000; 37 | 38 | if (cmd.hasOption("interval-millis")) { 39 | intervalMillis = parseLong(cmd.getOptionValue("interval-millis"), intervalMillis); 40 | } 41 | 42 | long warmupMillis = 0; 43 | 44 | if (cmd.hasOption("warmup-millis")) { 45 | warmupMillis = parseLong(cmd.getOptionValue("warmup-millis"), warmupMillis); 46 | } 47 | 48 | int threadCount = 5; 49 | 50 | if (cmd.hasOption("thread-count")) { 51 | threadCount = parseInt(cmd.getOptionValue("thread-count"), threadCount); 52 | } 53 | 54 | int printStatusEvery = Integer.MAX_VALUE; 55 | 56 | if (cmd.hasOption("print-status-every")) { 57 | printStatusEvery = parseInt(cmd.getOptionValue("print-status-every"), printStatusEvery); 58 | } 59 | 60 | int runCount = 1; 61 | 62 | if (cmd.hasOption("run-count")) { 63 | runCount = parseInt(cmd.getOptionValue("run-count"), runCount); 64 | } 65 | 66 | if (cmd.hasOption("frames-range")) { 67 | int[] framesCountRange = parseRange(cmd.getOptionValue("frames-range"), (new int[] { 0, 10 })); 68 | 69 | if (framesCountRange != null) { 70 | System.out.println("Setting frames range " + framesCountRange[0] + ".." + framesCountRange[1]); 71 | Config.get().setFramesRangeFromCommandLine(framesCountRange); 72 | } 73 | } 74 | 75 | boolean singleThread = false; 76 | 77 | if (cmd.hasOption("single-thread")) { 78 | singleThread = true; 79 | } 80 | 81 | if (cmd.hasOption("sticky-path")) { 82 | Config.get().setStickyPathsDir(cmd.getOptionValue("sticky-path")); 83 | } 84 | 85 | if (cmd.hasOption("events-spot")) { 86 | Config.get().setEventSpotDir(cmd.getOptionValue("events-spot")); 87 | } 88 | 89 | if (cmd.hasOption("seed")) { 90 | Config.rand = new Random(parseLong(cmd.getOptionValue("seed"), 0)); 91 | } 92 | 93 | boolean hideStackTraces = false; 94 | 95 | if (cmd.hasOption("hide-stacktraces")) { 96 | hideStackTraces = true; 97 | } 98 | 99 | System.out.println(String.format( 100 | "(Exceptions: %d) (Interval: %dms) (Warmup: %dms) (Threads: %d) (%s stacktraces) (sticky path: %s) (event spot: %s) (seed: %d)", 101 | exceptionsCount, intervalMillis, warmupMillis, 102 | singleThread ? 1 : threadCount, 103 | hideStackTraces ? "hide" : "show", 104 | Config.get().getStickyPathsDir(), 105 | Config.get().getEventSpotDir(), 106 | parseLong(cmd.getOptionValue("seed"), 0))); 107 | 108 | long startMillis = System.currentTimeMillis(); 109 | long warmupMillisTotal = 0l; 110 | ExecutorService executor = Executors.newFixedThreadPool(threadCount); 111 | long tasksCompleted = 0l; 112 | 113 | for (int j = 0; j < runCount; j++) { 114 | List calls = new ArrayList(); 115 | warmupMillisTotal = 0l; 116 | startMillis = System.currentTimeMillis(); 117 | tasksCompleted = 0l; 118 | 119 | try { 120 | long warmupStartMillis = System.currentTimeMillis(); 121 | 122 | if (warmupMillis > 0) { 123 | Thread.sleep(warmupMillis); 124 | } 125 | 126 | warmupMillisTotal += (System.currentTimeMillis() - warmupStartMillis); 127 | } catch (Exception e) { } 128 | 129 | if (runCount > 1) { 130 | System.out.println("Starting iteration number: " + (j + 1)); 131 | } 132 | 133 | for (long i = 0; i < exceptionsCount; i++) { 134 | try { 135 | if (singleThread) { 136 | tasksCompleted++; 137 | EntrypointSwitcher.randomCallable().call(); 138 | StatsReporter.get().incTasksCompleted(); 139 | } else { 140 | calls.add(executor.submit(EntrypointSwitcher.randomCallable())); 141 | } 142 | } 143 | catch (Exception e) { 144 | handleException(e, hideStackTraces, false); 145 | } 146 | 147 | long intervalStartMillis = System.currentTimeMillis(); 148 | 149 | do { 150 | if (!singleThread) { 151 | List doneCalls = new ArrayList(); 152 | 153 | for (Future call : calls) { 154 | if (call.isCancelled() || call.isDone()) { 155 | try { 156 | call.get(); 157 | } catch (Exception e) { 158 | handleException(e, hideStackTraces, true); 159 | } 160 | 161 | tasksCompleted++; 162 | StatsReporter.get().incTasksCompleted(); 163 | doneCalls.add(call); 164 | } 165 | } 166 | 167 | for (Future doneCall : doneCalls) { 168 | calls.remove(doneCall); 169 | } 170 | } 171 | 172 | if (intervalMillis > 0l) { 173 | try { 174 | Thread.currentThread().sleep(100); 175 | } catch (Exception e) { } 176 | } 177 | 178 | StatsReporter.get().generateReport(); 179 | } while ((System.currentTimeMillis() - intervalStartMillis) < intervalMillis); 180 | 181 | if (tasksCompleted > 0 && (tasksCompleted % printStatusEvery) == 0) { 182 | long endMillis = System.currentTimeMillis(); 183 | long diffMillis = (endMillis - startMillis); 184 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + tasksCompleted + " exceptions"); 185 | } 186 | } 187 | 188 | for (Future call : calls) { 189 | while (!call.isCancelled() && !call.isDone()) { 190 | try { 191 | Thread.currentThread().sleep(1); 192 | } catch (Exception e) { } 193 | } 194 | 195 | try { 196 | tasksCompleted++; 197 | call.get(); 198 | } catch (Exception e) { 199 | handleException(e, hideStackTraces, true); 200 | } 201 | 202 | if (tasksCompleted > 0 && (tasksCompleted % printStatusEvery) == 0) { 203 | long endMillis = System.currentTimeMillis(); 204 | long diffMillis = (endMillis - startMillis); 205 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + tasksCompleted + " exceptions"); 206 | } 207 | } 208 | } 209 | 210 | if (tasksCompleted > 0 && (tasksCompleted % printStatusEvery) == 0) { 211 | long endMillis = System.currentTimeMillis(); 212 | long diffMillis = (endMillis - startMillis); 213 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + tasksCompleted + " exceptions"); 214 | } 215 | 216 | executor.shutdown(); 217 | 218 | long endMillis = System.currentTimeMillis(); 219 | long diffMillis = (endMillis - startMillis); 220 | System.out.println("Took: " + (diffMillis - warmupMillisTotal) + " to throw " + tasksCompleted + " exceptions"); 221 | } 222 | 223 | private static void handleException(Exception exception, boolean hideStackTraces, boolean nested) { 224 | if (nested) { 225 | if (exception.getCause() instanceof Exception) { 226 | exception = (Exception) exception.getCause(); 227 | } 228 | } 229 | 230 | if (!(exception instanceof BullshifierException)) { 231 | exception.printStackTrace(); 232 | return; 233 | } 234 | 235 | BullshifierException bex = (BullshifierException) exception; 236 | 237 | if (!hideStackTraces) { 238 | exception.printStackTrace(); 239 | return; 240 | } 241 | 242 | if (bex != null) { 243 | System.out.println(bex.toString()); 244 | } 245 | } 246 | 247 | public static long parseLong(String str, long defaultValue) { 248 | try { 249 | return Long.parseLong(str); 250 | } catch (Exception e) { 251 | System.out.println("Error parsing long " + str); 252 | return defaultValue; 253 | } 254 | } 255 | 256 | public static int parseInt(String str, int defaultValue) { 257 | try { 258 | return Integer.parseInt(str); 259 | } catch (Exception e) { 260 | System.out.println("Error parsing int " + str); 261 | return defaultValue; 262 | } 263 | } 264 | 265 | public static int[] parseRange(String str, int[] defaultValue) 266 | { 267 | if (str == null) { 268 | System.out.println("Parse range error: null"); 269 | return defaultValue; 270 | } 271 | 272 | int from = defaultValue[0]; 273 | int to = defaultValue[1]; 274 | 275 | if (str.indexOf("..") == -1) { 276 | from = parseInt(str, defaultValue[0]); 277 | to = from; 278 | } else { 279 | String[] parts = str.split("\\.\\."); 280 | 281 | if (parts == null || parts.length != 2) { 282 | System.out.println("Parse range error: invalid format: " + str); 283 | return defaultValue; 284 | } 285 | 286 | from = parseInt(parts[0], from); 287 | to = parseInt(parts[1], to); 288 | } 289 | 290 | int[] result = new int[2]; 291 | result[0] = from; 292 | result[1] = to; 293 | return result; 294 | } 295 | 296 | private static Options createCommandLineOptions() { 297 | Options options = new Options(); 298 | 299 | options.addOption("h", "help", false, "Print this help"); 300 | options.addOption("st", "single-thread", false, "Run everything directly from the main thread (default to false)"); 301 | options.addOption("hs", "hide-stacktraces", false, "Determine whether to print the stack traces of the exceptions (default to false)"); 302 | options.addOption("pse", "print-status-every", true, "Print to screen every n events (default to Integer.MAX_VALUE)"); 303 | options.addOption("tc", "thread-count", true, "The number of threads (default to 5)"); 304 | options.addOption("ec", "exceptions-count", true, "The number of exceptions to throw (default to 1000)"); 305 | options.addOption("wm", "warmup-millis", true, "Time to wait before starting to throw exceptions (in millis) (default to 0)"); 306 | options.addOption("im", "interval-millis", true, "Time between exceptions (in millis) (default to 1000)"); 307 | options.addOption("rc", "run-count", true, "The number of times to run all (default to 1)"); 308 | options.addOption("fc", "frames-range", true, "Choose a random number between a range in '(X..)?Y' format. (default is 1..1)"); 309 | options.addOption("sp", "sticky-path", true, "A path to store constant paths in the code"); 310 | options.addOption("es", "events-spot", true, "A path to store events spot"); 311 | options.addOption("s", "seed", true, "Application 'Random' seed number"); 312 | 313 | return options; 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/main/groovy/generator/LogicGenerator.groovy: -------------------------------------------------------------------------------- 1 | package generator; 2 | 3 | public class LogicGenerator { 4 | static generate(methodName, context) { 5 | def method = new MethodBlock() 6 | method.name = methodName 7 | method.generate(context) 8 | 9 | return method 10 | } 11 | 12 | static generateBlocks(context) { 13 | def body = new BodyBlock() 14 | body.generate(context) 15 | 16 | return body 17 | } 18 | 19 | static class Block { 20 | static currentId = 0 21 | 22 | def parent 23 | def id 24 | def childIndex 25 | 26 | def Block() { 27 | this.id = currentId++ 28 | } 29 | 30 | def depth() { 31 | def counter = 0 32 | def current = this 33 | 34 | while (current) { 35 | counter++ 36 | current = current.parent 37 | } 38 | 39 | return counter 40 | } 41 | 42 | def path() { 43 | def result = [] 44 | def current = this 45 | 46 | while (current) { 47 | result += current 48 | current = current.parent 49 | } 50 | 51 | return result 52 | } 53 | 54 | def scope() { 55 | def path = path() 56 | 57 | return (path + path.collect({ it.nodesAbove() })).flatten().unique() 58 | } 59 | 60 | def nodesAbove() { 61 | if (!parent) { 62 | return [] 63 | } 64 | 65 | return parent.nodesAbove(this) 66 | } 67 | 68 | def print(tabs) { 69 | return [] 70 | } 71 | } 72 | 73 | static class BodyBlock extends Block { 74 | def body = [:] 75 | 76 | def generate(context) { 77 | def shouldGenerateMoreBlocks = Utils.rand.nextBoolean() 78 | def depth = depth() 79 | 80 | if (depth > 1 && (depth >= Config.maxBlocksDepth || !shouldGenerateMoreBlocks)) { 81 | def special = new SpecialBlock() 82 | 83 | special.parent = this 84 | special.generate(context) 85 | 86 | this.body = [(special.id):(special)] 87 | } else { 88 | def blocksCount = Utils.rand.nextInt(Config.minBlocksPerMethod + Config.maxBlocksPerMethod) + Config.minBlocksPerMethod 89 | 90 | for (def i = 0; i < blocksCount; i++) { 91 | def block = randomBlock() 92 | addBlock(block) 93 | } 94 | 95 | this.body.each { 96 | it.value.generate(context); 97 | } 98 | } 99 | } 100 | 101 | def addBlock(block) { 102 | this.body[block.id] = block 103 | 104 | block.childIndex = this.body.size() 105 | block.parent = this 106 | } 107 | 108 | def randomBlock() { 109 | def block = Utils.rand.nextInt(6) 110 | 111 | switch (block) 112 | { 113 | case (0): return new ForBlock() 114 | case (1): return new IfBlock() 115 | case (2): return new WhileBlock() 116 | case (3): return new VarBlock() 117 | case (4): return new TryBlock() 118 | case (5): return new AssignBlock() 119 | //case (5): return new CallBlock() 120 | } 121 | } 122 | 123 | def print(tabs) { 124 | def result = [] 125 | result += "${tabs}{" 126 | body.each 127 | { 128 | result += it.value.print("$tabs\t") 129 | } 130 | result += "${tabs}}" 131 | return result 132 | } 133 | 134 | def nodesAbove(child) { 135 | return body.collect({ it.value }).grep({ it.childIndex < child.childIndex }) 136 | } 137 | } 138 | 139 | static class VarHolder extends BodyBlock { 140 | def var 141 | } 142 | 143 | static class MethodBlock extends BodyBlock { 144 | def name 145 | def body 146 | 147 | def generate(context) { 148 | super.generate(context) 149 | 150 | def returnBlock = new ReturnBlock() 151 | addBlock(returnBlock) 152 | returnBlock.generate(context) 153 | } 154 | 155 | def print(tabs) { 156 | def result = [] 157 | result += "${tabs}public static long $name()" 158 | result += super.print(tabs) 159 | result += "${tabs}" 160 | return result 161 | } 162 | 163 | public String toString() { 164 | return "method" 165 | } 166 | } 167 | 168 | static class ForBlock extends BodyBlock { 169 | def from 170 | def to 171 | def loopIndex 172 | 173 | def generate(context) { 174 | super.generate(context) 175 | this.from = Utils.rand.nextInt(Config.maxLoopStart + 1) 176 | this.to = Utils.rand.nextInt(Config.maxLoopEnd) + from 177 | this.loopIndex = "loopIndex${depth()}$id" 178 | } 179 | 180 | def print(tabs) { 181 | def result = [] 182 | result += "${tabs}int $loopIndex = 0;" 183 | result += "${tabs}for ($loopIndex = $from; $loopIndex < $to; $loopIndex++)" 184 | result += super.print(tabs) 185 | result += "${tabs}" 186 | return result 187 | } 188 | 189 | public String toString() { 190 | return "for" 191 | } 192 | } 193 | 194 | static class ElseIfBlock extends BodyBlock { 195 | def body 196 | def condition 197 | 198 | def generate(context) { 199 | super.generate(context) 200 | this.condition = generateCondition(this) 201 | } 202 | 203 | def print(tabs) { 204 | def result = [] 205 | result += "${tabs}else if ($condition)" 206 | result += super.print(tabs) 207 | return result 208 | } 209 | 210 | public String toString() { 211 | return "elsif" 212 | } 213 | } 214 | 215 | static class ElseBlock extends BodyBlock { 216 | def body 217 | 218 | def print(tabs) { 219 | def result = [] 220 | result += "${tabs}else" 221 | result += super.print(tabs) 222 | return result 223 | } 224 | 225 | public String toString() { 226 | return "else" 227 | } 228 | } 229 | 230 | static class IfBlock extends BodyBlock { 231 | def condition 232 | def elseIfBlocks = [] 233 | def elseBlock 234 | 235 | def generate(context) { 236 | super.generate(context) 237 | this.condition = generateCondition(this) 238 | 239 | def shouldGenerateElseBlock = Utils.rand.nextBoolean() 240 | 241 | if (shouldGenerateElseBlock) { 242 | this.elseBlock = new ElseBlock() 243 | this.elseBlock.parent = this.parent 244 | this.elseBlock.generate(context) 245 | } 246 | 247 | def elseIfBlockCount = Utils.rand.nextInt(Config.maxElseIfBlocks) 248 | 249 | for (def i = 0; i < elseIfBlockCount; i++) { 250 | def elseIfBlock = new ElseIfBlock() 251 | elseIfBlock.parent = this.parent 252 | elseIfBlock.generate(context) 253 | elseIfBlocks += elseIfBlock 254 | } 255 | } 256 | 257 | def print(tabs) { 258 | def result = [] 259 | result += "${tabs}if ($condition)" 260 | result += super.print(tabs) 261 | 262 | for (def elseIfBlock : elseIfBlocks) { 263 | result += elseIfBlock.print(tabs) 264 | } 265 | 266 | if (elseBlock) { 267 | result += elseBlock.print(tabs) 268 | } 269 | 270 | result += "${tabs}" 271 | return result 272 | } 273 | 274 | public String toString() { 275 | return "if" 276 | } 277 | } 278 | 279 | static class WhileBlock extends BodyBlock { 280 | def body 281 | def loopIndex 282 | def from 283 | def to 284 | 285 | def generate(context) { 286 | super.generate(context) 287 | this.loopIndex = "whileIndex${depth()}${id}" 288 | this.from = Utils.rand.nextInt(Config.maxLoopStart + 1) 289 | this.to = Utils.rand.nextInt(Config.maxLoopEnd) + from 290 | } 291 | 292 | def print(tabs) { 293 | def result = [] 294 | result += "${tabs}long $loopIndex = $from;" 295 | result += "${tabs}" 296 | result += "${tabs}while ($loopIndex-- > 0)" 297 | result += super.print(tabs) 298 | result += "${tabs}" 299 | return result 300 | } 301 | 302 | public String toString() { 303 | return "while" 304 | } 305 | } 306 | 307 | static class CatchBlock extends BodyBlock { 308 | def var 309 | 310 | def generate(context) { 311 | this.var = "ex${depth()}$id" 312 | } 313 | 314 | def print(tabs) { 315 | def result = [] 316 | result += "${tabs}catch (Exception $var)" 317 | result += super.print(tabs) 318 | return result 319 | } 320 | 321 | public String toString() { 322 | return "catch" 323 | } 324 | } 325 | 326 | static class FinallyBlock extends BodyBlock { 327 | def print(tabs) { 328 | def result = [] 329 | result += "${tabs}finally" 330 | result += super.print(tabs) 331 | return result 332 | } 333 | 334 | public String toString() { 335 | return "finally" 336 | } 337 | } 338 | 339 | static class TryBlock extends BodyBlock { 340 | def catchBlock 341 | def finallyBlock 342 | 343 | def generate(context) { 344 | super.generate(context) 345 | 346 | def shouldGenerateCatchBlock = Utils.rand.nextBoolean() 347 | def shouldGenerateFinallyBlock = Utils.rand.nextBoolean() 348 | 349 | if (!shouldGenerateCatchBlock) { 350 | shouldGenerateFinallyBlock = true 351 | } 352 | 353 | if (shouldGenerateCatchBlock) { 354 | this.catchBlock = new CatchBlock() 355 | this.catchBlock.parent = this.parent 356 | this.catchBlock.generate(context) 357 | } 358 | 359 | if (shouldGenerateFinallyBlock) { 360 | this.finallyBlock = new FinallyBlock() 361 | this.finallyBlock.parent = this.parent 362 | this.finallyBlock.generate(context) 363 | } 364 | } 365 | 366 | def print(tabs) { 367 | def result = [] 368 | result += "${tabs}try" 369 | result += super.print(tabs) 370 | 371 | if (catchBlock) { 372 | result += catchBlock.print(tabs) 373 | } 374 | 375 | if (finallyBlock) { 376 | result += finallyBlock.print(tabs) 377 | } 378 | 379 | result += "${tabs}" 380 | return result 381 | } 382 | 383 | public String toString() { 384 | return "try" 385 | } 386 | } 387 | 388 | static class VarBlock extends VarHolder { 389 | def value 390 | 391 | def generate(context) { 392 | this.var = Utils.generateName("var", "", 10, true, true); 393 | this.value = generateValue(this.parent) 394 | } 395 | 396 | def print(tabs) { 397 | def result = [] 398 | result += "${tabs}long $var = $value;" 399 | return result 400 | } 401 | 402 | public String toString() { 403 | return "var" 404 | } 405 | } 406 | 407 | static class CallBlock extends VarHolder { 408 | def function 409 | 410 | def generate(context) { 411 | var = Utils.generateName("ret", "", 10, true, true) 412 | } 413 | 414 | def print(tabs) { 415 | def result = [] 416 | result += "${tabs}$var = call" 417 | return result 418 | } 419 | 420 | public String toString() { 421 | return "call" 422 | } 423 | } 424 | 425 | static class ReturnBlock extends Block { 426 | def value 427 | 428 | def generate(context) { 429 | this.value = generateValue(this) 430 | } 431 | 432 | def print(tabs) { 433 | def result = [] 434 | result += "${tabs}return $value;" 435 | return result 436 | } 437 | 438 | public String toString() { 439 | return "call" 440 | } 441 | } 442 | 443 | static class AssignBlock extends VarHolder { 444 | def value 445 | 446 | def generate(context) { 447 | def scopedVars = scope().grep({ it instanceof VarHolder }).collect({ it.var }).grep({ it }) 448 | 449 | if (scopedVars) { 450 | var = scopedVars[Utils.rand.nextInt(scopedVars.size())] 451 | 452 | if (var) { 453 | value = generateValue(this) 454 | } 455 | } 456 | } 457 | 458 | def print(tabs) { 459 | def result = [] 460 | 461 | if (var) { 462 | result += "${tabs}$var = $value;" 463 | } 464 | 465 | return result 466 | } 467 | 468 | public String toString() { 469 | return "assign" 470 | } 471 | } 472 | 473 | static class SpecialBlock extends Block { 474 | def code 475 | 476 | def generate(context) { 477 | this.code = SpecialLogic.generateSpecial() 478 | } 479 | 480 | def print(tabs) { 481 | def result = [] 482 | def codeStr = this.code.join("\n$tabs") 483 | result += "$tabs$codeStr" 484 | return result 485 | } 486 | 487 | public String toString() { 488 | return "special" 489 | } 490 | } 491 | 492 | static generateCondition(parent) { 493 | def value = generateValue(parent, 2) 494 | def num = Utils.rand.nextInt(1000000) + 1 495 | 496 | return "($value % $num) == 0" 497 | } 498 | 499 | static generateValue(parent, maxLength = Config.maxExpressionLength) { 500 | def leafers = [ 501 | { 502 | def from = Utils.rand.nextInt(10) 503 | def to = Utils.rand.nextInt(1000) + from 504 | 505 | return "Config.get().getRandom().nextInt($to) + $from" 506 | }, 507 | { 508 | return "${Utils.rand.nextInt(10000)}" 509 | }, 510 | { 511 | def scope = parent.scope() 512 | def vars = scope.grep({ it instanceof VarHolder }).collect({ it.var }) 513 | def loops = scope.grep({ it instanceof ForBlock || it instanceof WhileBlock }).collect({ it.loopIndex }) 514 | def all = (vars + loops).grep({ it }).grep({ it != parent }) 515 | 516 | if (all) 517 | { 518 | return all[Utils.rand.nextInt(all.size())] 519 | } 520 | } 521 | ] 522 | 523 | def operators = [ "+", "-", "*" ] 524 | 525 | def expressionLength = Utils.rand.nextInt(maxLength) 526 | def first = true 527 | def result = "" 528 | 529 | (0..expressionLength).each { 530 | def leaf = leafers[Utils.rand.nextInt(leafers.size())]() 531 | 532 | while (!leaf) { 533 | leaf = leafers[Utils.rand.nextInt(leafers.size())]() 534 | } 535 | 536 | if (!first) { 537 | result += " " 538 | result += operators[Utils.rand.nextInt(operators.size())] 539 | result += " " 540 | } 541 | 542 | first = false 543 | result += "($leaf)" 544 | } 545 | 546 | return result 547 | } 548 | } 549 | -------------------------------------------------------------------------------- /src/main/resources/predefined-names.txt: -------------------------------------------------------------------------------- 1 | ada 2 | Ada 3 | adelina 4 | Adelle 5 | Agatha 6 | Ahmad 7 | Ahmed 8 | Aileen 9 | ailene 10 | Al 11 | alaina 12 | Albertine 13 | Aldo 14 | Aleen 15 | Alejandra 16 | Alejandrina 17 | Alena 18 | Alesha 19 | Aleta 20 | Aletha 21 | Alex 22 | Alia 23 | Alicia 24 | alida 25 | Alida 26 | Alishia 27 | Alissa 28 | Aliza 29 | Alla 30 | Allen 31 | Allie 32 | Alphonso 33 | altha 34 | Althea 35 | Alton 36 | Alvin 37 | Alyssa 38 | amanda 39 | amber 40 | Amee 41 | Amie 42 | amira 43 | Andera 44 | Anderson 45 | Andres 46 | Angeles 47 | Angelic 48 | Angelica 49 | anglea 50 | Annamae 51 | Anneliese 52 | annelle 53 | Annelle 54 | Annette 55 | Annie 56 | antone 57 | Arcelia 58 | Ardella 59 | Argentina 60 | arla 61 | Arlean 62 | Arlette 63 | armandina 64 | Arminda 65 | Arnita 66 | Arnulfo 67 | Arturo 68 | Aura 69 | aurora 70 | avis 71 | Babette 72 | Barrett 73 | basil 74 | Basilia 75 | beau 76 | becki 77 | Becki 78 | Belle 79 | benita 80 | Benita 81 | Benny 82 | bernie 83 | Bernita 84 | berta 85 | beryl 86 | Bessie 87 | beth 88 | Bette 89 | bettye 90 | Bettye 91 | bianca 92 | billie 93 | blair 94 | Blair 95 | Blondell 96 | Bo 97 | Bobbi 98 | Bok 99 | Bonita 100 | bonnie 101 | Brad 102 | Brande 103 | bree 104 | Bree 105 | brendon 106 | Brett 107 | briana 108 | brianne 109 | Bridgette 110 | Brittanie 111 | Brittney 112 | brooke 113 | Burl 114 | Burma 115 | Burt 116 | Buster 117 | Callie 118 | camie 119 | Camilla 120 | candi 121 | Candie 122 | candy 123 | Candy 124 | carie 125 | Carin 126 | Carlene 127 | Carletta 128 | Carline 129 | Carlotta 130 | Carly 131 | Carmelia 132 | Carmelita 133 | carmelo 134 | Carolin 135 | Carolyne 136 | caroyln 137 | Carry 138 | cary 139 | Cary 140 | Casey 141 | cassi 142 | Cassy 143 | Caterina 144 | Catherine 145 | Cathern 146 | Catheryn 147 | cathrine 148 | Catina 149 | cayla 150 | Celestine 151 | Celinda 152 | Chan 153 | chance 154 | Chance 155 | Chang 156 | Charlene 157 | charlette 158 | Chassidy 159 | cherly 160 | chery 161 | Chia 162 | chris 163 | Christel 164 | Christia 165 | Christine 166 | ciera 167 | Claretha 168 | Claribel 169 | Clarice 170 | Classie 171 | Claudia 172 | Cliff 173 | clinton 174 | clora 175 | Colette 176 | colin 177 | Concetta 178 | Conchita 179 | Connie 180 | Conrad 181 | Consuela 182 | coral 183 | cordelia 184 | coretta 185 | Corina 186 | courtney 187 | Coy 188 | Crista 189 | Cristie 190 | Curt 191 | cyrstal 192 | Daisey 193 | Daniel 194 | Daniella 195 | danielle 196 | Danielle 197 | dara 198 | Darcie 199 | Daren 200 | daria 201 | Darin 202 | Darla 203 | Darlena 204 | Darlene 205 | daron 206 | darrin 207 | daryl 208 | Daryl 209 | Dave 210 | david 211 | Davina 212 | davis 213 | Dawne 214 | Daysi 215 | Deanna 216 | deb 217 | Debbi 218 | Debra 219 | Deena 220 | Delaine 221 | Delbert 222 | Delila 223 | Dell 224 | Delpha 225 | Demetria 226 | demetrius 227 | Demetrius 228 | denita 229 | Denita 230 | Denyse 231 | Desire 232 | Desmond 233 | Destiny 234 | Detra 235 | devin 236 | Devon 237 | devona 238 | Dewayne 239 | dexter 240 | Diamond 241 | dino 242 | Dionna 243 | dionne 244 | Dolly 245 | Dominique 246 | dominque 247 | dona 248 | donella 249 | Donita 250 | donn 251 | Donnetta 252 | dorathy 253 | Doreatha 254 | Doria 255 | dorothea 256 | Dorothy 257 | Dorsey 258 | Douglas 259 | Drema 260 | Duane 261 | dudley 262 | Dung 263 | Dustin 264 | Earlene 265 | Earlie 266 | eden 267 | edith 268 | edmundo 269 | Edra 270 | Edwin 271 | Ehtel 272 | Eileen 273 | Eilene 274 | Elba 275 | Elbert 276 | Eldon 277 | eldora 278 | eleanora 279 | Elease 280 | elene 281 | Elenor 282 | Elfriede 283 | Elida 284 | Elijah 285 | Eliseo 286 | elizabet 287 | Elizbeth 288 | Ellamae 289 | Ellan 290 | Ellen 291 | Elma 292 | Elodia 293 | Elouise 294 | Elsa 295 | Elvin 296 | Elvira 297 | Elwood 298 | Emmanuel 299 | Emory 300 | enid 301 | Erich 302 | Errol 303 | Esteban 304 | Estell 305 | Ethan 306 | Ethelene 307 | eugene 308 | eusebio 309 | Evelina 310 | eveline 311 | evelyn 312 | Evelynn 313 | everette 314 | Evita 315 | ezekiel 316 | Fanny 317 | Fawn 318 | fe 319 | Felice 320 | Fernando 321 | Filiberto 322 | Fletcher 323 | Flo 324 | florence 325 | Florentina 326 | francesco 327 | francisca 328 | Freddy 329 | Fredericka 330 | Fredrick 331 | gabriela 332 | Gabriella 333 | Garth 334 | Gaston 335 | gema 336 | Genaro 337 | Gene 338 | Genevie 339 | geoffrey 340 | Georgiana 341 | georgiann 342 | Gerard 343 | Gerda 344 | germaine 345 | gigi 346 | Gilma 347 | ginny 348 | giovanni 349 | Giuseppe 350 | Giuseppina 351 | Glenn 352 | gordon 353 | gracie 354 | Gracie 355 | Graham 356 | graig 357 | Graig 358 | gregg 359 | Grisel 360 | Gussie 361 | Gustavo 362 | Gwendolyn 363 | Haley 364 | Hannelore 365 | Harley 366 | harriett 367 | Hassie 368 | Hayley 369 | heather 370 | Hedy 371 | heidy 372 | Herb 373 | Hien 374 | Hillary 375 | hilma 376 | hodaya 377 | Hollie 378 | holly 379 | Hosea 380 | hwa 381 | Ian 382 | iesha 383 | ila 384 | Ileen 385 | ilene 386 | Ilene 387 | Indira 388 | Inell 389 | Inez 390 | Isa 391 | isaiah 392 | Isaiah 393 | Isis 394 | israel 395 | Ivana 396 | Ivette 397 | Ivey 398 | Ivonne 399 | ja 400 | jacelyn 401 | Jackie 402 | Jacqualine 403 | jacquelin 404 | jacquelyne 405 | Jacquetta 406 | jacqui 407 | Jacqui 408 | Jacquline 409 | Jaleesa 410 | Jamar 411 | James 412 | Jamey 413 | Jana 414 | janean 415 | Jaquelyn 416 | jared 417 | Jared 418 | Jarrett 419 | jasmine 420 | Jay 421 | Jaye 422 | Jayne 423 | jean 424 | Jean 425 | Jeanetta 426 | Jeffrey 427 | Jenae 428 | Jenee 429 | Jenell 430 | Jenifer 431 | jenise 432 | jenni 433 | jennie 434 | Jennie 435 | Jerald 436 | jerri 437 | Jerrold 438 | jerry 439 | Jesusita 440 | Ji 441 | jin 442 | jinny 443 | Joan 444 | Joana 445 | Joaquin 446 | Jocelyn 447 | jody 448 | Joel 449 | Johnathon 450 | Jolyn 451 | Jonah 452 | Jonathon 453 | Jone 454 | Jonnie 455 | Jorge 456 | jose 457 | Jose 458 | Josefina 459 | Josefine 460 | Joselyn 461 | julee 462 | Juli 463 | julius 464 | Justin 465 | Kaila 466 | Kala 467 | Kaley 468 | Kallie 469 | Kamilah 470 | Karly 471 | Karlyn 472 | karoline 473 | Karyl 474 | kate 475 | katerine 476 | kathaleen 477 | Katherine 478 | Katheryn 479 | Kathie 480 | Kathline 481 | Kathyrn 482 | kattie 483 | keeley 484 | Kellee 485 | Kellie 486 | Kelsie 487 | Ken 488 | Kena 489 | Keneth 490 | Kennith 491 | Kenton 492 | keren 493 | Kermit 494 | Kerri 495 | kesha 496 | Kevin 497 | Kiersten 498 | Kimberly 499 | Kimbra 500 | Kirsten 501 | kisha 502 | Kit 503 | kiyoko 504 | kourtney 505 | Kourtney 506 | Krista 507 | Kristel 508 | kristen 509 | Krystal 510 | kum 511 | kurtis 512 | Kyle 513 | Kymberly 514 | Kyong 515 | Lael 516 | Laine 517 | lajuana 518 | Lakeisha 519 | Lakenya 520 | Lakisha 521 | Lakita 522 | Lamont 523 | Lani 524 | Larraine 525 | Larry 526 | Lasandra 527 | lashaunda 528 | latarsha 529 | Latisha 530 | Latonya 531 | Latosha 532 | Latrisha 533 | Laura 534 | Laurel 535 | Laurette 536 | Laurine 537 | Lavenia 538 | lavern 539 | Lavina 540 | Lavinia 541 | Lavonna 542 | Lawanda 543 | Leandra 544 | leann 545 | leatha 546 | lecia 547 | Leena 548 | Leesa 549 | Leisha 550 | leoma 551 | leona 552 | Leona 553 | Leonardo 554 | Leonida 555 | Leonie 556 | Leontine 557 | les 558 | Lesia 559 | letitia 560 | Letitia 561 | Lewis 562 | Li 563 | Liana 564 | Lidia 565 | Liliana 566 | lillia 567 | Lilliam 568 | Lily 569 | lina 570 | Lincoln 571 | Linh 572 | Linn 573 | linnea 574 | Linsey 575 | Linwood 576 | Lisbeth 577 | Lissette 578 | Lizette 579 | lizzie 580 | loida 581 | Loise 582 | Lonnie 583 | Loretta 584 | Lorna 585 | Lorretta 586 | lorrine 587 | Louis 588 | Louise 589 | Lourie 590 | Lovella 591 | Luanna 592 | Lucas 593 | luci 594 | Lucinda 595 | Lucio 596 | ludivina 597 | luisa 598 | lulu 599 | Lupita 600 | Lurlene 601 | Lurline 602 | luther 603 | luvenia 604 | Lyman 605 | Lyndon 606 | Lynell 607 | Lynetta 608 | Lynna 609 | Lynnette 610 | lynsey 611 | Mabel 612 | Madaline 613 | maddie 614 | Madelyn 615 | madie 616 | Madison 617 | Magali 618 | magda 619 | magen 620 | major 621 | Major 622 | Malik 623 | Malika 624 | Malisa 625 | Malissa 626 | malorie 627 | Marc 628 | Marcell 629 | Marcie 630 | Mardell 631 | margaretta 632 | Margarette 633 | margarite 634 | margart 635 | Margherita 636 | Maria 637 | mariana 638 | Marianela 639 | marielle 640 | Marin 641 | maris 642 | Marisa 643 | Marisol 644 | Marita 645 | Marlyn 646 | marni 647 | Marni 648 | Marquerite 649 | marry 650 | marsha 651 | Martin 652 | Marx 653 | maryam 654 | Maryam 655 | Maryjo 656 | Mathilda 657 | Matt 658 | Maud 659 | Maurine 660 | max 661 | Maxwell 662 | maye 663 | Maye 664 | mayme 665 | maynard 666 | Mazie 667 | Mckinley 668 | meagan 669 | Meagan 670 | Meaghan 671 | Mellie 672 | Melody 673 | melonie 674 | Mercedez 675 | meri 676 | Merissa 677 | Merle 678 | Mica 679 | Miesha 680 | Mika 681 | Mikaela 682 | Mikki 683 | Milan 684 | Millie 685 | Minda 686 | Minerva 687 | Miquel 688 | Mirella 689 | misha 690 | Mitchel 691 | Mitsuko 692 | Mitzie 693 | Mohammed 694 | Monika 695 | mora 696 | Morris 697 | Murray 698 | Myra 699 | myriam 700 | myrna 701 | myrtie 702 | Naida 703 | Napoleon 704 | natasha 705 | Nathalie 706 | Nathaniel 707 | natisha 708 | Natividad 709 | neida 710 | nelda 711 | Nell 712 | Nelle 713 | Nellie 714 | Nettie 715 | Nichole 716 | Nicol 717 | Nicolasa 718 | Nicole 719 | Nicolle 720 | Nila 721 | Nisha 722 | Nobuko 723 | Noemi 724 | Nolan 725 | norbert 726 | Norman 727 | Norris 728 | Nu 729 | Nyla 730 | oda 731 | Odell 732 | odessa 733 | olene 734 | olimpia 735 | olinda 736 | Olivia 737 | Olympia 738 | Oma 739 | Omar 740 | oralee 741 | Oralia 742 | Orlando 743 | Otto 744 | Pandora 745 | Patrick 746 | Patsy 747 | patty 748 | Paul 749 | Pei 750 | Penni 751 | Pete 752 | phebe 753 | phuong 754 | Phylis 755 | Pinkie 756 | Precious 757 | Preston 758 | Princess 759 | Queen 760 | raguel 761 | Raisa 762 | Ramonita 763 | Rana 764 | Raphael 765 | rasheeda 766 | Raymon 767 | Reba 768 | rebbecca 769 | Rebecka 770 | refugia 771 | Reggie 772 | Regina 773 | Reid 774 | Rena 775 | renaldo 776 | renda 777 | Retta 778 | Rey 779 | reyna 780 | Richelle 781 | Ricki 782 | rikki 783 | Riley 784 | riva 785 | Robby 786 | Robena 787 | Robyn 788 | Rocco 789 | rocio 790 | rolanda 791 | rolande 792 | Rolando 793 | Rolland 794 | Romaine 795 | Ron 796 | Ronnie 797 | Roosevelt 798 | rory 799 | Rosa 800 | Rosalia 801 | Rosalina 802 | rosalva 803 | rosann 804 | Rosaura 805 | roscoe 806 | roseann 807 | roseanna 808 | Rosena 809 | Rosette 810 | Rosita 811 | Rossie 812 | Roxana 813 | Rubie 814 | rubin 815 | rueben 816 | rufina 817 | russell 818 | Russell 819 | Ruthann 820 | Ruthanne 821 | Ruthe 822 | Ruthie 823 | Sadye 824 | Sanda 825 | Sandra 826 | sanora 827 | Santina 828 | Santo 829 | sarah 830 | Saturnina 831 | scottie 832 | Sena 833 | Sha 834 | Shakia 835 | Shakira 836 | shakita 837 | Shalon 838 | Shanel 839 | shanell 840 | shanna 841 | Shanna 842 | shannon 843 | Shannon 844 | shantel 845 | Shantel 846 | Sharilyn 847 | sharita 848 | Sharla 849 | Sharonda 850 | Sharri 851 | shasta 852 | Shawana 853 | shawnna 854 | Shawnta 855 | shay 856 | Sheba 857 | Sheila 858 | Shelli 859 | Shellie 860 | Shelly 861 | sheree 862 | Sherice 863 | sherika 864 | Sherika 865 | Sherill 866 | Sherley 867 | Sherrie 868 | Sherrill 869 | Sheryl 870 | shonda 871 | Shonna 872 | Shonta 873 | Sibyl 874 | sidney 875 | Sima 876 | solange 877 | Sommer 878 | sondra 879 | Song 880 | Sonny 881 | Stacey 882 | Stacie 883 | Stan 884 | Stanley 885 | Star 886 | Starla 887 | Starr 888 | stasia 889 | Stefan 890 | Stephan 891 | Stephani 892 | Stephen 893 | Sudie 894 | sue 895 | Susana 896 | Suzan 897 | Suzy 898 | svetlana 899 | Synthia 900 | Talia 901 | Talitha 902 | tamala 903 | Tamala 904 | Tameika 905 | tamekia 906 | Tamera 907 | Tamra 908 | Tanna 909 | Tari 910 | Tatiana 911 | Tawanda 912 | Tawna 913 | tawnya 914 | Tawnya 915 | telma 916 | temika 917 | tena 918 | Tenesha 919 | Terence 920 | Terina 921 | Terri 922 | Thea 923 | Theda 924 | Thomasine 925 | Thora 926 | Tifany 927 | tiffani 928 | Tiffiny 929 | Timothy 930 | Tom 931 | tommie 932 | Tomoko 933 | Tonette 934 | toni 935 | tora 936 | Torrie 937 | Tosha 938 | tova 939 | towanda 940 | tracy 941 | Trenton 942 | Tricia 943 | Trinity 944 | ula 945 | Ulrike 946 | Ulysses 947 | Un 948 | val 949 | Valerie 950 | Vanda 951 | Vanita 952 | Vannessa 953 | vena 954 | Venessa 955 | Vern 956 | Verona 957 | Vickie 958 | victorina 959 | Vikki 960 | Vina 961 | Vincent 962 | Vinita 963 | violet 964 | Virgil 965 | Vito 966 | viva 967 | vonda 968 | Wade 969 | Wally 970 | Warner 971 | Waylon 972 | Weldon 973 | Wendolyn 974 | werner 975 | whitley 976 | whitney 977 | Wilbert 978 | Wilda 979 | wiley 980 | will 981 | Willie 982 | Willodean 983 | Willow 984 | Winford 985 | wynell 986 | xavier 987 | Xiomara 988 | Xuan 989 | Yadira 990 | Yan 991 | Yelena 992 | Yevette 993 | Yolanda 994 | Yolande 995 | Yon 996 | yu 997 | yuk 998 | Yulanda 999 | Yuri 1000 | Zandra --------------------------------------------------------------------------------